4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
11 *************************************************************************
12 ** This file contains the C functions that implement mutexes.
14 ** This file contains code that is common across all mutex implementations.
16 #include "sqliteInt.h"
18 #if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
20 ** For debugging purposes, record when the mutex subsystem is initialized
21 ** and uninitialized so that we can assert() if there is an attempt to
22 ** allocate a mutex while the system is uninitialized.
24 static SQLITE_WSD
int mutexIsInit
= 0;
25 #endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */
28 #ifndef SQLITE_MUTEX_OMIT
30 #ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
32 ** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains
33 ** the implementation of a wrapper around the system default mutex
34 ** implementation (sqlite3DefaultMutex()).
36 ** Most calls are passed directly through to the underlying default
37 ** mutex implementation. Except, if a mutex is configured by calling
38 ** sqlite3MutexWarnOnContention() on it, then if contention is ever
39 ** encountered within xMutexEnter() a warning is emitted via sqlite3_log().
41 ** This type of mutex is used as the database handle mutex when testing
42 ** apps that usually use SQLITE_CONFIG_MULTITHREAD mode.
46 ** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS
47 ** is defined. Variable CheckMutex.mutex is a pointer to the real mutex
48 ** allocated by the system mutex implementation. Variable iType is usually set
49 ** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST
50 ** or one of the static mutex identifiers. Or, if this is a recursive mutex
51 ** that has been configured using sqlite3MutexWarnOnContention(), it is
52 ** set to SQLITE_MUTEX_WARNONCONTENTION.
54 typedef struct CheckMutex CheckMutex
;
60 #define SQLITE_MUTEX_WARNONCONTENTION (-1)
63 ** Pointer to real mutex methods object used by the CheckMutex
64 ** implementation. Set by checkMutexInit().
66 static SQLITE_WSD
const sqlite3_mutex_methods
*pGlobalMutexMethods
;
69 static int checkMutexHeld(sqlite3_mutex
*p
){
70 return pGlobalMutexMethods
->xMutexHeld(((CheckMutex
*)p
)->mutex
);
72 static int checkMutexNotheld(sqlite3_mutex
*p
){
73 return pGlobalMutexMethods
->xMutexNotheld(((CheckMutex
*)p
)->mutex
);
78 ** Initialize and deinitialize the mutex subsystem.
80 static int checkMutexInit(void){
81 pGlobalMutexMethods
= sqlite3DefaultMutex();
84 static int checkMutexEnd(void){
85 pGlobalMutexMethods
= 0;
92 static sqlite3_mutex
*checkMutexAlloc(int iType
){
93 static CheckMutex staticMutexes
[] = {
94 {2, 0}, {3, 0}, {4, 0}, {5, 0},
95 {6, 0}, {7, 0}, {8, 0}, {9, 0},
96 {10, 0}, {11, 0}, {12, 0}, {13, 0}
100 assert( SQLITE_MUTEX_RECURSIVE
==1 && SQLITE_MUTEX_FAST
==0 );
102 p
= sqlite3MallocZero(sizeof(CheckMutex
));
106 #ifdef SQLITE_ENABLE_API_ARMOR
107 if( iType
-2>=ArraySize(staticMutexes
) ){
108 (void)SQLITE_MISUSE_BKPT
;
112 p
= &staticMutexes
[iType
-2];
116 p
->mutex
= pGlobalMutexMethods
->xMutexAlloc(iType
);
125 return (sqlite3_mutex
*)p
;
131 static void checkMutexFree(sqlite3_mutex
*p
){
132 assert( SQLITE_MUTEX_RECURSIVE
<2 );
133 assert( SQLITE_MUTEX_FAST
<2 );
134 assert( SQLITE_MUTEX_WARNONCONTENTION
<2 );
136 #ifdef SQLITE_ENABLE_API_ARMOR
137 if( ((CheckMutex
*)p
)->iType
<2 )
140 CheckMutex
*pCheck
= (CheckMutex
*)p
;
141 pGlobalMutexMethods
->xMutexFree(pCheck
->mutex
);
142 sqlite3_free(pCheck
);
144 #ifdef SQLITE_ENABLE_API_ARMOR
146 (void)SQLITE_MISUSE_BKPT
;
154 static void checkMutexEnter(sqlite3_mutex
*p
){
155 CheckMutex
*pCheck
= (CheckMutex
*)p
;
156 if( pCheck
->iType
==SQLITE_MUTEX_WARNONCONTENTION
){
157 if( SQLITE_OK
==pGlobalMutexMethods
->xMutexTry(pCheck
->mutex
) ){
160 sqlite3_log(SQLITE_MISUSE
,
161 "illegal multi-threaded access to database connection"
164 pGlobalMutexMethods
->xMutexEnter(pCheck
->mutex
);
168 ** Enter the mutex (do not block).
170 static int checkMutexTry(sqlite3_mutex
*p
){
171 CheckMutex
*pCheck
= (CheckMutex
*)p
;
172 return pGlobalMutexMethods
->xMutexTry(pCheck
->mutex
);
178 static void checkMutexLeave(sqlite3_mutex
*p
){
179 CheckMutex
*pCheck
= (CheckMutex
*)p
;
180 pGlobalMutexMethods
->xMutexLeave(pCheck
->mutex
);
183 sqlite3_mutex_methods
const *multiThreadedCheckMutex(void){
184 static const sqlite3_mutex_methods sMutex
= {
204 ** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as
205 ** one on which there should be no contention.
207 void sqlite3MutexWarnOnContention(sqlite3_mutex
*p
){
208 if( sqlite3GlobalConfig
.mutex
.xMutexAlloc
==checkMutexAlloc
){
209 CheckMutex
*pCheck
= (CheckMutex
*)p
;
210 assert( pCheck
->iType
==SQLITE_MUTEX_RECURSIVE
);
211 pCheck
->iType
= SQLITE_MUTEX_WARNONCONTENTION
;
214 #endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */
217 ** Initialize the mutex system.
219 int sqlite3MutexInit(void){
221 if( !sqlite3GlobalConfig
.mutex
.xMutexAlloc
){
222 /* If the xMutexAlloc method has not been set, then the user did not
223 ** install a mutex implementation via sqlite3_config() prior to
224 ** sqlite3_initialize() being called. This block copies pointers to
225 ** the default implementation into the sqlite3GlobalConfig structure.
227 sqlite3_mutex_methods
const *pFrom
;
228 sqlite3_mutex_methods
*pTo
= &sqlite3GlobalConfig
.mutex
;
230 if( sqlite3GlobalConfig
.bCoreMutex
){
231 #ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
232 pFrom
= multiThreadedCheckMutex();
234 pFrom
= sqlite3DefaultMutex();
237 pFrom
= sqlite3NoopMutex();
239 pTo
->xMutexInit
= pFrom
->xMutexInit
;
240 pTo
->xMutexEnd
= pFrom
->xMutexEnd
;
241 pTo
->xMutexFree
= pFrom
->xMutexFree
;
242 pTo
->xMutexEnter
= pFrom
->xMutexEnter
;
243 pTo
->xMutexTry
= pFrom
->xMutexTry
;
244 pTo
->xMutexLeave
= pFrom
->xMutexLeave
;
245 pTo
->xMutexHeld
= pFrom
->xMutexHeld
;
246 pTo
->xMutexNotheld
= pFrom
->xMutexNotheld
;
247 sqlite3MemoryBarrier();
248 pTo
->xMutexAlloc
= pFrom
->xMutexAlloc
;
250 assert( sqlite3GlobalConfig
.mutex
.xMutexInit
);
251 rc
= sqlite3GlobalConfig
.mutex
.xMutexInit();
254 GLOBAL(int, mutexIsInit
) = 1;
257 sqlite3MemoryBarrier();
262 ** Shutdown the mutex system. This call frees resources allocated by
263 ** sqlite3MutexInit().
265 int sqlite3MutexEnd(void){
267 if( sqlite3GlobalConfig
.mutex
.xMutexEnd
){
268 rc
= sqlite3GlobalConfig
.mutex
.xMutexEnd();
272 GLOBAL(int, mutexIsInit
) = 0;
279 ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
281 sqlite3_mutex
*sqlite3_mutex_alloc(int id
){
282 #ifndef SQLITE_OMIT_AUTOINIT
283 if( id
<=SQLITE_MUTEX_RECURSIVE
&& sqlite3_initialize() ) return 0;
284 if( id
>SQLITE_MUTEX_RECURSIVE
&& sqlite3MutexInit() ) return 0;
286 assert( sqlite3GlobalConfig
.mutex
.xMutexAlloc
);
287 return sqlite3GlobalConfig
.mutex
.xMutexAlloc(id
);
290 sqlite3_mutex
*sqlite3MutexAlloc(int id
){
291 if( !sqlite3GlobalConfig
.bCoreMutex
){
294 assert( GLOBAL(int, mutexIsInit
) );
295 assert( sqlite3GlobalConfig
.mutex
.xMutexAlloc
);
296 return sqlite3GlobalConfig
.mutex
.xMutexAlloc(id
);
300 ** Free a dynamic mutex.
302 void sqlite3_mutex_free(sqlite3_mutex
*p
){
304 assert( sqlite3GlobalConfig
.mutex
.xMutexFree
);
305 sqlite3GlobalConfig
.mutex
.xMutexFree(p
);
310 ** Obtain the mutex p. If some other thread already has the mutex, block
311 ** until it can be obtained.
313 void sqlite3_mutex_enter(sqlite3_mutex
*p
){
315 assert( sqlite3GlobalConfig
.mutex
.xMutexEnter
);
316 sqlite3GlobalConfig
.mutex
.xMutexEnter(p
);
321 ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
322 ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
324 int sqlite3_mutex_try(sqlite3_mutex
*p
){
327 assert( sqlite3GlobalConfig
.mutex
.xMutexTry
);
328 return sqlite3GlobalConfig
.mutex
.xMutexTry(p
);
334 ** The sqlite3_mutex_leave() routine exits a mutex that was previously
335 ** entered by the same thread. The behavior is undefined if the mutex
336 ** is not currently entered. If a NULL pointer is passed as an argument
337 ** this function is a no-op.
339 void sqlite3_mutex_leave(sqlite3_mutex
*p
){
341 assert( sqlite3GlobalConfig
.mutex
.xMutexLeave
);
342 sqlite3GlobalConfig
.mutex
.xMutexLeave(p
);
348 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
349 ** intended for use inside assert() statements.
351 int sqlite3_mutex_held(sqlite3_mutex
*p
){
352 assert( p
==0 || sqlite3GlobalConfig
.mutex
.xMutexHeld
);
353 return p
==0 || sqlite3GlobalConfig
.mutex
.xMutexHeld(p
);
355 int sqlite3_mutex_notheld(sqlite3_mutex
*p
){
356 assert( p
==0 || sqlite3GlobalConfig
.mutex
.xMutexNotheld
);
357 return p
==0 || sqlite3GlobalConfig
.mutex
.xMutexNotheld(p
);
361 #endif /* !defined(SQLITE_MUTEX_OMIT) */