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