aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/unix/sqlite-3.5.1/src/mutex_w32.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/src/mutex_w32.c')
-rw-r--r--libraries/sqlite/unix/sqlite-3.5.1/src/mutex_w32.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/src/mutex_w32.c b/libraries/sqlite/unix/sqlite-3.5.1/src/mutex_w32.c
new file mode 100644
index 0000000..ee5a408
--- /dev/null
+++ b/libraries/sqlite/unix/sqlite-3.5.1/src/mutex_w32.c
@@ -0,0 +1,208 @@
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** $Id: mutex_w32.c,v 1.4 2007/09/05 14:30:42 drh Exp $
15*/
16#include "sqliteInt.h"
17
18/*
19** The code in this file is only used if we are compiling multithreaded
20** on a win32 system.
21*/
22#ifdef SQLITE_MUTEX_W32
23
24/*
25** Each recursive mutex is an instance of the following structure.
26*/
27struct sqlite3_mutex {
28 CRITICAL_SECTION mutex; /* Mutex controlling the lock */
29 int id; /* Mutex type */
30 int nRef; /* Number of enterances */
31 DWORD owner; /* Thread holding this mutex */
32};
33
34/*
35** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
36** or WinCE. Return false (zero) for Win95, Win98, or WinME.
37**
38** Here is an interesting observation: Win95, Win98, and WinME lack
39** the LockFileEx() API. But we can still statically link against that
40** API as long as we don't call it win running Win95/98/ME. A call to
41** this routine is used to determine if the host is Win95/98/ME or
42** WinNT/2K/XP so that we will know whether or not we can safely call
43** the LockFileEx() API.
44*/
45#if OS_WINCE
46# define mutexIsNT() (1)
47#else
48 static int mutexIsNT(void){
49 static int osType = 0;
50 if( osType==0 ){
51 OSVERSIONINFO sInfo;
52 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
53 GetVersionEx(&sInfo);
54 osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
55 }
56 return osType==2;
57 }
58#endif /* OS_WINCE */
59
60
61/*
62** The sqlite3_mutex_alloc() routine allocates a new
63** mutex and returns a pointer to it. If it returns NULL
64** that means that a mutex could not be allocated. SQLite
65** will unwind its stack and return an error. The argument
66** to sqlite3_mutex_alloc() is one of these integer constants:
67**
68** <ul>
69** <li> SQLITE_MUTEX_FAST 0
70** <li> SQLITE_MUTEX_RECURSIVE 1
71** <li> SQLITE_MUTEX_STATIC_MASTER 2
72** <li> SQLITE_MUTEX_STATIC_MEM 3
73** <li> SQLITE_MUTEX_STATIC_PRNG 4
74** </ul>
75**
76** The first two constants cause sqlite3_mutex_alloc() to create
77** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
78** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
79** The mutex implementation does not need to make a distinction
80** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
81** not want to. But SQLite will only request a recursive mutex in
82** cases where it really needs one. If a faster non-recursive mutex
83** implementation is available on the host platform, the mutex subsystem
84** might return such a mutex in response to SQLITE_MUTEX_FAST.
85**
86** The other allowed parameters to sqlite3_mutex_alloc() each return
87** a pointer to a static preexisting mutex. Three static mutexes are
88** used by the current version of SQLite. Future versions of SQLite
89** may add additional static mutexes. Static mutexes are for internal
90** use by SQLite only. Applications that use SQLite mutexes should
91** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
92** SQLITE_MUTEX_RECURSIVE.
93**
94** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
95** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
96** returns a different mutex on every call. But for the static
97** mutex types, the same mutex is returned on every call that has
98** the same type number.
99*/
100sqlite3_mutex *sqlite3_mutex_alloc(int iType){
101 sqlite3_mutex *p;
102
103 switch( iType ){
104 case SQLITE_MUTEX_FAST:
105 case SQLITE_MUTEX_RECURSIVE: {
106 p = sqlite3MallocZero( sizeof(*p) );
107 if( p ){
108 p->id = iType;
109 InitializeCriticalSection(&p->mutex);
110 }
111 break;
112 }
113 default: {
114 static sqlite3_mutex staticMutexes[5];
115 static int isInit = 0;
116 while( !isInit ){
117 static long lock = 0;
118 if( InterlockedIncrement(&lock)==1 ){
119 int i;
120 for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
121 InitializeCriticalSection(&staticMutexes[i].mutex);
122 }
123 isInit = 1;
124 }else{
125 Sleep(1);
126 }
127 }
128 assert( iType-2 >= 0 );
129 assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
130 p = &staticMutexes[iType-2];
131 p->id = iType;
132 break;
133 }
134 }
135 return p;
136}
137
138
139/*
140** This routine deallocates a previously
141** allocated mutex. SQLite is careful to deallocate every
142** mutex that it allocates.
143*/
144void sqlite3_mutex_free(sqlite3_mutex *p){
145 assert( p );
146 assert( p->nRef==0 );
147 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
148 DeleteCriticalSection(&p->mutex);
149 sqlite3_free(p);
150}
151
152/*
153** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
154** to enter a mutex. If another thread is already within the mutex,
155** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
156** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
157** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
158** be entered multiple times by the same thread. In such cases the,
159** mutex must be exited an equal number of times before another thread
160** can enter. If the same thread tries to enter any other kind of mutex
161** more than once, the behavior is undefined.
162*/
163void sqlite3_mutex_enter(sqlite3_mutex *p){
164 assert( p );
165 assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
166 EnterCriticalSection(&p->mutex);
167 p->owner = GetCurrentThreadId();
168 p->nRef++;
169}
170int sqlite3_mutex_try(sqlite3_mutex *p){
171 int rc;
172 assert( p );
173 assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
174 if( mutexIsNT() && TryEnterCriticalSection(&p->mutex) ){
175 p->owner = GetCurrentThreadId();
176 p->nRef++;
177 rc = SQLITE_OK;
178 }else{
179 rc = SQLITE_BUSY;
180 }
181 return rc;
182}
183
184/*
185** The sqlite3_mutex_leave() routine exits a mutex that was
186** previously entered by the same thread. The behavior
187** is undefined if the mutex is not currently entered or
188** is not currently allocated. SQLite will never do either.
189*/
190void sqlite3_mutex_leave(sqlite3_mutex *p){
191 assert( p->nRef>0 );
192 assert( p->owner==GetCurrentThreadId() );
193 p->nRef--;
194 assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
195 LeaveCriticalSection(&p->mutex);
196}
197
198/*
199** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
200** intended for use only inside assert() statements.
201*/
202int sqlite3_mutex_held(sqlite3_mutex *p){
203 return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId());
204}
205int sqlite3_mutex_notheld(sqlite3_mutex *p){
206 return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId();
207}
208#endif /* SQLITE_MUTEX_W32 */