blob: 3ad7b89edc2510639b61b472e0db8804e28fc8b6 [file] [log] [blame]
drh90f6a5b2007-08-15 13:04:54 +00001/*
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*************************************************************************
drh437b9012007-08-28 16:34:42 +000012** This file contains the C functions that implement mutexes.
drh90f6a5b2007-08-15 13:04:54 +000013**
drh18472fa2008-10-07 15:25:48 +000014** This file contains code that is common across all mutex implementations.
drh90f6a5b2007-08-15 13:04:54 +000015*/
16#include "sqliteInt.h"
17
drhd0bc5d22009-09-10 22:30:53 +000018#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT)
drhfe5bdb32009-09-10 17:45:00 +000019/*
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.
23*/
24static SQLITE_WSD int mutexIsInit = 0;
mistachkin04abf082015-09-12 18:57:45 +000025#endif /* SQLITE_DEBUG && !defined(SQLITE_MUTEX_OMIT) */
drhfe5bdb32009-09-10 17:45:00 +000026
27
drh18472fa2008-10-07 15:25:48 +000028#ifndef SQLITE_MUTEX_OMIT
dan8385bec2017-11-25 17:51:01 +000029
30#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
31/*
32** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains
33** the implementation of a wrapper around the system default mutex
34** implementation (sqlite3DefaultMutex()).
35**
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().
40**
41** This type of mutex is used as the database handle mutex when testing
42** apps that usually use SQLITE_CONFIG_MULTITHREAD mode.
43*/
44
45/*
46** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS
dana90a2d52017-11-28 07:47:57 +000047** 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.
dan8385bec2017-11-25 17:51:01 +000053*/
54typedef struct CheckMutex CheckMutex;
55struct CheckMutex {
56 int iType;
57 sqlite3_mutex *mutex;
58};
59
dana90a2d52017-11-28 07:47:57 +000060#define SQLITE_MUTEX_WARNONCONTENTION (-1)
61
dan8385bec2017-11-25 17:51:01 +000062/*
63** Pointer to real mutex methods object used by the CheckMutex
64** implementation. Set by checkMutexInit().
65*/
66static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods;
67
68#ifdef SQLITE_DEBUG
69static int checkMutexHeld(sqlite3_mutex *p){
70 return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex);
71}
72static int checkMutexNotheld(sqlite3_mutex *p){
73 return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex);
74}
75#endif
76
77/*
78** Initialize and deinitialize the mutex subsystem.
79*/
80static int checkMutexInit(void){
81 pGlobalMutexMethods = sqlite3DefaultMutex();
82 return SQLITE_OK;
83}
84static int checkMutexEnd(void){
85 pGlobalMutexMethods = 0;
86 return SQLITE_OK;
87}
88
89/*
90** Allocate a mutex.
91*/
92static 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}
97 };
98 CheckMutex *p = 0;
99
100 assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 );
101 if( iType<2 ){
102 p = sqlite3MallocZero(sizeof(CheckMutex));
103 if( p==0 ) return 0;
104 p->iType = iType;
105 }else{
106#ifdef SQLITE_ENABLE_API_ARMOR
107 if( iType-2>=ArraySize(staticMutexes) ){
108 (void)SQLITE_MISUSE_BKPT;
109 return 0;
110 }
111#endif
112 p = &staticMutexes[iType-2];
113 }
114
115 if( p->mutex==0 ){
116 p->mutex = pGlobalMutexMethods->xMutexAlloc(iType);
117 if( p->mutex==0 ){
118 if( iType<2 ){
119 sqlite3_free(p);
120 }
121 p = 0;
122 }
123 }
124
125 return (sqlite3_mutex*)p;
126}
127
128/*
129** Free a mutex.
130*/
131static void checkMutexFree(sqlite3_mutex *p){
dana90a2d52017-11-28 07:47:57 +0000132 assert( SQLITE_MUTEX_RECURSIVE<2 );
133 assert( SQLITE_MUTEX_FAST<2 );
134 assert( SQLITE_MUTEX_WARNONCONTENTION<2 );
135
dan8385bec2017-11-25 17:51:01 +0000136#if SQLITE_ENABLE_API_ARMOR
dan8adb25a2017-12-05 14:58:59 +0000137 if( ((CheckMutex*)p)->iType<2 )
dan8385bec2017-11-25 17:51:01 +0000138#endif
139 {
140 CheckMutex *pCheck = (CheckMutex*)p;
141 pGlobalMutexMethods->xMutexFree(pCheck->mutex);
142 sqlite3_free(pCheck);
143 }
144#ifdef SQLITE_ENABLE_API_ARMOR
145 else{
146 (void)SQLITE_MISUSE_BKPT;
147 }
148#endif
149}
150
151/*
152** Enter the mutex.
153*/
154static void checkMutexEnter(sqlite3_mutex *p){
155 CheckMutex *pCheck = (CheckMutex*)p;
dana90a2d52017-11-28 07:47:57 +0000156 if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){
dan8385bec2017-11-25 17:51:01 +0000157 if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){
158 return;
159 }
160 sqlite3_log(SQLITE_MISUSE,
161 "illegal multi-threaded access to database connection"
162 );
163 }
164 pGlobalMutexMethods->xMutexEnter(pCheck->mutex);
165}
166
167/*
168** Enter the mutex (do not block).
169*/
170static int checkMutexTry(sqlite3_mutex *p){
171 CheckMutex *pCheck = (CheckMutex*)p;
172 return pGlobalMutexMethods->xMutexTry(pCheck->mutex);
173}
174
175/*
176** Leave the mutex.
177*/
178static void checkMutexLeave(sqlite3_mutex *p){
179 CheckMutex *pCheck = (CheckMutex*)p;
180 pGlobalMutexMethods->xMutexLeave(pCheck->mutex);
181}
182
183sqlite3_mutex_methods const *multiThreadedCheckMutex(void){
184 static const sqlite3_mutex_methods sMutex = {
185 checkMutexInit,
186 checkMutexEnd,
187 checkMutexAlloc,
188 checkMutexFree,
189 checkMutexEnter,
190 checkMutexTry,
191 checkMutexLeave,
192#ifdef SQLITE_DEBUG
193 checkMutexHeld,
194 checkMutexNotheld
195#else
196 0,
197 0
198#endif
199 };
200 return &sMutex;
201}
202
203/*
204** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as
205** one on which there should be no contention.
206*/
207void sqlite3MutexWarnOnContention(sqlite3_mutex *p){
208 if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){
209 CheckMutex *pCheck = (CheckMutex*)p;
210 assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE );
dana90a2d52017-11-28 07:47:57 +0000211 pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION;
dan8385bec2017-11-25 17:51:01 +0000212 }
213}
214#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */
215
danielk19776d2ab0e2008-06-17 17:21:18 +0000216/*
217** Initialize the mutex system.
218*/
danielk1977d0251742008-06-18 18:57:42 +0000219int sqlite3MutexInit(void){
danielk197759f8c082008-06-18 17:09:10 +0000220 int rc = SQLITE_OK;
drh92d76522010-05-05 00:05:24 +0000221 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.
226 */
dan558814f2010-06-02 05:53:53 +0000227 sqlite3_mutex_methods const *pFrom;
drh92d76522010-05-05 00:05:24 +0000228 sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
drhe64ca7b2009-07-16 18:21:17 +0000229
drh92d76522010-05-05 00:05:24 +0000230 if( sqlite3GlobalConfig.bCoreMutex ){
dan8385bec2017-11-25 17:51:01 +0000231#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
232 pFrom = multiThreadedCheckMutex();
233#else
drh92d76522010-05-05 00:05:24 +0000234 pFrom = sqlite3DefaultMutex();
dan8385bec2017-11-25 17:51:01 +0000235#endif
drh92d76522010-05-05 00:05:24 +0000236 }else{
237 pFrom = sqlite3NoopMutex();
danielk19776d2ab0e2008-06-17 17:21:18 +0000238 }
drhf5ed7ad2015-06-15 14:43:25 +0000239 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;
drh6081c1d2015-09-06 02:51:04 +0000247 sqlite3MemoryBarrier();
drh92d76522010-05-05 00:05:24 +0000248 pTo->xMutexAlloc = pFrom->xMutexAlloc;
danielk19776d2ab0e2008-06-17 17:21:18 +0000249 }
mistachkin04abf082015-09-12 18:57:45 +0000250 assert( sqlite3GlobalConfig.mutex.xMutexInit );
drh92d76522010-05-05 00:05:24 +0000251 rc = sqlite3GlobalConfig.mutex.xMutexInit();
danielk19776d2ab0e2008-06-17 17:21:18 +0000252
drhfe5bdb32009-09-10 17:45:00 +0000253#ifdef SQLITE_DEBUG
254 GLOBAL(int, mutexIsInit) = 1;
255#endif
256
danielk19776d2ab0e2008-06-17 17:21:18 +0000257 return rc;
258}
259
260/*
261** Shutdown the mutex system. This call frees resources allocated by
danielk1977d0251742008-06-18 18:57:42 +0000262** sqlite3MutexInit().
danielk19776d2ab0e2008-06-17 17:21:18 +0000263*/
danielk1977d0251742008-06-18 18:57:42 +0000264int sqlite3MutexEnd(void){
danielk19776d2ab0e2008-06-17 17:21:18 +0000265 int rc = SQLITE_OK;
danielk19770a549072009-02-17 16:29:10 +0000266 if( sqlite3GlobalConfig.mutex.xMutexEnd ){
267 rc = sqlite3GlobalConfig.mutex.xMutexEnd();
268 }
drhfe5bdb32009-09-10 17:45:00 +0000269
270#ifdef SQLITE_DEBUG
271 GLOBAL(int, mutexIsInit) = 0;
272#endif
273
danielk19776d2ab0e2008-06-17 17:21:18 +0000274 return rc;
275}
276
277/*
278** Retrieve a pointer to a static mutex or allocate a new dynamic one.
279*/
280sqlite3_mutex *sqlite3_mutex_alloc(int id){
danielk1977bc10d772008-06-18 18:08:39 +0000281#ifndef SQLITE_OMIT_AUTOINIT
drhd42d0be2014-07-30 21:10:12 +0000282 if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
mistachkin2d8ad512014-10-27 22:06:21 +0000283 if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
danielk1977bc10d772008-06-18 18:08:39 +0000284#endif
mistachkin04abf082015-09-12 18:57:45 +0000285 assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
danielk1977075c23a2008-09-01 18:34:20 +0000286 return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
danielk19776d2ab0e2008-06-17 17:21:18 +0000287}
288
danielk197759f8c082008-06-18 17:09:10 +0000289sqlite3_mutex *sqlite3MutexAlloc(int id){
danielk1977075c23a2008-09-01 18:34:20 +0000290 if( !sqlite3GlobalConfig.bCoreMutex ){
danielk197759f8c082008-06-18 17:09:10 +0000291 return 0;
292 }
drhfe5bdb32009-09-10 17:45:00 +0000293 assert( GLOBAL(int, mutexIsInit) );
mistachkin04abf082015-09-12 18:57:45 +0000294 assert( sqlite3GlobalConfig.mutex.xMutexAlloc );
danielk1977075c23a2008-09-01 18:34:20 +0000295 return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
danielk197759f8c082008-06-18 17:09:10 +0000296}
297
danielk19776d2ab0e2008-06-17 17:21:18 +0000298/*
299** Free a dynamic mutex.
300*/
301void sqlite3_mutex_free(sqlite3_mutex *p){
302 if( p ){
mistachkin04abf082015-09-12 18:57:45 +0000303 assert( sqlite3GlobalConfig.mutex.xMutexFree );
danielk1977075c23a2008-09-01 18:34:20 +0000304 sqlite3GlobalConfig.mutex.xMutexFree(p);
danielk19776d2ab0e2008-06-17 17:21:18 +0000305 }
306}
307
308/*
309** Obtain the mutex p. If some other thread already has the mutex, block
310** until it can be obtained.
311*/
312void sqlite3_mutex_enter(sqlite3_mutex *p){
313 if( p ){
mistachkin04abf082015-09-12 18:57:45 +0000314 assert( sqlite3GlobalConfig.mutex.xMutexEnter );
danielk1977075c23a2008-09-01 18:34:20 +0000315 sqlite3GlobalConfig.mutex.xMutexEnter(p);
danielk19776d2ab0e2008-06-17 17:21:18 +0000316 }
317}
318
319/*
320** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
321** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
322*/
323int sqlite3_mutex_try(sqlite3_mutex *p){
324 int rc = SQLITE_OK;
325 if( p ){
mistachkin04abf082015-09-12 18:57:45 +0000326 assert( sqlite3GlobalConfig.mutex.xMutexTry );
danielk1977075c23a2008-09-01 18:34:20 +0000327 return sqlite3GlobalConfig.mutex.xMutexTry(p);
danielk19776d2ab0e2008-06-17 17:21:18 +0000328 }
329 return rc;
330}
331
332/*
333** The sqlite3_mutex_leave() routine exits a mutex that was previously
334** entered by the same thread. The behavior is undefined if the mutex
335** is not currently entered. If a NULL pointer is passed as an argument
336** this function is a no-op.
337*/
338void sqlite3_mutex_leave(sqlite3_mutex *p){
339 if( p ){
mistachkin04abf082015-09-12 18:57:45 +0000340 assert( sqlite3GlobalConfig.mutex.xMutexLeave );
danielk1977075c23a2008-09-01 18:34:20 +0000341 sqlite3GlobalConfig.mutex.xMutexLeave(p);
danielk19776d2ab0e2008-06-17 17:21:18 +0000342 }
343}
344
345#ifndef NDEBUG
346/*
347** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
348** intended for use inside assert() statements.
349*/
350int sqlite3_mutex_held(sqlite3_mutex *p){
mistachkin04abf082015-09-12 18:57:45 +0000351 assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
danielk1977075c23a2008-09-01 18:34:20 +0000352 return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
danielk19776d2ab0e2008-06-17 17:21:18 +0000353}
354int sqlite3_mutex_notheld(sqlite3_mutex *p){
mistachkin04abf082015-09-12 18:57:45 +0000355 assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
danielk1977075c23a2008-09-01 18:34:20 +0000356 return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
danielk19776d2ab0e2008-06-17 17:21:18 +0000357}
358#endif
359
drhe4c88c02012-01-04 12:57:45 +0000360#endif /* !defined(SQLITE_MUTEX_OMIT) */