| 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 for win32 |  | 
|   13 ** |  | 
|   14 ** $Id: mutex_w32.c,v 1.18 2009/08/10 03:23:21 shane Exp $ |  | 
|   15 */ |  | 
|   16 #include "sqliteInt.h" |  | 
|   17  |  | 
|   18 /* |  | 
|   19 ** The code in this file is only used if we are compiling multithreaded |  | 
|   20 ** on a win32 system. |  | 
|   21 */ |  | 
|   22 #ifdef SQLITE_MUTEX_W32 |  | 
|   23  |  | 
|   24 /* |  | 
|   25 ** Each recursive mutex is an instance of the following structure. |  | 
|   26 */ |  | 
|   27 struct sqlite3_mutex { |  | 
|   28   CRITICAL_SECTION mutex;    /* Mutex controlling the lock */ |  | 
|   29   int id;                    /* Mutex type */ |  | 
|   30   int nRef;                  /* Number of enterances */ |  | 
|   31   DWORD owner;               /* Thread holding this mutex */ |  | 
|   32 }; |  | 
|   33  |  | 
|   34 /* |  | 
|   35 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, |  | 
|   36 ** or WinCE.  Return false (zero) for Win95, Win98, or WinME. |  | 
|   37 ** |  | 
|   38 ** Here is an interesting observation:  Win95, Win98, and WinME lack |  | 
|   39 ** the LockFileEx() API.  But we can still statically link against that |  | 
|   40 ** API as long as we don't call it win running Win95/98/ME.  A call to |  | 
|   41 ** this routine is used to determine if the host is Win95/98/ME or |  | 
|   42 ** WinNT/2K/XP so that we will know whether or not we can safely call |  | 
|   43 ** the LockFileEx() API. |  | 
|   44 ** |  | 
|   45 ** mutexIsNT() is only used for the TryEnterCriticalSection() API call, |  | 
|   46 ** which is only available if your application was compiled with  |  | 
|   47 ** _WIN32_WINNT defined to a value >= 0x0400.  Currently, the only |  | 
|   48 ** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef  |  | 
|   49 ** this out as well. |  | 
|   50 */ |  | 
|   51 #if 0 |  | 
|   52 #if SQLITE_OS_WINCE |  | 
|   53 # define mutexIsNT()  (1) |  | 
|   54 #else |  | 
|   55   static int mutexIsNT(void){ |  | 
|   56     static int osType = 0; |  | 
|   57     if( osType==0 ){ |  | 
|   58       OSVERSIONINFO sInfo; |  | 
|   59       sInfo.dwOSVersionInfoSize = sizeof(sInfo); |  | 
|   60       GetVersionEx(&sInfo); |  | 
|   61       osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |  | 
|   62     } |  | 
|   63     return osType==2; |  | 
|   64   } |  | 
|   65 #endif /* SQLITE_OS_WINCE */ |  | 
|   66 #endif |  | 
|   67  |  | 
|   68 #ifdef SQLITE_DEBUG |  | 
|   69 /* |  | 
|   70 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |  | 
|   71 ** intended for use only inside assert() statements. |  | 
|   72 */ |  | 
|   73 static int winMutexHeld(sqlite3_mutex *p){ |  | 
|   74   return p->nRef!=0 && p->owner==GetCurrentThreadId(); |  | 
|   75 } |  | 
|   76 static int winMutexNotheld(sqlite3_mutex *p){ |  | 
|   77   return p->nRef==0 || p->owner!=GetCurrentThreadId(); |  | 
|   78 } |  | 
|   79 #endif |  | 
|   80  |  | 
|   81  |  | 
|   82 /* |  | 
|   83 ** Initialize and deinitialize the mutex subsystem. |  | 
|   84 */ |  | 
|   85 static sqlite3_mutex winMutex_staticMutexes[6]; |  | 
|   86 static int winMutex_isInit = 0; |  | 
|   87 /* As winMutexInit() and winMutexEnd() are called as part |  | 
|   88 ** of the sqlite3_initialize and sqlite3_shutdown() |  | 
|   89 ** processing, the "interlocked" magic is probably not |  | 
|   90 ** strictly necessary. |  | 
|   91 */ |  | 
|   92 static long winMutex_lock = 0; |  | 
|   93  |  | 
|   94 static int winMutexInit(void){  |  | 
|   95   /* The first to increment to 1 does actual initialization */ |  | 
|   96   if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ |  | 
|   97     int i; |  | 
|   98     for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |  | 
|   99       InitializeCriticalSection(&winMutex_staticMutexes[i].mutex); |  | 
|  100     } |  | 
|  101     winMutex_isInit = 1; |  | 
|  102   }else{ |  | 
|  103     /* Someone else is in the process of initing the static mutexes */ |  | 
|  104     while( !winMutex_isInit ){ |  | 
|  105       Sleep(1); |  | 
|  106     } |  | 
|  107   } |  | 
|  108   return SQLITE_OK;  |  | 
|  109 } |  | 
|  110  |  | 
|  111 static int winMutexEnd(void){  |  | 
|  112   /* The first to decrement to 0 does actual shutdown  |  | 
|  113   ** (which should be the last to shutdown.) */ |  | 
|  114   if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){ |  | 
|  115     if( winMutex_isInit==1 ){ |  | 
|  116       int i; |  | 
|  117       for(i=0; i<ArraySize(winMutex_staticMutexes); i++){ |  | 
|  118         DeleteCriticalSection(&winMutex_staticMutexes[i].mutex); |  | 
|  119       } |  | 
|  120       winMutex_isInit = 0; |  | 
|  121     } |  | 
|  122   } |  | 
|  123   return SQLITE_OK;  |  | 
|  124 } |  | 
|  125  |  | 
|  126 /* |  | 
|  127 ** The sqlite3_mutex_alloc() routine allocates a new |  | 
|  128 ** mutex and returns a pointer to it.  If it returns NULL |  | 
|  129 ** that means that a mutex could not be allocated.  SQLite |  | 
|  130 ** will unwind its stack and return an error.  The argument |  | 
|  131 ** to sqlite3_mutex_alloc() is one of these integer constants: |  | 
|  132 ** |  | 
|  133 ** <ul> |  | 
|  134 ** <li>  SQLITE_MUTEX_FAST |  | 
|  135 ** <li>  SQLITE_MUTEX_RECURSIVE |  | 
|  136 ** <li>  SQLITE_MUTEX_STATIC_MASTER |  | 
|  137 ** <li>  SQLITE_MUTEX_STATIC_MEM |  | 
|  138 ** <li>  SQLITE_MUTEX_STATIC_MEM2 |  | 
|  139 ** <li>  SQLITE_MUTEX_STATIC_PRNG |  | 
|  140 ** <li>  SQLITE_MUTEX_STATIC_LRU |  | 
|  141 ** <li>  SQLITE_MUTEX_STATIC_LRU2 |  | 
|  142 ** </ul> |  | 
|  143 ** |  | 
|  144 ** The first two constants cause sqlite3_mutex_alloc() to create |  | 
|  145 ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |  | 
|  146 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |  | 
|  147 ** The mutex implementation does not need to make a distinction |  | 
|  148 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does |  | 
|  149 ** not want to.  But SQLite will only request a recursive mutex in |  | 
|  150 ** cases where it really needs one.  If a faster non-recursive mutex |  | 
|  151 ** implementation is available on the host platform, the mutex subsystem |  | 
|  152 ** might return such a mutex in response to SQLITE_MUTEX_FAST. |  | 
|  153 ** |  | 
|  154 ** The other allowed parameters to sqlite3_mutex_alloc() each return |  | 
|  155 ** a pointer to a static preexisting mutex.  Six static mutexes are |  | 
|  156 ** used by the current version of SQLite.  Future versions of SQLite |  | 
|  157 ** may add additional static mutexes.  Static mutexes are for internal |  | 
|  158 ** use by SQLite only.  Applications that use SQLite mutexes should |  | 
|  159 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or |  | 
|  160 ** SQLITE_MUTEX_RECURSIVE. |  | 
|  161 ** |  | 
|  162 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST |  | 
|  163 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() |  | 
|  164 ** returns a different mutex on every call.  But for the static  |  | 
|  165 ** mutex types, the same mutex is returned on every call that has |  | 
|  166 ** the same type number. |  | 
|  167 */ |  | 
|  168 static sqlite3_mutex *winMutexAlloc(int iType){ |  | 
|  169   sqlite3_mutex *p; |  | 
|  170  |  | 
|  171   switch( iType ){ |  | 
|  172     case SQLITE_MUTEX_FAST: |  | 
|  173     case SQLITE_MUTEX_RECURSIVE: { |  | 
|  174       p = sqlite3MallocZero( sizeof(*p) ); |  | 
|  175       if( p ){   |  | 
|  176         p->id = iType; |  | 
|  177         InitializeCriticalSection(&p->mutex); |  | 
|  178       } |  | 
|  179       break; |  | 
|  180     } |  | 
|  181     default: { |  | 
|  182       assert( winMutex_isInit==1 ); |  | 
|  183       assert( iType-2 >= 0 ); |  | 
|  184       assert( iType-2 < ArraySize(winMutex_staticMutexes) ); |  | 
|  185       p = &winMutex_staticMutexes[iType-2]; |  | 
|  186       p->id = iType; |  | 
|  187       break; |  | 
|  188     } |  | 
|  189   } |  | 
|  190   return p; |  | 
|  191 } |  | 
|  192  |  | 
|  193  |  | 
|  194 /* |  | 
|  195 ** This routine deallocates a previously |  | 
|  196 ** allocated mutex.  SQLite is careful to deallocate every |  | 
|  197 ** mutex that it allocates. |  | 
|  198 */ |  | 
|  199 static void winMutexFree(sqlite3_mutex *p){ |  | 
|  200   assert( p ); |  | 
|  201   assert( p->nRef==0 ); |  | 
|  202   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |  | 
|  203   DeleteCriticalSection(&p->mutex); |  | 
|  204   sqlite3_free(p); |  | 
|  205 } |  | 
|  206  |  | 
|  207 /* |  | 
|  208 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt |  | 
|  209 ** to enter a mutex.  If another thread is already within the mutex, |  | 
|  210 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return |  | 
|  211 ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK |  | 
|  212 ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can |  | 
|  213 ** be entered multiple times by the same thread.  In such cases the, |  | 
|  214 ** mutex must be exited an equal number of times before another thread |  | 
|  215 ** can enter.  If the same thread tries to enter any other kind of mutex |  | 
|  216 ** more than once, the behavior is undefined. |  | 
|  217 */ |  | 
|  218 static void winMutexEnter(sqlite3_mutex *p){ |  | 
|  219   assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); |  | 
|  220   EnterCriticalSection(&p->mutex); |  | 
|  221   p->owner = GetCurrentThreadId();  |  | 
|  222   p->nRef++; |  | 
|  223 } |  | 
|  224 static int winMutexTry(sqlite3_mutex *p){ |  | 
|  225   int rc = SQLITE_BUSY; |  | 
|  226   assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); |  | 
|  227   /* |  | 
|  228   ** The sqlite3_mutex_try() routine is very rarely used, and when it |  | 
|  229   ** is used it is merely an optimization.  So it is OK for it to always |  | 
|  230   ** fail.   |  | 
|  231   ** |  | 
|  232   ** The TryEnterCriticalSection() interface is only available on WinNT. |  | 
|  233   ** And some windows compilers complain if you try to use it without |  | 
|  234   ** first doing some #defines that prevent SQLite from building on Win98. |  | 
|  235   ** For that reason, we will omit this optimization for now.  See |  | 
|  236   ** ticket #2685. |  | 
|  237   */ |  | 
|  238 #if 0 |  | 
|  239   if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ |  | 
|  240     p->owner = GetCurrentThreadId(); |  | 
|  241     p->nRef++; |  | 
|  242     rc = SQLITE_OK; |  | 
|  243   } |  | 
|  244 #else |  | 
|  245   UNUSED_PARAMETER(p); |  | 
|  246 #endif |  | 
|  247   return rc; |  | 
|  248 } |  | 
|  249  |  | 
|  250 /* |  | 
|  251 ** The sqlite3_mutex_leave() routine exits a mutex that was |  | 
|  252 ** previously entered by the same thread.  The behavior |  | 
|  253 ** is undefined if the mutex is not currently entered or |  | 
|  254 ** is not currently allocated.  SQLite will never do either. |  | 
|  255 */ |  | 
|  256 static void winMutexLeave(sqlite3_mutex *p){ |  | 
|  257   assert( p->nRef>0 ); |  | 
|  258   assert( p->owner==GetCurrentThreadId() ); |  | 
|  259   p->nRef--; |  | 
|  260   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |  | 
|  261   LeaveCriticalSection(&p->mutex); |  | 
|  262 } |  | 
|  263  |  | 
|  264 sqlite3_mutex_methods *sqlite3DefaultMutex(void){ |  | 
|  265   static sqlite3_mutex_methods sMutex = { |  | 
|  266     winMutexInit, |  | 
|  267     winMutexEnd, |  | 
|  268     winMutexAlloc, |  | 
|  269     winMutexFree, |  | 
|  270     winMutexEnter, |  | 
|  271     winMutexTry, |  | 
|  272     winMutexLeave, |  | 
|  273 #ifdef SQLITE_DEBUG |  | 
|  274     winMutexHeld, |  | 
|  275     winMutexNotheld |  | 
|  276 #else |  | 
|  277     0, |  | 
|  278     0 |  | 
|  279 #endif |  | 
|  280   }; |  | 
|  281  |  | 
|  282   return &sMutex; |  | 
|  283 } |  | 
|  284 #endif /* SQLITE_MUTEX_W32 */ |  | 
| OLD | NEW |