9
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
13
*/
14
14
#include "sqliteInt.h"
15
15
16
16
#if SQLITE_OS_WIN
17
+ /*
18
+ ** Include code that is common to all os_*.c files
19
+ */
20
+ #include "os_common.h"
21
+
17
22
/*
18
23
** Include the header file for the Windows VFS.
19
24
*/
22
27
23
28
/*
24
29
** The code in this file is only used if we are compiling multithreaded
25
- ** on a win32 system.
30
+ ** on a Win32 system.
26
31
*/
27
32
#ifdef SQLITE_MUTEX_W32
28
33
@@ -35,48 +40,22 @@ struct sqlite3_mutex {
35
40
#ifdef SQLITE_DEBUG
36
41
volatile int nRef ; /* Number of enterances */
37
42
volatile DWORD owner ; /* Thread holding this mutex */
38
- int trace ; /* True to trace changes */
43
+ volatile int trace ; /* True to trace changes */
39
44
#endif
40
45
};
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
46
48
47
/*
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.
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.
64
51
*/
65
- #if 0
66
- #if SQLITE_OS_WINCE || SQLITE_OS_WINRT
67
- # define mutexIsNT () (1)
52
+ #define SQLITE_W32_MUTEX_INITIALIZER { 0 }
53
+
54
+ #ifdef SQLITE_DEBUG
55
+ #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \
56
+ 0L, (DWORD)0, 0 }
68
57
#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 */
58
+ #define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
80
59
#endif
81
60
82
61
#ifdef SQLITE_DEBUG
@@ -87,16 +66,17 @@ struct sqlite3_mutex {
87
66
static int winMutexHeld (sqlite3_mutex * p ){
88
67
return p -> nRef != 0 && p -> owner == GetCurrentThreadId ();
89
68
}
69
+
90
70
static int winMutexNotheld2 (sqlite3_mutex * p , DWORD tid ){
91
71
return p -> nRef == 0 || p -> owner != tid ;
92
72
}
73
+
93
74
static int winMutexNotheld (sqlite3_mutex * p ){
94
- DWORD tid = GetCurrentThreadId ();
75
+ DWORD tid = GetCurrentThreadId ();
95
76
return winMutexNotheld2 (p , tid );
96
77
}
97
78
#endif
98
79
99
-
100
80
/*
101
81
** Initialize and deinitialize the mutex subsystem.
102
82
*/
@@ -108,17 +88,20 @@ static sqlite3_mutex winMutex_staticMutexes[6] = {
108
88
SQLITE3_MUTEX_INITIALIZER ,
109
89
SQLITE3_MUTEX_INITIALIZER
110
90
};
91
+
111
92
static int winMutex_isInit = 0 ;
112
- /* As winMutexInit() and winMutexEnd() are called as part
113
- ** of the sqlite3_initialize and sqlite3_shutdown()
114
- ** processing, the "interlocked" magic is probably not
115
- ** strictly necessary.
93
+
94
+ /* As winMutexInit() and winMutexEnd() are called as part of the
95
+ ** sqlite3_initialize() and sqlite3_shutdown() processing, the
96
+ ** "interlocked" magic used in this section may not strictly
97
+ ** necessary.
116
98
*/
117
99
static LONG winMutex_lock = 0 ;
118
100
101
+ int sqlite3_win32_is_nt (void ); /* os_win.c */
119
102
void sqlite3_win32_sleep (DWORD milliseconds ); /* os_win.c */
120
103
121
- static int winMutexInit (void ){
104
+ static int winMutexInit (void ){
122
105
/* The first to increment to 1 does actual initialization */
123
106
if ( InterlockedCompareExchange (& winMutex_lock , 1 , 0 )== 0 ){
124
107
int i ;
@@ -131,16 +114,17 @@ static int winMutexInit(void){
131
114
}
132
115
winMutex_isInit = 1 ;
133
116
}else {
134
- /* Someone else is in the process of initing the static mutexes */
117
+ /* Another thread is (in the process of) initializing the static
118
+ ** mutexes */
135
119
while ( !winMutex_isInit ){
136
120
sqlite3_win32_sleep (1 );
137
121
}
138
122
}
139
- return SQLITE_OK ;
123
+ return SQLITE_OK ;
140
124
}
141
125
142
- static int winMutexEnd (void ){
143
- /* The first to decrement to 0 does actual shutdown
126
+ static int winMutexEnd (void ){
127
+ /* The first to decrement to 0 does actual shutdown
144
128
** (which should be the last to shutdown.) */
145
129
if ( InterlockedCompareExchange (& winMutex_lock , 0 , 1 )== 1 ){
146
130
if ( winMutex_isInit == 1 ){
@@ -151,7 +135,7 @@ static int winMutexEnd(void){
151
135
winMutex_isInit = 0 ;
152
136
}
153
137
}
154
- return SQLITE_OK ;
138
+ return SQLITE_OK ;
155
139
}
156
140
157
141
/*
@@ -192,7 +176,7 @@ static int winMutexEnd(void){
192
176
**
193
177
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
194
178
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
195
- ** returns a different mutex on every call. But for the static
179
+ ** returns a different mutex on every call. But for the static
196
180
** mutex types, the same mutex is returned on every call that has
197
181
** the same type number.
198
182
*/
@@ -203,9 +187,12 @@ static sqlite3_mutex *winMutexAlloc(int iType){
203
187
case SQLITE_MUTEX_FAST :
204
188
case SQLITE_MUTEX_RECURSIVE : {
205
189
p = sqlite3MallocZero ( sizeof (* p ) );
206
- if ( p ){
190
+ if ( p ){
207
191
#ifdef SQLITE_DEBUG
208
192
p -> id = iType ;
193
+ #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
194
+ p -> trace = 1 ;
195
+ #endif
209
196
#endif
210
197
#if SQLITE_OS_WINRT
211
198
InitializeCriticalSectionEx (& p -> mutex , 0 , 0 );
@@ -216,12 +203,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
216
203
break ;
217
204
}
218
205
default : {
219
- assert ( winMutex_isInit == 1 );
220
206
assert ( iType - 2 >= 0 );
221
207
assert ( iType - 2 < ArraySize (winMutex_staticMutexes ) );
208
+ assert ( winMutex_isInit == 1 );
222
209
p = & winMutex_staticMutexes [iType - 2 ];
223
210
#ifdef SQLITE_DEBUG
224
211
p -> id = iType ;
212
+ #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
213
+ p -> trace = 1 ;
214
+ #endif
225
215
#endif
226
216
break ;
227
217
}
@@ -237,8 +227,10 @@ static sqlite3_mutex *winMutexAlloc(int iType){
237
227
*/
238
228
static void winMutexFree (sqlite3_mutex * p ){
239
229
assert ( p );
230
+ #ifdef SQLITE_DEBUG
240
231
assert ( p -> nRef == 0 && p -> owner == 0 );
241
232
assert ( p -> id == SQLITE_MUTEX_FAST || p -> id == SQLITE_MUTEX_RECURSIVE );
233
+ #endif
242
234
DeleteCriticalSection (& p -> mutex );
243
235
sqlite3_free (p );
244
236
}
@@ -255,49 +247,60 @@ static void winMutexFree(sqlite3_mutex *p){
255
247
** more than once, the behavior is undefined.
256
248
*/
257
249
static void winMutexEnter (sqlite3_mutex * p ){
250
+ #if defined(SQLITE_DEBUG ) || defined(SQLITE_TEST )
251
+ DWORD tid = GetCurrentThreadId ();
252
+ #endif
258
253
#ifdef SQLITE_DEBUG
259
- DWORD tid = GetCurrentThreadId ();
254
+ assert ( p );
260
255
assert ( p -> id == SQLITE_MUTEX_RECURSIVE || winMutexNotheld2 (p , tid ) );
256
+ #else
257
+ assert ( p );
261
258
#endif
262
259
EnterCriticalSection (& p -> mutex );
263
260
#ifdef SQLITE_DEBUG
264
261
assert ( p -> nRef > 0 || p -> owner == 0 );
265
- p -> owner = tid ;
262
+ p -> owner = tid ;
266
263
p -> nRef ++ ;
267
264
if ( p -> trace ){
268
- printf ("enter mutex %p (%d) with nRef=%d\n" , p , p -> trace , p -> nRef );
265
+ OSTRACE (("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n" ,
266
+ tid , p , p -> trace , p -> nRef ));
269
267
}
270
268
#endif
271
269
}
270
+
272
271
static int winMutexTry (sqlite3_mutex * p ){
273
- #ifndef NDEBUG
274
- DWORD tid = GetCurrentThreadId ();
272
+ #if defined( SQLITE_DEBUG ) || defined( SQLITE_TEST )
273
+ DWORD tid = GetCurrentThreadId ();
275
274
#endif
276
275
int rc = SQLITE_BUSY ;
276
+ assert ( p );
277
277
assert ( p -> id == SQLITE_MUTEX_RECURSIVE || winMutexNotheld2 (p , tid ) );
278
278
/*
279
279
** The sqlite3_mutex_try() routine is very rarely used, and when it
280
280
** is used it is merely an optimization. So it is OK for it to always
281
- ** fail.
281
+ ** fail.
282
282
**
283
283
** The TryEnterCriticalSection() interface is only available on WinNT.
284
284
** And some windows compilers complain if you try to use it without
285
285
** first doing some #defines that prevent SQLite from building on Win98.
286
286
** For that reason, we will omit this optimization for now. See
287
287
** ticket #2685.
288
288
*/
289
- #if 0
290
- if ( mutexIsNT () && TryEnterCriticalSection (& p -> mutex ) ){
289
+ #if defined(_WIN32_WINNT ) && _WIN32_WINNT >= 0x0400
290
+ if ( sqlite3_win32_is_nt () && TryEnterCriticalSection (& p -> mutex ) ){
291
+ #ifdef SQLITE_DEBUG
291
292
p -> owner = tid ;
292
293
p -> nRef ++ ;
294
+ #endif
293
295
rc = SQLITE_OK ;
294
296
}
295
297
#else
296
298
UNUSED_PARAMETER (p );
297
299
#endif
298
300
#ifdef SQLITE_DEBUG
299
- if ( rc == SQLITE_OK && p -> trace ){
300
- printf ("try mutex %p (%d) with nRef=%d\n" , p , p -> trace , p -> nRef );
301
+ if ( p -> trace ){
302
+ OSTRACE (("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n" ,
303
+ tid , p , p -> trace , p -> owner , p -> nRef , sqlite3ErrName (rc )));
301
304
}
302
305
#endif
303
306
return rc ;
@@ -310,8 +313,11 @@ static int winMutexTry(sqlite3_mutex *p){
310
313
** is not currently allocated. SQLite will never do either.
311
314
*/
312
315
static void winMutexLeave (sqlite3_mutex * p ){
313
- #ifndef NDEBUG
316
+ #if defined( SQLITE_DEBUG ) || defined( SQLITE_TEST )
314
317
DWORD tid = GetCurrentThreadId ();
318
+ #endif
319
+ assert ( p );
320
+ #ifdef SQLITE_DEBUG
315
321
assert ( p -> nRef > 0 );
316
322
assert ( p -> owner == tid );
317
323
p -> nRef -- ;
@@ -321,7 +327,8 @@ static void winMutexLeave(sqlite3_mutex *p){
321
327
LeaveCriticalSection (& p -> mutex );
322
328
#ifdef SQLITE_DEBUG
323
329
if ( p -> trace ){
324
- printf ("leave mutex %p (%d) with nRef=%d\n" , p , p -> trace , p -> nRef );
330
+ OSTRACE (("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n" ,
331
+ tid , p , p -> trace , p -> nRef ));
325
332
}
326
333
#endif
327
334
}
@@ -343,7 +350,7 @@ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
343
350
0
344
351
#endif
345
352
};
346
-
347
353
return & sMutex ;
348
354
}
355
+
349
356
#endif /* SQLITE_MUTEX_W32 */
0 commit comments