persistentstorage/sql/SQLite364/mutex.c
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     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 **
       
    17 ** $Id: mutex.c,v 1.29 2008/10/07 15:25:48 drh Exp $
       
    18 */
       
    19 #include "sqliteInt.h"
       
    20 
       
    21 #ifndef SQLITE_MUTEX_OMIT
       
    22 /*
       
    23 ** Initialize the mutex system.
       
    24 */
       
    25 int sqlite3MutexInit(void){ 
       
    26   int rc = SQLITE_OK;
       
    27   if( sqlite3GlobalConfig.bCoreMutex ){
       
    28     if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
       
    29       /* If the xMutexAlloc method has not been set, then the user did not
       
    30       ** install a mutex implementation via sqlite3_config() prior to 
       
    31       ** sqlite3_initialize() being called. This block copies pointers to
       
    32       ** the default implementation into the sqlite3GlobalConfig structure.
       
    33       **
       
    34       ** The danger is that although sqlite3_config() is not a threadsafe
       
    35       ** API, sqlite3_initialize() is, and so multiple threads may be
       
    36       ** attempting to run this function simultaneously. To guard write
       
    37       ** access to the sqlite3GlobalConfig structure, the 'MASTER' static mutex
       
    38       ** is obtained before modifying it.
       
    39       */
       
    40       sqlite3_mutex_methods *p = sqlite3DefaultMutex();
       
    41       sqlite3_mutex *pMaster = 0;
       
    42   
       
    43       rc = p->xMutexInit();
       
    44       if( rc==SQLITE_OK ){
       
    45         pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
       
    46         assert(pMaster);
       
    47         p->xMutexEnter(pMaster);
       
    48         assert( sqlite3GlobalConfig.mutex.xMutexAlloc==0 
       
    49              || sqlite3GlobalConfig.mutex.xMutexAlloc==p->xMutexAlloc
       
    50         );
       
    51         if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
       
    52           sqlite3GlobalConfig.mutex = *p;
       
    53         }
       
    54         p->xMutexLeave(pMaster);
       
    55       }
       
    56     }else{
       
    57       rc = sqlite3GlobalConfig.mutex.xMutexInit();
       
    58     }
       
    59   }
       
    60 
       
    61   return rc;
       
    62 }
       
    63 
       
    64 /*
       
    65 ** Shutdown the mutex system. This call frees resources allocated by
       
    66 ** sqlite3MutexInit().
       
    67 */
       
    68 int sqlite3MutexEnd(void){
       
    69   int rc = SQLITE_OK;
       
    70   if( sqlite3GlobalConfig.mutex.xMutexEnd ){
       
    71     rc = sqlite3GlobalConfig.mutex.xMutexEnd();
       
    72   }
       
    73   return rc;
       
    74 }
       
    75 
       
    76 /*
       
    77 ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
       
    78 */
       
    79 sqlite3_mutex *sqlite3_mutex_alloc(int id){
       
    80 #ifndef SQLITE_OMIT_AUTOINIT
       
    81   if( sqlite3_initialize() ) return 0;
       
    82 #endif
       
    83   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
       
    84 }
       
    85 
       
    86 sqlite3_mutex *sqlite3MutexAlloc(int id){
       
    87   if( !sqlite3GlobalConfig.bCoreMutex ){
       
    88     return 0;
       
    89   }
       
    90   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
       
    91 }
       
    92 
       
    93 /*
       
    94 ** Free a dynamic mutex.
       
    95 */
       
    96 void sqlite3_mutex_free(sqlite3_mutex *p){
       
    97   if( p ){
       
    98     sqlite3GlobalConfig.mutex.xMutexFree(p);
       
    99   }
       
   100 }
       
   101 
       
   102 /*
       
   103 ** Obtain the mutex p. If some other thread already has the mutex, block
       
   104 ** until it can be obtained.
       
   105 */
       
   106 void sqlite3_mutex_enter(sqlite3_mutex *p){
       
   107   if( p ){
       
   108     sqlite3GlobalConfig.mutex.xMutexEnter(p);
       
   109   }
       
   110 }
       
   111 
       
   112 /*
       
   113 ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
       
   114 ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
       
   115 */
       
   116 int sqlite3_mutex_try(sqlite3_mutex *p){
       
   117   int rc = SQLITE_OK;
       
   118   if( p ){
       
   119     return sqlite3GlobalConfig.mutex.xMutexTry(p);
       
   120   }
       
   121   return rc;
       
   122 }
       
   123 
       
   124 /*
       
   125 ** The sqlite3_mutex_leave() routine exits a mutex that was previously
       
   126 ** entered by the same thread.  The behavior is undefined if the mutex 
       
   127 ** is not currently entered. If a NULL pointer is passed as an argument
       
   128 ** this function is a no-op.
       
   129 */
       
   130 void sqlite3_mutex_leave(sqlite3_mutex *p){
       
   131   if( p ){
       
   132     sqlite3GlobalConfig.mutex.xMutexLeave(p);
       
   133   }
       
   134 }
       
   135 
       
   136 #ifndef NDEBUG
       
   137 /*
       
   138 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
       
   139 ** intended for use inside assert() statements.
       
   140 */
       
   141 int sqlite3_mutex_held(sqlite3_mutex *p){
       
   142   return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
       
   143 }
       
   144 int sqlite3_mutex_notheld(sqlite3_mutex *p){
       
   145   return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
       
   146 }
       
   147 #endif
       
   148 
       
   149 #endif /* SQLITE_OMIT_MUTEX */