00001 /* 00002 ** 2007 August 14 00003 ** 00004 ** The author disclaims copyright to this source code. In place of 00005 ** a legal notice, here is a blessing: 00006 ** 00007 ** May you do good and not evil. 00008 ** May you find forgiveness for yourself and forgive others. 00009 ** May you share freely, never taking more than you give. 00010 ** 00011 ************************************************************************* 00012 ** This file contains the C functions that implement mutexes. 00013 ** 00014 ** This file contains code that is common across all mutex implementations. 00015 00016 ** 00017 ** $Id: mutex.c,v 1.29 2008/10/07 15:25:48 drh Exp $ 00018 */ 00019 #include "sqliteInt.h" 00020 00021 #ifndef SQLITE_MUTEX_OMIT 00022 /* 00023 ** Initialize the mutex system. 00024 */ 00025 int sqlite3MutexInit(void){ 00026 int rc = SQLITE_OK; 00027 if( sqlite3GlobalConfig.bCoreMutex ){ 00028 if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ 00029 /* If the xMutexAlloc method has not been set, then the user did not 00030 ** install a mutex implementation via sqlite3_config() prior to 00031 ** sqlite3_initialize() being called. This block copies pointers to 00032 ** the default implementation into the sqlite3GlobalConfig structure. 00033 ** 00034 ** The danger is that although sqlite3_config() is not a threadsafe 00035 ** API, sqlite3_initialize() is, and so multiple threads may be 00036 ** attempting to run this function simultaneously. To guard write 00037 ** access to the sqlite3GlobalConfig structure, the 'MASTER' static mutex 00038 ** is obtained before modifying it. 00039 */ 00040 sqlite3_mutex_methods *p = sqlite3DefaultMutex(); 00041 sqlite3_mutex *pMaster = 0; 00042 00043 rc = p->xMutexInit(); 00044 if( rc==SQLITE_OK ){ 00045 pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER); 00046 assert(pMaster); 00047 p->xMutexEnter(pMaster); 00048 assert( sqlite3GlobalConfig.mutex.xMutexAlloc==0 00049 || sqlite3GlobalConfig.mutex.xMutexAlloc==p->xMutexAlloc 00050 ); 00051 if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ 00052 sqlite3GlobalConfig.mutex = *p; 00053 } 00054 p->xMutexLeave(pMaster); 00055 } 00056 }else{ 00057 rc = sqlite3GlobalConfig.mutex.xMutexInit(); 00058 } 00059 } 00060 00061 return rc; 00062 } 00063 00064 /* 00065 ** Shutdown the mutex system. This call frees resources allocated by 00066 ** sqlite3MutexInit(). 00067 */ 00068 int sqlite3MutexEnd(void){ 00069 int rc = SQLITE_OK; 00070 rc = sqlite3GlobalConfig.mutex.xMutexEnd(); 00071 return rc; 00072 } 00073 00074 /* 00075 ** Retrieve a pointer to a static mutex or allocate a new dynamic one. 00076 */ 00077 sqlite3_mutex *sqlite3_mutex_alloc(int id){ 00078 #ifndef SQLITE_OMIT_AUTOINIT 00079 if( sqlite3_initialize() ) return 0; 00080 #endif 00081 return sqlite3GlobalConfig.mutex.xMutexAlloc(id); 00082 } 00083 00084 sqlite3_mutex *sqlite3MutexAlloc(int id){ 00085 if( !sqlite3GlobalConfig.bCoreMutex ){ 00086 return 0; 00087 } 00088 return sqlite3GlobalConfig.mutex.xMutexAlloc(id); 00089 } 00090 00091 /* 00092 ** Free a dynamic mutex. 00093 */ 00094 void sqlite3_mutex_free(sqlite3_mutex *p){ 00095 if( p ){ 00096 sqlite3GlobalConfig.mutex.xMutexFree(p); 00097 } 00098 } 00099 00100 /* 00101 ** Obtain the mutex p. If some other thread already has the mutex, block 00102 ** until it can be obtained. 00103 */ 00104 void sqlite3_mutex_enter(sqlite3_mutex *p){ 00105 if( p ){ 00106 sqlite3GlobalConfig.mutex.xMutexEnter(p); 00107 } 00108 } 00109 00110 /* 00111 ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another 00112 ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. 00113 */ 00114 int sqlite3_mutex_try(sqlite3_mutex *p){ 00115 int rc = SQLITE_OK; 00116 if( p ){ 00117 return sqlite3GlobalConfig.mutex.xMutexTry(p); 00118 } 00119 return rc; 00120 } 00121 00122 /* 00123 ** The sqlite3_mutex_leave() routine exits a mutex that was previously 00124 ** entered by the same thread. The behavior is undefined if the mutex 00125 ** is not currently entered. If a NULL pointer is passed as an argument 00126 ** this function is a no-op. 00127 */ 00128 void sqlite3_mutex_leave(sqlite3_mutex *p){ 00129 if( p ){ 00130 sqlite3GlobalConfig.mutex.xMutexLeave(p); 00131 } 00132 } 00133 00134 #ifndef NDEBUG 00135 /* 00136 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are 00137 ** intended for use inside assert() statements. 00138 */ 00139 int sqlite3_mutex_held(sqlite3_mutex *p){ 00140 return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); 00141 } 00142 int sqlite3_mutex_notheld(sqlite3_mutex *p){ 00143 return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); 00144 } 00145 #endif 00146 00147 #endif /* SQLITE_OMIT_MUTEX */
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1