OLD | NEW |
1 /* | 1 /* |
2 ** 2007 August 14 | 2 ** 2007 August 14 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 return p->nRef==0 || p->owner!=tid; | 71 return p->nRef==0 || p->owner!=tid; |
72 } | 72 } |
73 | 73 |
74 static int winMutexNotheld(sqlite3_mutex *p){ | 74 static int winMutexNotheld(sqlite3_mutex *p){ |
75 DWORD tid = GetCurrentThreadId(); | 75 DWORD tid = GetCurrentThreadId(); |
76 return winMutexNotheld2(p, tid); | 76 return winMutexNotheld2(p, tid); |
77 } | 77 } |
78 #endif | 78 #endif |
79 | 79 |
80 /* | 80 /* |
| 81 ** Try to provide a memory barrier operation, needed for initialization |
| 82 ** and also for the xShmBarrier method of the VFS in cases when SQLite is |
| 83 ** compiled without mutexes (SQLITE_THREADSAFE=0). |
| 84 */ |
| 85 void sqlite3MemoryBarrier(void){ |
| 86 #if defined(SQLITE_MEMORY_BARRIER) |
| 87 SQLITE_MEMORY_BARRIER; |
| 88 #elif defined(__GNUC__) |
| 89 __sync_synchronize(); |
| 90 #elif !defined(SQLITE_DISABLE_INTRINSIC) && \ |
| 91 defined(_MSC_VER) && _MSC_VER>=1300 |
| 92 _ReadWriteBarrier(); |
| 93 #elif defined(MemoryBarrier) |
| 94 MemoryBarrier(); |
| 95 #endif |
| 96 } |
| 97 |
| 98 /* |
81 ** Initialize and deinitialize the mutex subsystem. | 99 ** Initialize and deinitialize the mutex subsystem. |
82 */ | 100 */ |
83 static sqlite3_mutex winMutex_staticMutexes[] = { | 101 static sqlite3_mutex winMutex_staticMutexes[] = { |
84 SQLITE3_MUTEX_INITIALIZER, | 102 SQLITE3_MUTEX_INITIALIZER, |
85 SQLITE3_MUTEX_INITIALIZER, | 103 SQLITE3_MUTEX_INITIALIZER, |
86 SQLITE3_MUTEX_INITIALIZER, | 104 SQLITE3_MUTEX_INITIALIZER, |
87 SQLITE3_MUTEX_INITIALIZER, | 105 SQLITE3_MUTEX_INITIALIZER, |
88 SQLITE3_MUTEX_INITIALIZER, | 106 SQLITE3_MUTEX_INITIALIZER, |
89 SQLITE3_MUTEX_INITIALIZER, | 107 SQLITE3_MUTEX_INITIALIZER, |
90 SQLITE3_MUTEX_INITIALIZER, | 108 SQLITE3_MUTEX_INITIALIZER, |
91 SQLITE3_MUTEX_INITIALIZER, | 109 SQLITE3_MUTEX_INITIALIZER, |
| 110 SQLITE3_MUTEX_INITIALIZER, |
| 111 SQLITE3_MUTEX_INITIALIZER, |
| 112 SQLITE3_MUTEX_INITIALIZER, |
92 SQLITE3_MUTEX_INITIALIZER | 113 SQLITE3_MUTEX_INITIALIZER |
93 }; | 114 }; |
94 | 115 |
95 static int winMutex_isInit = 0; | 116 static int winMutex_isInit = 0; |
96 static int winMutex_isNt = -1; /* <0 means "need to query" */ | 117 static int winMutex_isNt = -1; /* <0 means "need to query" */ |
97 | 118 |
98 /* As the winMutexInit() and winMutexEnd() functions are called as part | 119 /* As the winMutexInit() and winMutexEnd() functions are called as part |
99 ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the | 120 ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the |
100 ** "interlocked" magic used here is probably not strictly necessary. | 121 ** "interlocked" magic used here is probably not strictly necessary. |
101 */ | 122 */ |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 ** <li> SQLITE_MUTEX_RECURSIVE | 174 ** <li> SQLITE_MUTEX_RECURSIVE |
154 ** <li> SQLITE_MUTEX_STATIC_MASTER | 175 ** <li> SQLITE_MUTEX_STATIC_MASTER |
155 ** <li> SQLITE_MUTEX_STATIC_MEM | 176 ** <li> SQLITE_MUTEX_STATIC_MEM |
156 ** <li> SQLITE_MUTEX_STATIC_OPEN | 177 ** <li> SQLITE_MUTEX_STATIC_OPEN |
157 ** <li> SQLITE_MUTEX_STATIC_PRNG | 178 ** <li> SQLITE_MUTEX_STATIC_PRNG |
158 ** <li> SQLITE_MUTEX_STATIC_LRU | 179 ** <li> SQLITE_MUTEX_STATIC_LRU |
159 ** <li> SQLITE_MUTEX_STATIC_PMEM | 180 ** <li> SQLITE_MUTEX_STATIC_PMEM |
160 ** <li> SQLITE_MUTEX_STATIC_APP1 | 181 ** <li> SQLITE_MUTEX_STATIC_APP1 |
161 ** <li> SQLITE_MUTEX_STATIC_APP2 | 182 ** <li> SQLITE_MUTEX_STATIC_APP2 |
162 ** <li> SQLITE_MUTEX_STATIC_APP3 | 183 ** <li> SQLITE_MUTEX_STATIC_APP3 |
| 184 ** <li> SQLITE_MUTEX_STATIC_VFS1 |
| 185 ** <li> SQLITE_MUTEX_STATIC_VFS2 |
| 186 ** <li> SQLITE_MUTEX_STATIC_VFS3 |
163 ** </ul> | 187 ** </ul> |
164 ** | 188 ** |
165 ** The first two constants cause sqlite3_mutex_alloc() to create | 189 ** The first two constants cause sqlite3_mutex_alloc() to create |
166 ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE | 190 ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE |
167 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. | 191 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. |
168 ** The mutex implementation does not need to make a distinction | 192 ** The mutex implementation does not need to make a distinction |
169 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does | 193 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does |
170 ** not want to. But SQLite will only request a recursive mutex in | 194 ** not want to. But SQLite will only request a recursive mutex in |
171 ** cases where it really needs one. If a faster non-recursive mutex | 195 ** cases where it really needs one. If a faster non-recursive mutex |
172 ** implementation is available on the host platform, the mutex subsystem | 196 ** implementation is available on the host platform, the mutex subsystem |
(...skipping 14 matching lines...) Expand all Loading... |
187 ** the same type number. | 211 ** the same type number. |
188 */ | 212 */ |
189 static sqlite3_mutex *winMutexAlloc(int iType){ | 213 static sqlite3_mutex *winMutexAlloc(int iType){ |
190 sqlite3_mutex *p; | 214 sqlite3_mutex *p; |
191 | 215 |
192 switch( iType ){ | 216 switch( iType ){ |
193 case SQLITE_MUTEX_FAST: | 217 case SQLITE_MUTEX_FAST: |
194 case SQLITE_MUTEX_RECURSIVE: { | 218 case SQLITE_MUTEX_RECURSIVE: { |
195 p = sqlite3MallocZero( sizeof(*p) ); | 219 p = sqlite3MallocZero( sizeof(*p) ); |
196 if( p ){ | 220 if( p ){ |
| 221 p->id = iType; |
197 #ifdef SQLITE_DEBUG | 222 #ifdef SQLITE_DEBUG |
198 p->id = iType; | |
199 #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC | 223 #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC |
200 p->trace = 1; | 224 p->trace = 1; |
201 #endif | 225 #endif |
202 #endif | 226 #endif |
203 #if SQLITE_OS_WINRT | 227 #if SQLITE_OS_WINRT |
204 InitializeCriticalSectionEx(&p->mutex, 0, 0); | 228 InitializeCriticalSectionEx(&p->mutex, 0, 0); |
205 #else | 229 #else |
206 InitializeCriticalSection(&p->mutex); | 230 InitializeCriticalSection(&p->mutex); |
207 #endif | 231 #endif |
208 } | 232 } |
209 break; | 233 break; |
210 } | 234 } |
211 default: { | 235 default: { |
212 assert( iType-2 >= 0 ); | 236 #ifdef SQLITE_ENABLE_API_ARMOR |
213 assert( iType-2 < ArraySize(winMutex_staticMutexes) ); | 237 if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){ |
214 assert( winMutex_isInit==1 ); | 238 (void)SQLITE_MISUSE_BKPT; |
| 239 return 0; |
| 240 } |
| 241 #endif |
215 p = &winMutex_staticMutexes[iType-2]; | 242 p = &winMutex_staticMutexes[iType-2]; |
| 243 p->id = iType; |
216 #ifdef SQLITE_DEBUG | 244 #ifdef SQLITE_DEBUG |
217 p->id = iType; | |
218 #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC | 245 #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC |
219 p->trace = 1; | 246 p->trace = 1; |
220 #endif | 247 #endif |
221 #endif | 248 #endif |
222 break; | 249 break; |
223 } | 250 } |
224 } | 251 } |
225 return p; | 252 return p; |
226 } | 253 } |
227 | 254 |
228 | 255 |
229 /* | 256 /* |
230 ** This routine deallocates a previously | 257 ** This routine deallocates a previously |
231 ** allocated mutex. SQLite is careful to deallocate every | 258 ** allocated mutex. SQLite is careful to deallocate every |
232 ** mutex that it allocates. | 259 ** mutex that it allocates. |
233 */ | 260 */ |
234 static void winMutexFree(sqlite3_mutex *p){ | 261 static void winMutexFree(sqlite3_mutex *p){ |
235 assert( p ); | 262 assert( p ); |
236 #ifdef SQLITE_DEBUG | |
237 assert( p->nRef==0 && p->owner==0 ); | 263 assert( p->nRef==0 && p->owner==0 ); |
238 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); | 264 if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ |
| 265 DeleteCriticalSection(&p->mutex); |
| 266 sqlite3_free(p); |
| 267 }else{ |
| 268 #ifdef SQLITE_ENABLE_API_ARMOR |
| 269 (void)SQLITE_MISUSE_BKPT; |
239 #endif | 270 #endif |
240 assert( winMutex_isInit==1 ); | 271 } |
241 DeleteCriticalSection(&p->mutex); | |
242 sqlite3_free(p); | |
243 } | 272 } |
244 | 273 |
245 /* | 274 /* |
246 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt | 275 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt |
247 ** to enter a mutex. If another thread is already within the mutex, | 276 ** to enter a mutex. If another thread is already within the mutex, |
248 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return | 277 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return |
249 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK | 278 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK |
250 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can | 279 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can |
251 ** be entered multiple times by the same thread. In such cases the, | 280 ** be entered multiple times by the same thread. In such cases the, |
252 ** mutex must be exited an equal number of times before another thread | 281 ** mutex must be exited an equal number of times before another thread |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 winMutexNotheld | 391 winMutexNotheld |
363 #else | 392 #else |
364 0, | 393 0, |
365 0 | 394 0 |
366 #endif | 395 #endif |
367 }; | 396 }; |
368 return &sMutex; | 397 return &sMutex; |
369 } | 398 } |
370 | 399 |
371 #endif /* SQLITE_MUTEX_W32 */ | 400 #endif /* SQLITE_MUTEX_W32 */ |
OLD | NEW |