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/*
17** The code in this file is only used if we are compiling multithreaded
18** on a win32 system.
19*/
20#ifdef SQLITE_MUTEX_W32
21
22/*
23** Each recursive mutex is an instance of the following structure.
24*/
25struct sqlite3_mutex {
26  CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
27  int id;                    /* Mutex type */
28#ifdef SQLITE_DEBUG
29  volatile int nRef;         /* Number of enterances */
30  volatile DWORD owner;      /* Thread holding this mutex */
31  int trace;                 /* True to trace changes */
32#endif
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
40
41/*
42** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
43** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
44**
45** Here is an interesting observation:  Win95, Win98, and WinME lack
46** the LockFileEx() API.  But we can still statically link against that
47** API as long as we don't call it win running Win95/98/ME.  A call to
48** this routine is used to determine if the host is Win95/98/ME or
49** WinNT/2K/XP so that we will know whether or not we can safely call
50** the LockFileEx() API.
51**
52** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
53** which is only available if your application was compiled with
54** _WIN32_WINNT defined to a value >= 0x0400.  Currently, the only
55** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef
56** this out as well.
57*/
58#if 0
59#if SQLITE_OS_WINCE
60# define mutexIsNT()  (1)
61#else
62  static int mutexIsNT(void){
63    static int osType = 0;
64    if( osType==0 ){
65      OSVERSIONINFO sInfo;
66      sInfo.dwOSVersionInfoSize = sizeof(sInfo);
67      GetVersionEx(&sInfo);
68      osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
69    }
70    return osType==2;
71  }
72#endif /* SQLITE_OS_WINCE */
73#endif
74
75#ifdef SQLITE_DEBUG
76/*
77** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
78** intended for use only inside assert() statements.
79*/
80static int winMutexHeld(sqlite3_mutex *p){
81  return p->nRef!=0 && p->owner==GetCurrentThreadId();
82}
83static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){
84  return p->nRef==0 || p->owner!=tid;
85}
86static int winMutexNotheld(sqlite3_mutex *p){
87  DWORD tid = GetCurrentThreadId();
88  return winMutexNotheld2(p, tid);
89}
90#endif
91
92
93/*
94** Initialize and deinitialize the mutex subsystem.
95*/
96static 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};
104static int winMutex_isInit = 0;
105/* As winMutexInit() and winMutexEnd() are called as part
106** of the sqlite3_initialize and sqlite3_shutdown()
107** processing, the "interlocked" magic is probably not
108** strictly necessary.
109*/
110static long winMutex_lock = 0;
111
112static int winMutexInit(void){
113  /* The first to increment to 1 does actual initialization */
114  if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
115    int i;
116    for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
117      InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
118    }
119    winMutex_isInit = 1;
120  }else{
121    /* Someone else is in the process of initing the static mutexes */
122    while( !winMutex_isInit ){
123      Sleep(1);
124    }
125  }
126  return SQLITE_OK;
127}
128
129static int winMutexEnd(void){
130  /* The first to decrement to 0 does actual shutdown
131  ** (which should be the last to shutdown.) */
132  if( InterlockedCompareExchange(&winMutex_lock, 0, 1)==1 ){
133    if( winMutex_isInit==1 ){
134      int i;
135      for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
136        DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
137      }
138      winMutex_isInit = 0;
139    }
140  }
141  return SQLITE_OK;
142}
143
144/*
145** The sqlite3_mutex_alloc() routine allocates a new
146** mutex and returns a pointer to it.  If it returns NULL
147** that means that a mutex could not be allocated.  SQLite
148** will unwind its stack and return an error.  The argument
149** to sqlite3_mutex_alloc() is one of these integer constants:
150**
151** <ul>
152** <li>  SQLITE_MUTEX_FAST
153** <li>  SQLITE_MUTEX_RECURSIVE
154** <li>  SQLITE_MUTEX_STATIC_MASTER
155** <li>  SQLITE_MUTEX_STATIC_MEM
156** <li>  SQLITE_MUTEX_STATIC_MEM2
157** <li>  SQLITE_MUTEX_STATIC_PRNG
158** <li>  SQLITE_MUTEX_STATIC_LRU
159** <li>  SQLITE_MUTEX_STATIC_PMEM
160** </ul>
161**
162** The first two constants cause sqlite3_mutex_alloc() to create
163** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
164** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
165** The mutex implementation does not need to make a distinction
166** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
167** not want to.  But SQLite will only request a recursive mutex in
168** cases where it really needs one.  If a faster non-recursive mutex
169** implementation is available on the host platform, the mutex subsystem
170** might return such a mutex in response to SQLITE_MUTEX_FAST.
171**
172** The other allowed parameters to sqlite3_mutex_alloc() each return
173** a pointer to a static preexisting mutex.  Six static mutexes are
174** used by the current version of SQLite.  Future versions of SQLite
175** may add additional static mutexes.  Static mutexes are for internal
176** use by SQLite only.  Applications that use SQLite mutexes should
177** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
178** SQLITE_MUTEX_RECURSIVE.
179**
180** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
181** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
182** returns a different mutex on every call.  But for the static
183** mutex types, the same mutex is returned on every call that has
184** the same type number.
185*/
186static sqlite3_mutex *winMutexAlloc(int iType){
187  sqlite3_mutex *p;
188
189  switch( iType ){
190    case SQLITE_MUTEX_FAST:
191    case SQLITE_MUTEX_RECURSIVE: {
192      p = sqlite3MallocZero( sizeof(*p) );
193      if( p ){
194#ifdef SQLITE_DEBUG
195        p->id = iType;
196#endif
197        InitializeCriticalSection(&p->mutex);
198      }
199      break;
200    }
201    default: {
202      assert( winMutex_isInit==1 );
203      assert( iType-2 >= 0 );
204      assert( iType-2 < ArraySize(winMutex_staticMutexes) );
205      p = &winMutex_staticMutexes[iType-2];
206#ifdef SQLITE_DEBUG
207      p->id = iType;
208#endif
209      break;
210    }
211  }
212  return p;
213}
214
215
216/*
217** This routine deallocates a previously
218** allocated mutex.  SQLite is careful to deallocate every
219** mutex that it allocates.
220*/
221static void winMutexFree(sqlite3_mutex *p){
222  assert( p );
223  assert( p->nRef==0 && p->owner==0 );
224  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
225  DeleteCriticalSection(&p->mutex);
226  sqlite3_free(p);
227}
228
229/*
230** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
231** to enter a mutex.  If another thread is already within the mutex,
232** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
233** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
234** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
235** be entered multiple times by the same thread.  In such cases the,
236** mutex must be exited an equal number of times before another thread
237** can enter.  If the same thread tries to enter any other kind of mutex
238** more than once, the behavior is undefined.
239*/
240static void winMutexEnter(sqlite3_mutex *p){
241#ifdef SQLITE_DEBUG
242  DWORD tid = GetCurrentThreadId();
243  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
244#endif
245  EnterCriticalSection(&p->mutex);
246#ifdef SQLITE_DEBUG
247  assert( p->nRef>0 || p->owner==0 );
248  p->owner = tid;
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
254}
255static int winMutexTry(sqlite3_mutex *p){
256#ifndef NDEBUG
257  DWORD tid = GetCurrentThreadId();
258#endif
259  int rc = SQLITE_BUSY;
260  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) );
261  /*
262  ** The sqlite3_mutex_try() routine is very rarely used, and when it
263  ** is used it is merely an optimization.  So it is OK for it to always
264  ** fail.
265  **
266  ** The TryEnterCriticalSection() interface is only available on WinNT.
267  ** And some windows compilers complain if you try to use it without
268  ** first doing some #defines that prevent SQLite from building on Win98.
269  ** For that reason, we will omit this optimization for now.  See
270  ** ticket #2685.
271  */
272#if 0
273  if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
274    p->owner = tid;
275    p->nRef++;
276    rc = SQLITE_OK;
277  }
278#else
279  UNUSED_PARAMETER(p);
280#endif
281#ifdef SQLITE_DEBUG
282  if( rc==SQLITE_OK && p->trace ){
283    printf("try mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
284  }
285#endif
286  return rc;
287}
288
289/*
290** The sqlite3_mutex_leave() routine exits a mutex that was
291** previously entered by the same thread.  The behavior
292** is undefined if the mutex is not currently entered or
293** is not currently allocated.  SQLite will never do either.
294*/
295static void winMutexLeave(sqlite3_mutex *p){
296#ifndef NDEBUG
297  DWORD tid = GetCurrentThreadId();
298  assert( p->nRef>0 );
299  assert( p->owner==tid );
300  p->nRef--;
301  if( p->nRef==0 ) p->owner = 0;
302  assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
303#endif
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
310}
311
312sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
313  static const sqlite3_mutex_methods sMutex = {
314    winMutexInit,
315    winMutexEnd,
316    winMutexAlloc,
317    winMutexFree,
318    winMutexEnter,
319    winMutexTry,
320    winMutexLeave,
321#ifdef SQLITE_DEBUG
322    winMutexHeld,
323    winMutexNotheld
324#else
325    0,
326    0
327#endif
328  };
329
330  return &sMutex;
331}
332#endif /* SQLITE_MUTEX_W32 */
333