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