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.6 2008/03/26 18:34:43 danielk1977 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 #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[6]; 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 = SQLITE_BUSY; 172 assert( p ); 173 assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); 174 /* 175 ** The sqlite3_mutex_try() routine is very rarely used, and when it 176 ** is used it is merely an optimization. So it is OK for it to always 177 ** fail. 178 ** 179 ** The TryEnterCriticalSection() interface is only available on WinNT. 180 ** And some windows compilers complain if you try to use it without 181 ** first doing some #defines that prevent SQLite from building on Win98. 182 ** For that reason, we will omit this optimization for now. See 183 ** ticket #2685. 184 */ 185 #if 0 186 if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ 187 p->owner = GetCurrentThreadId(); 188 p->nRef++; 189 rc = SQLITE_OK; 190 } 191 #endif 192 return rc; 193 } 194 195 /* 196 ** The sqlite3_mutex_leave() routine exits a mutex that was 197 ** previously entered by the same thread. The behavior 198 ** is undefined if the mutex is not currently entered or 199 ** is not currently allocated. SQLite will never do either. 200 */ 201 void sqlite3_mutex_leave(sqlite3_mutex *p){ 202 assert( p->nRef>0 ); 203 assert( p->owner==GetCurrentThreadId() ); 204 p->nRef--; 205 assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); 206 LeaveCriticalSection(&p->mutex); 207 } 208 209 /* 210 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are 211 ** intended for use only inside assert() statements. 212 */ 213 int sqlite3_mutex_held(sqlite3_mutex *p){ 214 return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId()); 215 } 216 int sqlite3_mutex_notheld(sqlite3_mutex *p){ 217 return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId(); 218 } 219 #endif /* SQLITE_MUTEX_W32 */ 220