diff options
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.c | 208 |
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 | */ | ||
27 | struct 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 | */ | ||
100 | sqlite3_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 | */ | ||
144 | void 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 | */ | ||
163 | void 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 | } | ||
170 | int 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 | */ | ||
190 | void 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 | */ | ||
202 | int sqlite3_mutex_held(sqlite3_mutex *p){ | ||
203 | return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId()); | ||
204 | } | ||
205 | int sqlite3_mutex_notheld(sqlite3_mutex *p){ | ||
206 | return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId(); | ||
207 | } | ||
208 | #endif /* SQLITE_MUTEX_W32 */ | ||