xref: /sqlite-3.40.0/src/mutex.c (revision 5d00d0a8)
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.
13 **
14 ** This file contains code that is common across all mutex implementations.
15 
16 **
17 ** $Id: mutex.c,v 1.31 2009/07/16 18:21:18 drh Exp $
18 */
19 #include "sqliteInt.h"
20 
21 #ifndef SQLITE_MUTEX_OMIT
22 /*
23 ** Initialize the mutex system.
24 */
25 int sqlite3MutexInit(void){
26   int rc = SQLITE_OK;
27   if( sqlite3GlobalConfig.bCoreMutex ){
28     if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){
29       /* If the xMutexAlloc method has not been set, then the user did not
30       ** install a mutex implementation via sqlite3_config() prior to
31       ** sqlite3_initialize() being called. This block copies pointers to
32       ** the default implementation into the sqlite3GlobalConfig structure.
33       */
34       sqlite3_mutex_methods *pFrom = sqlite3DefaultMutex();
35       sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
36 
37       memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc));
38       memcpy(&pTo->xMutexFree, &pFrom->xMutexFree,
39              sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree));
40       pTo->xMutexAlloc = pFrom->xMutexAlloc;
41     }
42     rc = sqlite3GlobalConfig.mutex.xMutexInit();
43   }
44 
45   return rc;
46 }
47 
48 /*
49 ** Shutdown the mutex system. This call frees resources allocated by
50 ** sqlite3MutexInit().
51 */
52 int sqlite3MutexEnd(void){
53   int rc = SQLITE_OK;
54   if( sqlite3GlobalConfig.mutex.xMutexEnd ){
55     rc = sqlite3GlobalConfig.mutex.xMutexEnd();
56   }
57   return rc;
58 }
59 
60 /*
61 ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
62 */
63 sqlite3_mutex *sqlite3_mutex_alloc(int id){
64 #ifndef SQLITE_OMIT_AUTOINIT
65   if( sqlite3_initialize() ) return 0;
66 #endif
67   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
68 }
69 
70 sqlite3_mutex *sqlite3MutexAlloc(int id){
71   if( !sqlite3GlobalConfig.bCoreMutex ){
72     return 0;
73   }
74   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
75 }
76 
77 /*
78 ** Free a dynamic mutex.
79 */
80 void sqlite3_mutex_free(sqlite3_mutex *p){
81   if( p ){
82     sqlite3GlobalConfig.mutex.xMutexFree(p);
83   }
84 }
85 
86 /*
87 ** Obtain the mutex p. If some other thread already has the mutex, block
88 ** until it can be obtained.
89 */
90 void sqlite3_mutex_enter(sqlite3_mutex *p){
91   if( p ){
92     sqlite3GlobalConfig.mutex.xMutexEnter(p);
93   }
94 }
95 
96 /*
97 ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
98 ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
99 */
100 int sqlite3_mutex_try(sqlite3_mutex *p){
101   int rc = SQLITE_OK;
102   if( p ){
103     return sqlite3GlobalConfig.mutex.xMutexTry(p);
104   }
105   return rc;
106 }
107 
108 /*
109 ** The sqlite3_mutex_leave() routine exits a mutex that was previously
110 ** entered by the same thread.  The behavior is undefined if the mutex
111 ** is not currently entered. If a NULL pointer is passed as an argument
112 ** this function is a no-op.
113 */
114 void sqlite3_mutex_leave(sqlite3_mutex *p){
115   if( p ){
116     sqlite3GlobalConfig.mutex.xMutexLeave(p);
117   }
118 }
119 
120 #ifndef NDEBUG
121 /*
122 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
123 ** intended for use inside assert() statements.
124 */
125 int sqlite3_mutex_held(sqlite3_mutex *p){
126   return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
127 }
128 int sqlite3_mutex_notheld(sqlite3_mutex *p){
129   return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
130 }
131 #endif
132 
133 #endif /* SQLITE_OMIT_MUTEX */
134