mutex.c

Go to the documentation of this file.
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