mutex_w32.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 for win32
00013 **
00014 ** $Id: mutex_w32.c,v 1.12 2008/11/10 20:01:41 shane Exp $
00015 */
00016 #include "sqliteInt.h"
00017 
00018 /*
00019 ** The code in this file is only used if we are compiling multithreaded
00020 ** on a win32 system.
00021 */
00022 #ifdef SQLITE_MUTEX_W32
00023 
00024 /*
00025 ** Each recursive mutex is an instance of the following structure.
00026 */
00027 struct sqlite3_mutex {
00028   CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
00029   int id;                    /* Mutex type */
00030   int nRef;                  /* Number of enterances */
00031   DWORD owner;               /* Thread holding this mutex */
00032 };
00033 
00034 /*
00035 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
00036 ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
00037 **
00038 ** Here is an interesting observation:  Win95, Win98, and WinME lack
00039 ** the LockFileEx() API.  But we can still statically link against that
00040 ** API as long as we don't call it win running Win95/98/ME.  A call to
00041 ** this routine is used to determine if the host is Win95/98/ME or
00042 ** WinNT/2K/XP so that we will know whether or not we can safely call
00043 ** the LockFileEx() API.
00044 **
00045 ** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
00046 ** which is only available if your application was compiled with 
00047 ** _WIN32_WINNT defined to a value >= 0x0400.  Currently, the only
00048 ** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef 
00049 ** this out as well.
00050 */
00051 #if 0
00052 #if SQLITE_OS_WINCE
00053 # define mutexIsNT()  (1)
00054 #else
00055   static int mutexIsNT(void){
00056     static int osType = 0;
00057     if( osType==0 ){
00058       OSVERSIONINFO sInfo;
00059       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
00060       GetVersionEx(&sInfo);
00061       osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
00062     }
00063     return osType==2;
00064   }
00065 #endif /* SQLITE_OS_WINCE */
00066 #endif
00067 
00068 #ifdef SQLITE_DEBUG
00069 /*
00070 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
00071 ** intended for use only inside assert() statements.
00072 */
00073 static int winMutexHeld(sqlite3_mutex *p){
00074   return p->nRef!=0 && p->owner==GetCurrentThreadId();
00075 }
00076 static int winMutexNotheld(sqlite3_mutex *p){
00077   return p->nRef==0 || p->owner!=GetCurrentThreadId();
00078 }
00079 #endif
00080 
00081 
00082 /*
00083 ** Initialize and deinitialize the mutex subsystem.
00084 */
00085 static int winMutexInit(void){ return SQLITE_OK; }
00086 static int winMutexEnd(void){ return SQLITE_OK; }
00087 
00088 /*
00089 ** The sqlite3_mutex_alloc() routine allocates a new
00090 ** mutex and returns a pointer to it.  If it returns NULL
00091 ** that means that a mutex could not be allocated.  SQLite
00092 ** will unwind its stack and return an error.  The argument
00093 ** to sqlite3_mutex_alloc() is one of these integer constants:
00094 **
00095 ** <ul>
00096 ** <li>  SQLITE_MUTEX_FAST               0
00097 ** <li>  SQLITE_MUTEX_RECURSIVE          1
00098 ** <li>  SQLITE_MUTEX_STATIC_MASTER      2
00099 ** <li>  SQLITE_MUTEX_STATIC_MEM         3
00100 ** <li>  SQLITE_MUTEX_STATIC_PRNG        4
00101 ** </ul>
00102 **
00103 ** The first two constants cause sqlite3_mutex_alloc() to create
00104 ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
00105 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
00106 ** The mutex implementation does not need to make a distinction
00107 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
00108 ** not want to.  But SQLite will only request a recursive mutex in
00109 ** cases where it really needs one.  If a faster non-recursive mutex
00110 ** implementation is available on the host platform, the mutex subsystem
00111 ** might return such a mutex in response to SQLITE_MUTEX_FAST.
00112 **
00113 ** The other allowed parameters to sqlite3_mutex_alloc() each return
00114 ** a pointer to a static preexisting mutex.  Three static mutexes are
00115 ** used by the current version of SQLite.  Future versions of SQLite
00116 ** may add additional static mutexes.  Static mutexes are for internal
00117 ** use by SQLite only.  Applications that use SQLite mutexes should
00118 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
00119 ** SQLITE_MUTEX_RECURSIVE.
00120 **
00121 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
00122 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
00123 ** returns a different mutex on every call.  But for the static 
00124 ** mutex types, the same mutex is returned on every call that has
00125 ** the same type number.
00126 */
00127 static sqlite3_mutex *winMutexAlloc(int iType){
00128   sqlite3_mutex *p;
00129 
00130   switch( iType ){
00131     case SQLITE_MUTEX_FAST:
00132     case SQLITE_MUTEX_RECURSIVE: {
00133       p = sqlite3MallocZero( sizeof(*p) );
00134       if( p ){
00135         p->id = iType;
00136         InitializeCriticalSection(&p->mutex);
00137       }
00138       break;
00139     }
00140     default: {
00141       static sqlite3_mutex staticMutexes[6];
00142       static int isInit = 0;
00143       while( !isInit ){
00144         static long lock = 0;
00145         if( InterlockedIncrement(&lock)==1 ){
00146           int i;
00147           for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
00148             InitializeCriticalSection(&staticMutexes[i].mutex);
00149           }
00150           isInit = 1;
00151         }else{
00152           Sleep(1);
00153         }
00154       }
00155       assert( iType-2 >= 0 );
00156       assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
00157       p = &staticMutexes[iType-2];
00158       p->id = iType;
00159       break;
00160     }
00161   }
00162   return p;
00163 }
00164 
00165 
00166 /*
00167 ** This routine deallocates a previously
00168 ** allocated mutex.  SQLite is careful to deallocate every
00169 ** mutex that it allocates.
00170 */
00171 static void winMutexFree(sqlite3_mutex *p){
00172   assert( p );
00173   assert( p->nRef==0 );
00174   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
00175   DeleteCriticalSection(&p->mutex);
00176   sqlite3_free(p);
00177 }
00178 
00179 /*
00180 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
00181 ** to enter a mutex.  If another thread is already within the mutex,
00182 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
00183 ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
00184 ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
00185 ** be entered multiple times by the same thread.  In such cases the,
00186 ** mutex must be exited an equal number of times before another thread
00187 ** can enter.  If the same thread tries to enter any other kind of mutex
00188 ** more than once, the behavior is undefined.
00189 */
00190 static void winMutexEnter(sqlite3_mutex *p){
00191   assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
00192   EnterCriticalSection(&p->mutex);
00193   p->owner = GetCurrentThreadId(); 
00194   p->nRef++;
00195 }
00196 static int winMutexTry(sqlite3_mutex *p){
00197   int rc = SQLITE_BUSY;
00198   assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
00199   /*
00200   ** The sqlite3_mutex_try() routine is very rarely used, and when it
00201   ** is used it is merely an optimization.  So it is OK for it to always
00202   ** fail.  
00203   **
00204   ** The TryEnterCriticalSection() interface is only available on WinNT.
00205   ** And some windows compilers complain if you try to use it without
00206   ** first doing some #defines that prevent SQLite from building on Win98.
00207   ** For that reason, we will omit this optimization for now.  See
00208   ** ticket #2685.
00209   */
00210 #if 0
00211   if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
00212     p->owner = GetCurrentThreadId();
00213     p->nRef++;
00214     rc = SQLITE_OK;
00215   }
00216 #endif
00217   return rc;
00218 }
00219 
00220 /*
00221 ** The sqlite3_mutex_leave() routine exits a mutex that was
00222 ** previously entered by the same thread.  The behavior
00223 ** is undefined if the mutex is not currently entered or
00224 ** is not currently allocated.  SQLite will never do either.
00225 */
00226 static void winMutexLeave(sqlite3_mutex *p){
00227   assert( p->nRef>0 );
00228   assert( p->owner==GetCurrentThreadId() );
00229   p->nRef--;
00230   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
00231   LeaveCriticalSection(&p->mutex);
00232 }
00233 
00234 sqlite3_mutex_methods *sqlite3DefaultMutex(void){
00235   static sqlite3_mutex_methods sMutex = {
00236     winMutexInit,
00237     winMutexEnd,
00238     winMutexAlloc,
00239     winMutexFree,
00240     winMutexEnter,
00241     winMutexTry,
00242     winMutexLeave,
00243 #ifdef SQLITE_DEBUG
00244     winMutexHeld,
00245     winMutexNotheld
00246 #endif
00247   };
00248 
00249   return &sMutex;
00250 }
00251 #endif /* SQLITE_MUTEX_W32 */

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1