1437b9013Sdrh /*
2437b9013Sdrh ** 2007 August 14
3437b9013Sdrh **
4437b9013Sdrh ** The author disclaims copyright to this source code. In place of
5437b9013Sdrh ** a legal notice, here is a blessing:
6437b9013Sdrh **
7437b9013Sdrh ** May you do good and not evil.
8437b9013Sdrh ** May you find forgiveness for yourself and forgive others.
9437b9013Sdrh ** May you share freely, never taking more than you give.
10437b9013Sdrh **
11437b9013Sdrh *************************************************************************
120174ffa9Smistachkin ** This file contains the C functions that implement mutexes for Win32.
13437b9013Sdrh */
14437b9013Sdrh #include "sqliteInt.h"
15437b9013Sdrh
160f710546Smistachkin #if SQLITE_OS_WIN
170f710546Smistachkin /*
180174ffa9Smistachkin ** Include code that is common to all os_*.c files
190174ffa9Smistachkin */
200174ffa9Smistachkin #include "os_common.h"
210174ffa9Smistachkin
220174ffa9Smistachkin /*
230f710546Smistachkin ** Include the header file for the Windows VFS.
240f710546Smistachkin */
250f710546Smistachkin #include "os_win.h"
260f710546Smistachkin #endif
270f710546Smistachkin
28437b9013Sdrh /*
29437b9013Sdrh ** The code in this file is only used if we are compiling multithreaded
300174ffa9Smistachkin ** on a Win32 system.
31437b9013Sdrh */
32c7ce76afSdrh #ifdef SQLITE_MUTEX_W32
33437b9013Sdrh
34437b9013Sdrh /*
35437b9013Sdrh ** Each recursive mutex is an instance of the following structure.
36437b9013Sdrh */
37437b9013Sdrh struct sqlite3_mutex {
38437b9013Sdrh CRITICAL_SECTION mutex; /* Mutex controlling the lock */
39437b9013Sdrh int id; /* Mutex type */
401f4222f8Sshaneh #ifdef SQLITE_DEBUG
4172339a3eSdrh volatile int nRef; /* Number of enterances */
4272339a3eSdrh volatile DWORD owner; /* Thread holding this mutex */
43091881bbSmistachkin volatile LONG trace; /* True to trace changes */
441f4222f8Sshaneh #endif
45437b9013Sdrh };
46a418980bSdrh
47d42d0bedSdrh /*
480174ffa9Smistachkin ** These are the initializer values used when declaring a "static" mutex
490174ffa9Smistachkin ** on Win32. It should be noted that all mutexes require initialization
500174ffa9Smistachkin ** on the Win32 platform.
51d42d0bedSdrh */
520174ffa9Smistachkin #define SQLITE_W32_MUTEX_INITIALIZER { 0 }
530174ffa9Smistachkin
540174ffa9Smistachkin #ifdef SQLITE_DEBUG
55091881bbSmistachkin #define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \
560174ffa9Smistachkin 0L, (DWORD)0, 0 }
57d42d0bedSdrh #else
58091881bbSmistachkin #define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id }
59d42d0bedSdrh #endif
60d42d0bedSdrh
61a418980bSdrh #ifdef SQLITE_DEBUG
626d2ab0e4Sdanielk1977 /*
636d2ab0e4Sdanielk1977 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
646d2ab0e4Sdanielk1977 ** intended for use only inside assert() statements.
656d2ab0e4Sdanielk1977 */
winMutexHeld(sqlite3_mutex * p)666d2ab0e4Sdanielk1977 static int winMutexHeld(sqlite3_mutex *p){
676d2ab0e4Sdanielk1977 return p->nRef!=0 && p->owner==GetCurrentThreadId();
686d2ab0e4Sdanielk1977 }
690174ffa9Smistachkin
winMutexNotheld2(sqlite3_mutex * p,DWORD tid)701f4222f8Sshaneh static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
711f4222f8Sshaneh return p->nRef==0 || p->owner!=tid;
721f4222f8Sshaneh }
730174ffa9Smistachkin
winMutexNotheld(sqlite3_mutex * p)746d2ab0e4Sdanielk1977 static int winMutexNotheld(sqlite3_mutex *p){
751f4222f8Sshaneh DWORD tid = GetCurrentThreadId();
761f4222f8Sshaneh return winMutexNotheld2(p, tid);
776d2ab0e4Sdanielk1977 }
78a418980bSdrh #endif
796d2ab0e4Sdanielk1977
80df6a81c8Sdrh /*
81539482b7Sdrh ** Try to provide a memory barrier operation, needed for initialization
82539482b7Sdrh ** and also for the xShmBarrier method of the VFS in cases when SQLite is
83539482b7Sdrh ** compiled without mutexes (SQLITE_THREADSAFE=0).
846081c1dbSdrh */
sqlite3MemoryBarrier(void)856081c1dbSdrh void sqlite3MemoryBarrier(void){
862d64034bSdrh #if defined(SQLITE_MEMORY_BARRIER)
872d64034bSdrh SQLITE_MEMORY_BARRIER;
882d64034bSdrh #elif defined(__GNUC__)
892d64034bSdrh __sync_synchronize();
9030a5831cSdrh #elif MSVC_VERSION>=1300
918d9837acSmistachkin _ReadWriteBarrier();
928d9837acSmistachkin #elif defined(MemoryBarrier)
936081c1dbSdrh MemoryBarrier();
942d64034bSdrh #endif
956081c1dbSdrh }
966081c1dbSdrh
976081c1dbSdrh /*
9840257ffdSdrh ** Initialize and deinitialize the mutex subsystem.
9940257ffdSdrh */
100d42d0bedSdrh static sqlite3_mutex winMutex_staticMutexes[] = {
101091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(2),
102091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(3),
103091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(4),
104091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(5),
105091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(6),
106091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(7),
107091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(8),
108091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(9),
109091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(10),
110091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(11),
111091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(12),
112091881bbSmistachkin SQLITE3_MUTEX_INITIALIZER(13)
1131f4222f8Sshaneh };
1140174ffa9Smistachkin
11561b82d6aSshane static int winMutex_isInit = 0;
116202cb641Smistachkin static int winMutex_isNt = -1; /* <0 means "need to query" */
1170174ffa9Smistachkin
1180174ffa9Smistachkin /* As the winMutexInit() and winMutexEnd() functions are called as part
1190174ffa9Smistachkin ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
1200174ffa9Smistachkin ** "interlocked" magic used here is probably not strictly necessary.
12161b82d6aSshane */
122ce64d610Smistachkin static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
12361b82d6aSshane
1240174ffa9Smistachkin int sqlite3_win32_is_nt(void); /* os_win.c */
1259721c21cSmistachkin void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
1269721c21cSmistachkin
winMutexInit(void)12761b82d6aSshane static int winMutexInit(void){
12861b82d6aSshane /* The first to increment to 1 does actual initialization */
1291987c8d4Sshane if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
13061b82d6aSshane int i;
1319ac06509Sdrh for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
132cf3d7a4eSdrh #if SQLITE_OS_WINRT
133cf3d7a4eSdrh InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0);
134cf3d7a4eSdrh #else
13561b82d6aSshane InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
136cf3d7a4eSdrh #endif
13761b82d6aSshane }
13861b82d6aSshane winMutex_isInit = 1;
13961b82d6aSshane }else{
1400174ffa9Smistachkin /* Another thread is (in the process of) initializing the static
1410174ffa9Smistachkin ** mutexes */
14261b82d6aSshane while( !winMutex_isInit ){
143f4f327ceSmistachkin sqlite3_win32_sleep(1);
14461b82d6aSshane }
14561b82d6aSshane }
14661b82d6aSshane return SQLITE_OK;
14761b82d6aSshane }
14861b82d6aSshane
winMutexEnd(void)14961b82d6aSshane static int winMutexEnd(void){
15061b82d6aSshane /* The first to decrement to 0 does actual shutdown
15161b82d6aSshane ** (which should be the last to shutdown.) */
1521987c8d4Sshane if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
15361b82d6aSshane if( winMutex_isInit==1 ){
15461b82d6aSshane int i;
1559ac06509Sdrh for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
15661b82d6aSshane DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
15761b82d6aSshane }
15861b82d6aSshane winMutex_isInit = 0;
15961b82d6aSshane }
16061b82d6aSshane }
16161b82d6aSshane return SQLITE_OK;
16261b82d6aSshane }
16340257ffdSdrh
16440257ffdSdrh /*
165437b9013Sdrh ** The sqlite3_mutex_alloc() routine allocates a new
166437b9013Sdrh ** mutex and returns a pointer to it. If it returns NULL
167437b9013Sdrh ** that means that a mutex could not be allocated. SQLite
168437b9013Sdrh ** will unwind its stack and return an error. The argument
169437b9013Sdrh ** to sqlite3_mutex_alloc() is one of these integer constants:
170437b9013Sdrh **
171437b9013Sdrh ** <ul>
1727c7c311dSshane ** <li> SQLITE_MUTEX_FAST
1737c7c311dSshane ** <li> SQLITE_MUTEX_RECURSIVE
174*ccb2113aSdrh ** <li> SQLITE_MUTEX_STATIC_MAIN
1757c7c311dSshane ** <li> SQLITE_MUTEX_STATIC_MEM
176d42d0bedSdrh ** <li> SQLITE_MUTEX_STATIC_OPEN
1777c7c311dSshane ** <li> SQLITE_MUTEX_STATIC_PRNG
1787c7c311dSshane ** <li> SQLITE_MUTEX_STATIC_LRU
1796d4fb833Sdan ** <li> SQLITE_MUTEX_STATIC_PMEM
180d42d0bedSdrh ** <li> SQLITE_MUTEX_STATIC_APP1
181d42d0bedSdrh ** <li> SQLITE_MUTEX_STATIC_APP2
182d42d0bedSdrh ** <li> SQLITE_MUTEX_STATIC_APP3
18393de6538Smistachkin ** <li> SQLITE_MUTEX_STATIC_VFS1
18493de6538Smistachkin ** <li> SQLITE_MUTEX_STATIC_VFS2
18593de6538Smistachkin ** <li> SQLITE_MUTEX_STATIC_VFS3
186437b9013Sdrh ** </ul>
187437b9013Sdrh **
188437b9013Sdrh ** The first two constants cause sqlite3_mutex_alloc() to create
189437b9013Sdrh ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
190437b9013Sdrh ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
191437b9013Sdrh ** The mutex implementation does not need to make a distinction
192437b9013Sdrh ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
193437b9013Sdrh ** not want to. But SQLite will only request a recursive mutex in
194437b9013Sdrh ** cases where it really needs one. If a faster non-recursive mutex
195437b9013Sdrh ** implementation is available on the host platform, the mutex subsystem
196437b9013Sdrh ** might return such a mutex in response to SQLITE_MUTEX_FAST.
197437b9013Sdrh **
198437b9013Sdrh ** The other allowed parameters to sqlite3_mutex_alloc() each return
1997c7c311dSshane ** a pointer to a static preexisting mutex. Six static mutexes are
200437b9013Sdrh ** used by the current version of SQLite. Future versions of SQLite
201437b9013Sdrh ** may add additional static mutexes. Static mutexes are for internal
202437b9013Sdrh ** use by SQLite only. Applications that use SQLite mutexes should
203437b9013Sdrh ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
204437b9013Sdrh ** SQLITE_MUTEX_RECURSIVE.
205437b9013Sdrh **
206437b9013Sdrh ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
207437b9013Sdrh ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
208437b9013Sdrh ** returns a different mutex on every call. But for the static
209437b9013Sdrh ** mutex types, the same mutex is returned on every call that has
210437b9013Sdrh ** the same type number.
211437b9013Sdrh */
winMutexAlloc(int iType)2126d2ab0e4Sdanielk1977 static sqlite3_mutex *winMutexAlloc(int iType){
213437b9013Sdrh sqlite3_mutex *p;
214437b9013Sdrh
215437b9013Sdrh switch( iType ){
216437b9013Sdrh case SQLITE_MUTEX_FAST:
217437b9013Sdrh case SQLITE_MUTEX_RECURSIVE: {
218437b9013Sdrh p = sqlite3MallocZero( sizeof(*p) );
219437b9013Sdrh if( p ){
220437b9013Sdrh p->id = iType;
221cbb3f33cSdrh #ifdef SQLITE_DEBUG
2220174ffa9Smistachkin #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
2230174ffa9Smistachkin p->trace = 1;
2240174ffa9Smistachkin #endif
22572339a3eSdrh #endif
226df562d55Smistachkin #if SQLITE_OS_WINRT
227df562d55Smistachkin InitializeCriticalSectionEx(&p->mutex, 0, 0);
228df562d55Smistachkin #else
229437b9013Sdrh InitializeCriticalSection(&p->mutex);
230df562d55Smistachkin #endif
231437b9013Sdrh }
232437b9013Sdrh break;
233437b9013Sdrh }
234437b9013Sdrh default: {
235cd54bab6Smistachkin #ifdef SQLITE_ENABLE_API_ARMOR
236cd54bab6Smistachkin if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
237cd54bab6Smistachkin (void)SQLITE_MISUSE_BKPT;
238cd54bab6Smistachkin return 0;
239cd54bab6Smistachkin }
240cd54bab6Smistachkin #endif
24161b82d6aSshane p = &winMutex_staticMutexes[iType-2];
242cbb3f33cSdrh #ifdef SQLITE_DEBUG
2430174ffa9Smistachkin #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
244091881bbSmistachkin InterlockedCompareExchange(&p->trace, 1, 0);
2450174ffa9Smistachkin #endif
24672339a3eSdrh #endif
247437b9013Sdrh break;
248437b9013Sdrh }
249437b9013Sdrh }
250091881bbSmistachkin assert( p==0 || p->id==iType );
251437b9013Sdrh return p;
252437b9013Sdrh }
253437b9013Sdrh
254437b9013Sdrh
255437b9013Sdrh /*
256437b9013Sdrh ** This routine deallocates a previously
257437b9013Sdrh ** allocated mutex. SQLite is careful to deallocate every
258437b9013Sdrh ** mutex that it allocates.
259437b9013Sdrh */
winMutexFree(sqlite3_mutex * p)2606d2ab0e4Sdanielk1977 static void winMutexFree(sqlite3_mutex *p){
261437b9013Sdrh assert( p );
26284612fecSdan assert( p->nRef==0 && p->owner==0 );
26396c707a3Sdrh if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
264437b9013Sdrh DeleteCriticalSection(&p->mutex);
265437b9013Sdrh sqlite3_free(p);
26696c707a3Sdrh }else{
26796c707a3Sdrh #ifdef SQLITE_ENABLE_API_ARMOR
26896c707a3Sdrh (void)SQLITE_MISUSE_BKPT;
26996c707a3Sdrh #endif
27096c707a3Sdrh }
271437b9013Sdrh }
272437b9013Sdrh
273437b9013Sdrh /*
274437b9013Sdrh ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
275437b9013Sdrh ** to enter a mutex. If another thread is already within the mutex,
276437b9013Sdrh ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
277437b9013Sdrh ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
278437b9013Sdrh ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
279437b9013Sdrh ** be entered multiple times by the same thread. In such cases the,
280437b9013Sdrh ** mutex must be exited an equal number of times before another thread
281437b9013Sdrh ** can enter. If the same thread tries to enter any other kind of mutex
282437b9013Sdrh ** more than once, the behavior is undefined.
283437b9013Sdrh */
winMutexEnter(sqlite3_mutex * p)2846d2ab0e4Sdanielk1977 static void winMutexEnter(sqlite3_mutex *p){
2850174ffa9Smistachkin #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
286d42d0bedSdrh DWORD tid = GetCurrentThreadId();
2870174ffa9Smistachkin #endif
2880174ffa9Smistachkin #ifdef SQLITE_DEBUG
2890174ffa9Smistachkin assert( p );
2901f4222f8Sshaneh assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
2910174ffa9Smistachkin #else
2920174ffa9Smistachkin assert( p );
29372339a3eSdrh #endif
294d42d0bedSdrh assert( winMutex_isInit==1 );
295437b9013Sdrh EnterCriticalSection(&p->mutex);
29672339a3eSdrh #ifdef SQLITE_DEBUG
29784612fecSdan assert( p->nRef>0 || p->owner==0 );
2981f4222f8Sshaneh p->owner = tid;
299437b9013Sdrh p->nRef++;
3001f4222f8Sshaneh if( p->trace ){
3010d5b3b76Smistachkin OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
3020d5b3b76Smistachkin tid, p->id, p, p->trace, p->nRef));
3031f4222f8Sshaneh }
3041f4222f8Sshaneh #endif
305437b9013Sdrh }
3060174ffa9Smistachkin
winMutexTry(sqlite3_mutex * p)3076d2ab0e4Sdanielk1977 static int winMutexTry(sqlite3_mutex *p){
3080174ffa9Smistachkin #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
3091f4222f8Sshaneh DWORD tid = GetCurrentThreadId();
3101da207e6Sshaneh #endif
31186505068Sdrh int rc = SQLITE_BUSY;
3120174ffa9Smistachkin assert( p );
3131f4222f8Sshaneh assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
31486505068Sdrh /*
31586505068Sdrh ** The sqlite3_mutex_try() routine is very rarely used, and when it
31686505068Sdrh ** is used it is merely an optimization. So it is OK for it to always
31786505068Sdrh ** fail.
31886505068Sdrh **
31986505068Sdrh ** The TryEnterCriticalSection() interface is only available on WinNT.
32086505068Sdrh ** And some windows compilers complain if you try to use it without
32186505068Sdrh ** first doing some #defines that prevent SQLite from building on Win98.
32286505068Sdrh ** For that reason, we will omit this optimization for now. See
32386505068Sdrh ** ticket #2685.
32486505068Sdrh */
3250174ffa9Smistachkin #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0400
326d42d0bedSdrh assert( winMutex_isInit==1 );
327202cb641Smistachkin assert( winMutex_isNt>=-1 && winMutex_isNt<=1 );
328202cb641Smistachkin if( winMutex_isNt<0 ){
329202cb641Smistachkin winMutex_isNt = sqlite3_win32_is_nt();
330202cb641Smistachkin }
331202cb641Smistachkin assert( winMutex_isNt==0 || winMutex_isNt==1 );
332202cb641Smistachkin if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){
3330174ffa9Smistachkin #ifdef SQLITE_DEBUG
3341f4222f8Sshaneh p->owner = tid;
335437b9013Sdrh p->nRef++;
3360174ffa9Smistachkin #endif
337437b9013Sdrh rc = SQLITE_OK;
338437b9013Sdrh }
3391a38964bSshane #else
3401a38964bSshane UNUSED_PARAMETER(p);
34186505068Sdrh #endif
3421f4222f8Sshaneh #ifdef SQLITE_DEBUG
3430174ffa9Smistachkin if( p->trace ){
3440d5b3b76Smistachkin OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
3450d5b3b76Smistachkin tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
3461f4222f8Sshaneh }
3471f4222f8Sshaneh #endif
348437b9013Sdrh return rc;
349437b9013Sdrh }
350437b9013Sdrh
351437b9013Sdrh /*
352437b9013Sdrh ** The sqlite3_mutex_leave() routine exits a mutex that was
353437b9013Sdrh ** previously entered by the same thread. The behavior
354437b9013Sdrh ** is undefined if the mutex is not currently entered or
355437b9013Sdrh ** is not currently allocated. SQLite will never do either.
356437b9013Sdrh */
winMutexLeave(sqlite3_mutex * p)3576d2ab0e4Sdanielk1977 static void winMutexLeave(sqlite3_mutex *p){
3580174ffa9Smistachkin #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
3591f4222f8Sshaneh DWORD tid = GetCurrentThreadId();
3600174ffa9Smistachkin #endif
3610174ffa9Smistachkin assert( p );
3620174ffa9Smistachkin #ifdef SQLITE_DEBUG
363437b9013Sdrh assert( p->nRef>0 );
3641f4222f8Sshaneh assert( p->owner==tid );
365437b9013Sdrh p->nRef--;
36684612fecSdan if( p->nRef==0 ) p->owner = 0;
367437b9013Sdrh assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
36872339a3eSdrh #endif
369d42d0bedSdrh assert( winMutex_isInit==1 );
370437b9013Sdrh LeaveCriticalSection(&p->mutex);
3711f4222f8Sshaneh #ifdef SQLITE_DEBUG
3721f4222f8Sshaneh if( p->trace ){
3730d5b3b76Smistachkin OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
3740d5b3b76Smistachkin tid, p->id, p, p->trace, p->nRef));
3751f4222f8Sshaneh }
3761f4222f8Sshaneh #endif
377437b9013Sdrh }
378437b9013Sdrh
sqlite3DefaultMutex(void)379558814f8Sdan sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
380558814f8Sdan static const sqlite3_mutex_methods sMutex = {
3816d2ab0e4Sdanielk1977 winMutexInit,
3824a9d1f66Sdanielk1977 winMutexEnd,
3836d2ab0e4Sdanielk1977 winMutexAlloc,
3846d2ab0e4Sdanielk1977 winMutexFree,
3856d2ab0e4Sdanielk1977 winMutexEnter,
3866d2ab0e4Sdanielk1977 winMutexTry,
3876d2ab0e4Sdanielk1977 winMutexLeave,
388a418980bSdrh #ifdef SQLITE_DEBUG
3896d2ab0e4Sdanielk1977 winMutexHeld,
3906d2ab0e4Sdanielk1977 winMutexNotheld
3911875f7a3Sdrh #else
3921875f7a3Sdrh 0,
3931875f7a3Sdrh 0
394a418980bSdrh #endif
3956d2ab0e4Sdanielk1977 };
3966d2ab0e4Sdanielk1977 return &sMutex;
397437b9013Sdrh }
3980174ffa9Smistachkin
399c7ce76afSdrh #endif /* SQLITE_MUTEX_W32 */
400