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