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