modernc.org/cc@v1.0.1/v2/testdata/_sqlite/src/mutex.c (about)

     1  /*
     2  ** 2007 August 14
     3  **
     4  ** The author disclaims copyright to this source code.  In place of
     5  ** a legal notice, here is a blessing:
     6  **
     7  **    May you do good and not evil.
     8  **    May you find forgiveness for yourself and forgive others.
     9  **    May you share freely, never taking more than you give.
    10  **
    11  *************************************************************************
    12  ** This file contains the C functions that implement mutexes.
    13  **
    14  ** This file contains code that is common across all mutex implementations.
    15  */
    16  #include "sqliteInt.h"
    17  
    18  #if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
    19  /*
    20  ** For debugging purposes, record when the mutex subsystem is initialized
    21  ** and uninitialized so that we can assert() if there is an attempt to
    22  ** allocate a mutex while the system is uninitialized.
    23  */
    24  static SQLITE_WSD int mutexIsInit = 0;
    25  #endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */
    26  
    27  
    28  #ifndef SQLITE_MUTEX_OMIT
    29  /*
    30  ** Initialize the mutex system.
    31  */
    32  int sqlite3MutexInit(void){ 
    33    int rc = SQLITE_OK;
    34    if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
    35      /* If the xMutexAlloc method has not been set, then the user did not
    36      ** install a mutex implementation via sqlite3_config() prior to 
    37      ** sqlite3_initialize() being called. This block copies pointers to
    38      ** the default implementation into the sqlite3GlobalConfig structure.
    39      */
    40      sqlite3_mutex_methods const *pFrom;
    41      sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
    42  
    43      if( sqlite3GlobalConfig.bCoreMutex ){
    44        pFrom = sqlite3DefaultMutex();
    45      }else{
    46        pFrom = sqlite3NoopMutex();
    47      }
    48      pTo->xMutexInit = pFrom->xMutexInit;
    49      pTo->xMutexEnd = pFrom->xMutexEnd;
    50      pTo->xMutexFree = pFrom->xMutexFree;
    51      pTo->xMutexEnter = pFrom->xMutexEnter;
    52      pTo->xMutexTry = pFrom->xMutexTry;
    53      pTo->xMutexLeave = pFrom->xMutexLeave;
    54      pTo->xMutexHeld = pFrom->xMutexHeld;
    55      pTo->xMutexNotheld = pFrom->xMutexNotheld;
    56      sqlite3MemoryBarrier();
    57      pTo->xMutexAlloc = pFrom->xMutexAlloc;
    58    }
    59    assert( sqlite3GlobalConfig.mutex.xMutexInit );
    60    rc = sqlite3GlobalConfig.mutex.xMutexInit();
    61  
    62  #ifdef SQLITE_DEBUG
    63    GLOBAL(int, mutexIsInit) = 1;
    64  #endif
    65  
    66    return rc;
    67  }
    68  
    69  /*
    70  ** Shutdown the mutex system. This call frees resources allocated by
    71  ** sqlite3MutexInit().
    72  */
    73  int sqlite3MutexEnd(void){
    74    int rc = SQLITE_OK;
    75    if( sqlite3GlobalConfig.mutex.xMutexEnd ){
    76      rc = sqlite3GlobalConfig.mutex.xMutexEnd();
    77    }
    78  
    79  #ifdef SQLITE_DEBUG
    80    GLOBAL(int, mutexIsInit) = 0;
    81  #endif
    82  
    83    return rc;
    84  }
    85  
    86  /*
    87  ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
    88  */
    89  sqlite3_mutex *sqlite3_mutex_alloc(int id){
    90  #ifndef SQLITE_OMIT_AUTOINIT
    91    if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
    92    if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
    93  #endif
    94    assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
    95    return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
    96  }
    97  
    98  sqlite3_mutex *sqlite3MutexAlloc(int id){
    99    if( !sqlite3GlobalConfig.bCoreMutex ){
   100      return 0;
   101    }
   102    assert( GLOBAL(int, mutexIsInit) );
   103    assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
   104    return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
   105  }
   106  
   107  /*
   108  ** Free a dynamic mutex.
   109  */
   110  void sqlite3_mutex_free(sqlite3_mutex *p){
   111    if( p ){
   112      assert( sqlite3GlobalConfig.mutex.xMutexFree );
   113      sqlite3GlobalConfig.mutex.xMutexFree(p);
   114    }
   115  }
   116  
   117  /*
   118  ** Obtain the mutex p. If some other thread already has the mutex, block
   119  ** until it can be obtained.
   120  */
   121  void sqlite3_mutex_enter(sqlite3_mutex *p){
   122    if( p ){
   123      assert( sqlite3GlobalConfig.mutex.xMutexEnter );
   124      sqlite3GlobalConfig.mutex.xMutexEnter(p);
   125    }
   126  }
   127  
   128  /*
   129  ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
   130  ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
   131  */
   132  int sqlite3_mutex_try(sqlite3_mutex *p){
   133    int rc = SQLITE_OK;
   134    if( p ){
   135      assert( sqlite3GlobalConfig.mutex.xMutexTry );
   136      return sqlite3GlobalConfig.mutex.xMutexTry(p);
   137    }
   138    return rc;
   139  }
   140  
   141  /*
   142  ** The sqlite3_mutex_leave() routine exits a mutex that was previously
   143  ** entered by the same thread.  The behavior is undefined if the mutex 
   144  ** is not currently entered. If a NULL pointer is passed as an argument
   145  ** this function is a no-op.
   146  */
   147  void sqlite3_mutex_leave(sqlite3_mutex *p){
   148    if( p ){
   149      assert( sqlite3GlobalConfig.mutex.xMutexLeave );
   150      sqlite3GlobalConfig.mutex.xMutexLeave(p);
   151    }
   152  }
   153  
   154  #ifndef NDEBUG
   155  /*
   156  ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
   157  ** intended for use inside assert() statements.
   158  */
   159  int sqlite3_mutex_held(sqlite3_mutex *p){
   160    assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
   161    return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
   162  }
   163  int sqlite3_mutex_notheld(sqlite3_mutex *p){
   164    assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
   165    return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
   166  }
   167  #endif
   168  
   169  #endif /* !defined(SQLITE_MUTEX_OMIT) */