Skip to content

Commit d691865

Browse files
author
mistachkin
committed
Enhancements and updates to the Win32 mutex subsystem.
FossilOrigin-Name: 18984c321049a759f6619cfa17fb3f4e7b3e08ea
1 parent e6bc1ef commit d691865

File tree

5 files changed

+105
-89
lines changed

5 files changed

+105
-89
lines changed

manifest

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
C Remove\san\sunreachable\sbranch\sfrom\sthe\ssqlite3_value_numeric_type()\sinterface.
2-
D 2014-07-26T20:12:56.006
1+
C Enhancements\sand\supdates\sto\sthe\sWin32\smutex\ssubsystem.
2+
D 2014-07-29T05:49:02.604
33
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
44
F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
55
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -189,7 +189,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
189189
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
190190
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
191191
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
192-
F src/main.c cfdb2aa5d248ff1af60227cc3f6d485ba86f92dc
192+
F src/main.c 2c7647fd706cbb048e2b70429e552a7bf732d298
193193
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
194194
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
195195
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
@@ -201,14 +201,14 @@ F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc
201201
F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea
202202
F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553
203203
F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
204-
F src/mutex_w32.c 9bcab6e699fdb20eae784237c36b299830fb3316
204+
F src/mutex_w32.c 45020ed78735a202ff14efcf19415d29f556f16d
205205
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
206206
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
207207
F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e
208208
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
209209
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
210210
F src/os_unix.c a7baf1b30f3c58ba20b813e01aab23b18ae44f85
211-
F src/os_win.c 8dbf6c11780fe2eb96c1f289e664d0c7b2911d37
211+
F src/os_win.c c29e3a80b47ebdbabd61fc3d4015e52d2654d8c5
212212
F src/os_win.h 057344a6720b4c8405d9bd98f58cb37a6ee46c25
213213
F src/pager.c f6bb1fa6cdf2062f2d8aec3e64db302bca519ab8
214214
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
@@ -1184,7 +1184,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
11841184
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
11851185
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
11861186
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
1187-
P 413d7287977702fa651c0140bd5cf29021fe3e79
1188-
R 882befeb8b61995267c9bc4311daa690
1189-
U drh
1190-
Z 28fa8e103cbfa69958d1f03600e24fde
1187+
P 5350229b52b18a4961858a30538c5c75e5bd3048
1188+
R de509ee2752907682d663ce7b389c5a6
1189+
T *branch * winMutex
1190+
T *sym-winMutex *
1191+
T -sym-trunk *
1192+
U mistachkin
1193+
Z 9395c7aaf9a6a0a0988325332158758a

manifest.uuid

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5350229b52b18a4961858a30538c5c75e5bd3048
1+
18984c321049a759f6619cfa17fb3f4e7b3e08ea

src/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
10561056
** Return a static string containing the name corresponding to the error code
10571057
** specified in the argument.
10581058
*/
1059-
#if defined(SQLITE_TEST)
1059+
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
10601060
const char *sqlite3ErrName(int rc){
10611061
const char *zName = 0;
10621062
int i, origRc = rc;

src/mutex_w32.c

Lines changed: 73 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,16 @@
99
** May you share freely, never taking more than you give.
1010
**
1111
*************************************************************************
12-
** This file contains the C functions that implement mutexes for win32
12+
** This file contains the C functions that implement mutexes for Win32.
1313
*/
1414
#include "sqliteInt.h"
1515

1616
#if SQLITE_OS_WIN
17+
/*
18+
** Include code that is common to all os_*.c files
19+
*/
20+
#include "os_common.h"
21+
1722
/*
1823
** Include the header file for the Windows VFS.
1924
*/
@@ -22,7 +27,7 @@
2227

2328
/*
2429
** The code in this file is only used if we are compiling multithreaded
25-
** on a win32 system.
30+
** on a Win32 system.
2631
*/
2732
#ifdef SQLITE_MUTEX_W32
2833

@@ -35,48 +40,22 @@ struct sqlite3_mutex {
3540
#ifdef SQLITE_DEBUG
3641
volatile int nRef; /* Number of enterances */
3742
volatile DWORD owner; /* Thread holding this mutex */
38-
int trace; /* True to trace changes */
43+
volatile int trace; /* True to trace changes */
3944
#endif
4045
};
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
4746

4847
/*
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.
6451
*/
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 }
6857
#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 }
8059
#endif
8160

8261
#ifdef SQLITE_DEBUG
@@ -87,16 +66,17 @@ struct sqlite3_mutex {
8766
static int winMutexHeld(sqlite3_mutex *p){
8867
return p->nRef!=0 && p->owner==GetCurrentThreadId();
8968
}
69+
9070
static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
9171
return p->nRef==0 || p->owner!=tid;
9272
}
73+
9374
static int winMutexNotheld(sqlite3_mutex *p){
94-
DWORD tid = GetCurrentThreadId();
75+
DWORD tid = GetCurrentThreadId();
9576
return winMutexNotheld2(p, tid);
9677
}
9778
#endif
9879

99-
10080
/*
10181
** Initialize and deinitialize the mutex subsystem.
10282
*/
@@ -108,17 +88,20 @@ static sqlite3_mutex winMutex_staticMutexes[6] = {
10888
SQLITE3_MUTEX_INITIALIZER,
10989
SQLITE3_MUTEX_INITIALIZER
11090
};
91+
11192
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.
11698
*/
11799
static LONG winMutex_lock = 0;
118100

101+
int sqlite3_win32_is_nt(void); /* os_win.c */
119102
void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
120103

121-
static int winMutexInit(void){
104+
static int winMutexInit(void){
122105
/* The first to increment to 1 does actual initialization */
123106
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
124107
int i;
@@ -131,16 +114,17 @@ static int winMutexInit(void){
131114
}
132115
winMutex_isInit = 1;
133116
}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 */
135119
while( !winMutex_isInit ){
136120
sqlite3_win32_sleep(1);
137121
}
138122
}
139-
return SQLITE_OK;
123+
return SQLITE_OK;
140124
}
141125

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
144128
** (which should be the last to shutdown.) */
145129
if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
146130
if( winMutex_isInit==1 ){
@@ -151,7 +135,7 @@ static int winMutexEnd(void){
151135
winMutex_isInit = 0;
152136
}
153137
}
154-
return SQLITE_OK;
138+
return SQLITE_OK;
155139
}
156140

157141
/*
@@ -192,7 +176,7 @@ static int winMutexEnd(void){
192176
**
193177
** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
194178
** 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
196180
** mutex types, the same mutex is returned on every call that has
197181
** the same type number.
198182
*/
@@ -203,9 +187,12 @@ static sqlite3_mutex *winMutexAlloc(int iType){
203187
case SQLITE_MUTEX_FAST:
204188
case SQLITE_MUTEX_RECURSIVE: {
205189
p = sqlite3MallocZero( sizeof(*p) );
206-
if( p ){
190+
if( p ){
207191
#ifdef SQLITE_DEBUG
208192
p->id = iType;
193+
#ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
194+
p->trace = 1;
195+
#endif
209196
#endif
210197
#if SQLITE_OS_WINRT
211198
InitializeCriticalSectionEx(&p->mutex, 0, 0);
@@ -216,12 +203,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
216203
break;
217204
}
218205
default: {
219-
assert( winMutex_isInit==1 );
220206
assert( iType-2 >= 0 );
221207
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
208+
assert( winMutex_isInit==1 );
222209
p = &winMutex_staticMutexes[iType-2];
223210
#ifdef SQLITE_DEBUG
224211
p->id = iType;
212+
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
213+
p->trace = 1;
214+
#endif
225215
#endif
226216
break;
227217
}
@@ -237,8 +227,10 @@ static sqlite3_mutex *winMutexAlloc(int iType){
237227
*/
238228
static void winMutexFree(sqlite3_mutex *p){
239229
assert( p );
230+
#ifdef SQLITE_DEBUG
240231
assert( p->nRef==0 && p->owner==0 );
241232
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
233+
#endif
242234
DeleteCriticalSection(&p->mutex);
243235
sqlite3_free(p);
244236
}
@@ -255,49 +247,60 @@ static void winMutexFree(sqlite3_mutex *p){
255247
** more than once, the behavior is undefined.
256248
*/
257249
static void winMutexEnter(sqlite3_mutex *p){
250+
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
251+
DWORD tid = GetCurrentThreadId();
252+
#endif
258253
#ifdef SQLITE_DEBUG
259-
DWORD tid = GetCurrentThreadId();
254+
assert( p );
260255
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
256+
#else
257+
assert( p );
261258
#endif
262259
EnterCriticalSection(&p->mutex);
263260
#ifdef SQLITE_DEBUG
264261
assert( p->nRef>0 || p->owner==0 );
265-
p->owner = tid;
262+
p->owner = tid;
266263
p->nRef++;
267264
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));
269267
}
270268
#endif
271269
}
270+
272271
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();
275274
#endif
276275
int rc = SQLITE_BUSY;
276+
assert( p );
277277
assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
278278
/*
279279
** The sqlite3_mutex_try() routine is very rarely used, and when it
280280
** is used it is merely an optimization. So it is OK for it to always
281-
** fail.
281+
** fail.
282282
**
283283
** The TryEnterCriticalSection() interface is only available on WinNT.
284284
** And some windows compilers complain if you try to use it without
285285
** first doing some #defines that prevent SQLite from building on Win98.
286286
** For that reason, we will omit this optimization for now. See
287287
** ticket #2685.
288288
*/
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
291292
p->owner = tid;
292293
p->nRef++;
294+
#endif
293295
rc = SQLITE_OK;
294296
}
295297
#else
296298
UNUSED_PARAMETER(p);
297299
#endif
298300
#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)));
301304
}
302305
#endif
303306
return rc;
@@ -310,8 +313,11 @@ static int winMutexTry(sqlite3_mutex *p){
310313
** is not currently allocated. SQLite will never do either.
311314
*/
312315
static void winMutexLeave(sqlite3_mutex *p){
313-
#ifndef NDEBUG
316+
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
314317
DWORD tid = GetCurrentThreadId();
318+
#endif
319+
assert( p );
320+
#ifdef SQLITE_DEBUG
315321
assert( p->nRef>0 );
316322
assert( p->owner==tid );
317323
p->nRef--;
@@ -321,7 +327,8 @@ static void winMutexLeave(sqlite3_mutex *p){
321327
LeaveCriticalSection(&p->mutex);
322328
#ifdef SQLITE_DEBUG
323329
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));
325332
}
326333
#endif
327334
}
@@ -343,7 +350,7 @@ sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
343350
0
344351
#endif
345352
};
346-
347353
return &sMutex;
348354
}
355+
349356
#endif /* SQLITE_MUTEX_W32 */

0 commit comments

Comments
 (0)