OLD | NEW |
1 /* | 1 /* |
2 ** 2007 August 14 | 2 ** 2007 August 14 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
11 ************************************************************************* | 11 ************************************************************************* |
12 ** This file contains the C functions that implement mutexes for win32 | 12 ** This file contains the C functions that implement mutexes for win32 |
13 ** | |
14 ** $Id: mutex_w32.c,v 1.18 2009/08/10 03:23:21 shane Exp $ | |
15 */ | 13 */ |
16 #include "sqliteInt.h" | 14 #include "sqliteInt.h" |
17 | 15 |
18 /* | 16 /* |
19 ** The code in this file is only used if we are compiling multithreaded | 17 ** The code in this file is only used if we are compiling multithreaded |
20 ** on a win32 system. | 18 ** on a win32 system. |
21 */ | 19 */ |
22 #ifdef SQLITE_MUTEX_W32 | 20 #ifdef SQLITE_MUTEX_W32 |
23 | 21 |
24 /* | 22 /* |
25 ** Each recursive mutex is an instance of the following structure. | 23 ** Each recursive mutex is an instance of the following structure. |
26 */ | 24 */ |
27 struct sqlite3_mutex { | 25 struct sqlite3_mutex { |
28 CRITICAL_SECTION mutex; /* Mutex controlling the lock */ | 26 CRITICAL_SECTION mutex; /* Mutex controlling the lock */ |
29 int id; /* Mutex type */ | 27 int id; /* Mutex type */ |
30 int nRef; /* Number of enterances */ | 28 #ifdef SQLITE_DEBUG |
31 DWORD owner; /* Thread holding this mutex */ | 29 volatile int nRef; /* Number of enterances */ |
| 30 volatile DWORD owner; /* Thread holding this mutex */ |
| 31 int trace; /* True to trace changes */ |
| 32 #endif |
32 }; | 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 |
33 | 40 |
34 /* | 41 /* |
35 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, | 42 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, |
36 ** or WinCE. Return false (zero) for Win95, Win98, or WinME. | 43 ** or WinCE. Return false (zero) for Win95, Win98, or WinME. |
37 ** | 44 ** |
38 ** Here is an interesting observation: Win95, Win98, and WinME lack | 45 ** Here is an interesting observation: Win95, Win98, and WinME lack |
39 ** the LockFileEx() API. But we can still statically link against that | 46 ** 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 | 47 ** 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 | 48 ** 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 | 49 ** WinNT/2K/XP so that we will know whether or not we can safely call |
(...skipping 23 matching lines...) Expand all Loading... |
66 #endif | 73 #endif |
67 | 74 |
68 #ifdef SQLITE_DEBUG | 75 #ifdef SQLITE_DEBUG |
69 /* | 76 /* |
70 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are | 77 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
71 ** intended for use only inside assert() statements. | 78 ** intended for use only inside assert() statements. |
72 */ | 79 */ |
73 static int winMutexHeld(sqlite3_mutex *p){ | 80 static int winMutexHeld(sqlite3_mutex *p){ |
74 return p->nRef!=0 && p->owner==GetCurrentThreadId(); | 81 return p->nRef!=0 && p->owner==GetCurrentThreadId(); |
75 } | 82 } |
| 83 static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ |
| 84 return p->nRef==0 || p->owner!=tid; |
| 85 } |
76 static int winMutexNotheld(sqlite3_mutex *p){ | 86 static int winMutexNotheld(sqlite3_mutex *p){ |
77 return p->nRef==0 || p->owner!=GetCurrentThreadId(); | 87 DWORD tid = GetCurrentThreadId(); |
| 88 return winMutexNotheld2(p, tid); |
78 } | 89 } |
79 #endif | 90 #endif |
80 | 91 |
81 | 92 |
82 /* | 93 /* |
83 ** Initialize and deinitialize the mutex subsystem. | 94 ** Initialize and deinitialize the mutex subsystem. |
84 */ | 95 */ |
85 static sqlite3_mutex winMutex_staticMutexes[6]; | 96 static 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 }; |
86 static int winMutex_isInit = 0; | 104 static int winMutex_isInit = 0; |
87 /* As winMutexInit() and winMutexEnd() are called as part | 105 /* As winMutexInit() and winMutexEnd() are called as part |
88 ** of the sqlite3_initialize and sqlite3_shutdown() | 106 ** of the sqlite3_initialize and sqlite3_shutdown() |
89 ** processing, the "interlocked" magic is probably not | 107 ** processing, the "interlocked" magic is probably not |
90 ** strictly necessary. | 108 ** strictly necessary. |
91 */ | 109 */ |
92 static long winMutex_lock = 0; | 110 static long winMutex_lock = 0; |
93 | 111 |
94 static int winMutexInit(void){ | 112 static int winMutexInit(void){ |
95 /* The first to increment to 1 does actual initialization */ | 113 /* The first to increment to 1 does actual initialization */ |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 ** the same type number. | 184 ** the same type number. |
167 */ | 185 */ |
168 static sqlite3_mutex *winMutexAlloc(int iType){ | 186 static sqlite3_mutex *winMutexAlloc(int iType){ |
169 sqlite3_mutex *p; | 187 sqlite3_mutex *p; |
170 | 188 |
171 switch( iType ){ | 189 switch( iType ){ |
172 case SQLITE_MUTEX_FAST: | 190 case SQLITE_MUTEX_FAST: |
173 case SQLITE_MUTEX_RECURSIVE: { | 191 case SQLITE_MUTEX_RECURSIVE: { |
174 p = sqlite3MallocZero( sizeof(*p) ); | 192 p = sqlite3MallocZero( sizeof(*p) ); |
175 if( p ){ | 193 if( p ){ |
| 194 #ifdef SQLITE_DEBUG |
176 p->id = iType; | 195 p->id = iType; |
| 196 #endif |
177 InitializeCriticalSection(&p->mutex); | 197 InitializeCriticalSection(&p->mutex); |
178 } | 198 } |
179 break; | 199 break; |
180 } | 200 } |
181 default: { | 201 default: { |
182 assert( winMutex_isInit==1 ); | 202 assert( winMutex_isInit==1 ); |
183 assert( iType-2 >= 0 ); | 203 assert( iType-2 >= 0 ); |
184 assert( iType-2 < ArraySize(winMutex_staticMutexes) ); | 204 assert( iType-2 < ArraySize(winMutex_staticMutexes) ); |
185 p = &winMutex_staticMutexes[iType-2]; | 205 p = &winMutex_staticMutexes[iType-2]; |
| 206 #ifdef SQLITE_DEBUG |
186 p->id = iType; | 207 p->id = iType; |
| 208 #endif |
187 break; | 209 break; |
188 } | 210 } |
189 } | 211 } |
190 return p; | 212 return p; |
191 } | 213 } |
192 | 214 |
193 | 215 |
194 /* | 216 /* |
195 ** This routine deallocates a previously | 217 ** This routine deallocates a previously |
196 ** allocated mutex. SQLite is careful to deallocate every | 218 ** allocated mutex. SQLite is careful to deallocate every |
197 ** mutex that it allocates. | 219 ** mutex that it allocates. |
198 */ | 220 */ |
199 static void winMutexFree(sqlite3_mutex *p){ | 221 static void winMutexFree(sqlite3_mutex *p){ |
200 assert( p ); | 222 assert( p ); |
201 assert( p->nRef==0 ); | 223 assert( p->nRef==0 && p->owner==0 ); |
202 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); | 224 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
203 DeleteCriticalSection(&p->mutex); | 225 DeleteCriticalSection(&p->mutex); |
204 sqlite3_free(p); | 226 sqlite3_free(p); |
205 } | 227 } |
206 | 228 |
207 /* | 229 /* |
208 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt | 230 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt |
209 ** to enter a mutex. If another thread is already within the mutex, | 231 ** to enter a mutex. If another thread is already within the mutex, |
210 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return | 232 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return |
211 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK | 233 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK |
212 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can | 234 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can |
213 ** be entered multiple times by the same thread. In such cases the, | 235 ** be entered multiple times by the same thread. In such cases the, |
214 ** mutex must be exited an equal number of times before another thread | 236 ** mutex must be exited an equal number of times before another thread |
215 ** can enter. If the same thread tries to enter any other kind of mutex | 237 ** can enter. If the same thread tries to enter any other kind of mutex |
216 ** more than once, the behavior is undefined. | 238 ** more than once, the behavior is undefined. |
217 */ | 239 */ |
218 static void winMutexEnter(sqlite3_mutex *p){ | 240 static void winMutexEnter(sqlite3_mutex *p){ |
219 assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); | 241 #ifdef SQLITE_DEBUG |
| 242 DWORD tid = GetCurrentThreadId(); |
| 243 assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
| 244 #endif |
220 EnterCriticalSection(&p->mutex); | 245 EnterCriticalSection(&p->mutex); |
221 p->owner = GetCurrentThreadId(); | 246 #ifdef SQLITE_DEBUG |
| 247 assert( p->nRef>0 || p->owner==0 ); |
| 248 p->owner = tid; |
222 p->nRef++; | 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 |
223 } | 254 } |
224 static int winMutexTry(sqlite3_mutex *p){ | 255 static int winMutexTry(sqlite3_mutex *p){ |
| 256 #ifndef NDEBUG |
| 257 DWORD tid = GetCurrentThreadId(); |
| 258 #endif |
225 int rc = SQLITE_BUSY; | 259 int rc = SQLITE_BUSY; |
226 assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) ); | 260 assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); |
227 /* | 261 /* |
228 ** The sqlite3_mutex_try() routine is very rarely used, and when it | 262 ** The sqlite3_mutex_try() routine is very rarely used, and when it |
229 ** is used it is merely an optimization. So it is OK for it to always | 263 ** is used it is merely an optimization. So it is OK for it to always |
230 ** fail. | 264 ** fail. |
231 ** | 265 ** |
232 ** The TryEnterCriticalSection() interface is only available on WinNT. | 266 ** The TryEnterCriticalSection() interface is only available on WinNT. |
233 ** And some windows compilers complain if you try to use it without | 267 ** And some windows compilers complain if you try to use it without |
234 ** first doing some #defines that prevent SQLite from building on Win98. | 268 ** first doing some #defines that prevent SQLite from building on Win98. |
235 ** For that reason, we will omit this optimization for now. See | 269 ** For that reason, we will omit this optimization for now. See |
236 ** ticket #2685. | 270 ** ticket #2685. |
237 */ | 271 */ |
238 #if 0 | 272 #if 0 |
239 if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ | 273 if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){ |
240 p->owner = GetCurrentThreadId(); | 274 p->owner = tid; |
241 p->nRef++; | 275 p->nRef++; |
242 rc = SQLITE_OK; | 276 rc = SQLITE_OK; |
243 } | 277 } |
244 #else | 278 #else |
245 UNUSED_PARAMETER(p); | 279 UNUSED_PARAMETER(p); |
246 #endif | 280 #endif |
| 281 #ifdef SQLITE_DEBUG |
| 282 if( rc==SQLITE_OK && p->trace ){ |
| 283 printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); |
| 284 } |
| 285 #endif |
247 return rc; | 286 return rc; |
248 } | 287 } |
249 | 288 |
250 /* | 289 /* |
251 ** The sqlite3_mutex_leave() routine exits a mutex that was | 290 ** The sqlite3_mutex_leave() routine exits a mutex that was |
252 ** previously entered by the same thread. The behavior | 291 ** previously entered by the same thread. The behavior |
253 ** is undefined if the mutex is not currently entered or | 292 ** is undefined if the mutex is not currently entered or |
254 ** is not currently allocated. SQLite will never do either. | 293 ** is not currently allocated. SQLite will never do either. |
255 */ | 294 */ |
256 static void winMutexLeave(sqlite3_mutex *p){ | 295 static void winMutexLeave(sqlite3_mutex *p){ |
| 296 #ifndef NDEBUG |
| 297 DWORD tid = GetCurrentThreadId(); |
257 assert( p->nRef>0 ); | 298 assert( p->nRef>0 ); |
258 assert( p->owner==GetCurrentThreadId() ); | 299 assert( p->owner==tid ); |
259 p->nRef--; | 300 p->nRef--; |
| 301 if( p->nRef==0 ) p->owner = 0; |
260 assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); | 302 assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 303 #endif |
261 LeaveCriticalSection(&p->mutex); | 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 |
262 } | 310 } |
263 | 311 |
264 sqlite3_mutex_methods *sqlite3DefaultMutex(void){ | 312 sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
265 static sqlite3_mutex_methods sMutex = { | 313 static const sqlite3_mutex_methods sMutex = { |
266 winMutexInit, | 314 winMutexInit, |
267 winMutexEnd, | 315 winMutexEnd, |
268 winMutexAlloc, | 316 winMutexAlloc, |
269 winMutexFree, | 317 winMutexFree, |
270 winMutexEnter, | 318 winMutexEnter, |
271 winMutexTry, | 319 winMutexTry, |
272 winMutexLeave, | 320 winMutexLeave, |
273 #ifdef SQLITE_DEBUG | 321 #ifdef SQLITE_DEBUG |
274 winMutexHeld, | 322 winMutexHeld, |
275 winMutexNotheld | 323 winMutexNotheld |
276 #else | 324 #else |
277 0, | 325 0, |
278 0 | 326 0 |
279 #endif | 327 #endif |
280 }; | 328 }; |
281 | 329 |
282 return &sMutex; | 330 return &sMutex; |
283 } | 331 } |
284 #endif /* SQLITE_MUTEX_W32 */ | 332 #endif /* SQLITE_MUTEX_W32 */ |
OLD | NEW |