extensions/sqlite/sqlite-source/mutex_w32.c
author Asher Baker <asherkin@gmail.com>
Thu Apr 26 16:58:18 2012 +0100 (2012-04-26)
changeset 3488 bee90c8ef6c3
parent 1645 27307df4d711
permissions -rw-r--r--
Fixed client serials not being unique on Windows (bug 5285, r=psychonic).
     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$
    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 #if OS_WINCE
    46 # define mutexIsNT()  (1)
    47 #else
    48   static int mutexIsNT(void){
    49     static int osType = 0;
    50     if( osType==0 ){
    51       OSVERSIONINFO sInfo;
    52       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
    53       GetVersionEx(&sInfo);
    54       osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
    55     }
    56     return osType==2;
    57   }
    58 #endif /* OS_WINCE */
    59 
    60 
    61 /*
    62 ** The sqlite3_mutex_alloc() routine allocates a new
    63 ** mutex and returns a pointer to it.  If it returns NULL
    64 ** that means that a mutex could not be allocated.  SQLite
    65 ** will unwind its stack and return an error.  The argument
    66 ** to sqlite3_mutex_alloc() is one of these integer constants:
    67 **
    68 ** <ul>
    69 ** <li>  SQLITE_MUTEX_FAST               0
    70 ** <li>  SQLITE_MUTEX_RECURSIVE          1
    71 ** <li>  SQLITE_MUTEX_STATIC_MASTER      2
    72 ** <li>  SQLITE_MUTEX_STATIC_MEM         3
    73 ** <li>  SQLITE_MUTEX_STATIC_PRNG        4
    74 ** </ul>
    75 **
    76 ** The first two constants cause sqlite3_mutex_alloc() to create
    77 ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
    78 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
    79 ** The mutex implementation does not need to make a distinction
    80 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
    81 ** not want to.  But SQLite will only request a recursive mutex in
    82 ** cases where it really needs one.  If a faster non-recursive mutex
    83 ** implementation is available on the host platform, the mutex subsystem
    84 ** might return such a mutex in response to SQLITE_MUTEX_FAST.
    85 **
    86 ** The other allowed parameters to sqlite3_mutex_alloc() each return
    87 ** a pointer to a static preexisting mutex.  Three static mutexes are
    88 ** used by the current version of SQLite.  Future versions of SQLite
    89 ** may add additional static mutexes.  Static mutexes are for internal
    90 ** use by SQLite only.  Applications that use SQLite mutexes should
    91 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
    92 ** SQLITE_MUTEX_RECURSIVE.
    93 **
    94 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
    95 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
    96 ** returns a different mutex on every call.  But for the static 
    97 ** mutex types, the same mutex is returned on every call that has
    98 ** the same type number.
    99 */
   100 sqlite3_mutex *sqlite3_mutex_alloc(int iType){
   101   sqlite3_mutex *p;
   102 
   103   switch( iType ){
   104     case SQLITE_MUTEX_FAST:
   105     case SQLITE_MUTEX_RECURSIVE: {
   106       p = sqlite3MallocZero( sizeof(*p) );
   107       if( p ){
   108         p->id = iType;
   109         InitializeCriticalSection(&p->mutex);
   110       }
   111       break;
   112     }
   113     default: {
   114       static sqlite3_mutex staticMutexes[5];
   115       static int isInit = 0;
   116       while( !isInit ){
   117         static long lock = 0;
   118         if( InterlockedIncrement(&lock)==1 ){
   119           int i;
   120           for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
   121             InitializeCriticalSection(&staticMutexes[i].mutex);
   122           }
   123           isInit = 1;
   124         }else{
   125           Sleep(1);
   126         }
   127       }
   128       assert( iType-2 >= 0 );
   129       assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
   130       p = &staticMutexes[iType-2];
   131       p->id = iType;
   132       break;
   133     }
   134   }
   135   return p;
   136 }
   137 
   138 
   139 /*
   140 ** This routine deallocates a previously
   141 ** allocated mutex.  SQLite is careful to deallocate every
   142 ** mutex that it allocates.
   143 */
   144 void sqlite3_mutex_free(sqlite3_mutex *p){
   145   assert( p );
   146   assert( p->nRef==0 );
   147   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
   148   DeleteCriticalSection(&p->mutex);
   149   sqlite3_free(p);
   150 }
   151 
   152 /*
   153 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
   154 ** to enter a mutex.  If another thread is already within the mutex,
   155 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
   156 ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
   157 ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
   158 ** be entered multiple times by the same thread.  In such cases the,
   159 ** mutex must be exited an equal number of times before another thread
   160 ** can enter.  If the same thread tries to enter any other kind of mutex
   161 ** more than once, the behavior is undefined.
   162 */
   163 void sqlite3_mutex_enter(sqlite3_mutex *p){
   164   assert( p );
   165   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
   166   EnterCriticalSection(&p->mutex);
   167   p->owner = GetCurrentThreadId(); 
   168   p->nRef++;
   169 }
   170 int sqlite3_mutex_try(sqlite3_mutex *p){
   171   int rc;
   172   assert( p );
   173   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
   174   if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
   175     p->owner = GetCurrentThreadId();
   176     p->nRef++;
   177     rc = SQLITE_OK;
   178   }else{
   179     rc = SQLITE_BUSY;
   180   }
   181   return rc;
   182 }
   183 
   184 /*
   185 ** The sqlite3_mutex_leave() routine exits a mutex that was
   186 ** previously entered by the same thread.  The behavior
   187 ** is undefined if the mutex is not currently entered or
   188 ** is not currently allocated.  SQLite will never do either.
   189 */
   190 void sqlite3_mutex_leave(sqlite3_mutex *p){
   191   assert( p->nRef>0 );
   192   assert( p->owner==GetCurrentThreadId() );
   193   p->nRef--;
   194   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
   195   LeaveCriticalSection(&p->mutex);
   196 }
   197 
   198 /*
   199 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
   200 ** intended for use only inside assert() statements.
   201 */
   202 int sqlite3_mutex_held(sqlite3_mutex *p){
   203   return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId());
   204 }
   205 int sqlite3_mutex_notheld(sqlite3_mutex *p){
   206   return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId();
   207 }
   208 #endif /* SQLITE_MUTEX_W32 */