| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2008 October 07 | 2 ** 2008 October 07 |
| 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 ** |
| 11 ************************************************************************* | 11 ************************************************************************* |
| 12 ** This file contains the C functions that implement mutexes. | 12 ** This file contains the C functions that implement mutexes. |
| 13 ** | 13 ** |
| 14 ** This implementation in this file does not provide any mutual | 14 ** This implementation in this file does not provide any mutual |
| 15 ** exclusion and is thus suitable for use only in applications | 15 ** exclusion and is thus suitable for use only in applications |
| 16 ** that use SQLite in a single thread. The routines defined | 16 ** that use SQLite in a single thread. The routines defined |
| 17 ** here are place-holders. Applications can substitute working | 17 ** here are place-holders. Applications can substitute working |
| 18 ** mutex routines at start-time using the | 18 ** mutex routines at start-time using the |
| 19 ** | 19 ** |
| 20 ** sqlite3_config(SQLITE_CONFIG_MUTEX,...) | 20 ** sqlite3_config(SQLITE_CONFIG_MUTEX,...) |
| 21 ** | 21 ** |
| 22 ** interface. | 22 ** interface. |
| 23 ** | 23 ** |
| 24 ** If compiled with SQLITE_DEBUG, then additional logic is inserted | 24 ** If compiled with SQLITE_DEBUG, then additional logic is inserted |
| 25 ** that does error checking on mutexes to make sure they are being | 25 ** that does error checking on mutexes to make sure they are being |
| 26 ** called correctly. | 26 ** called correctly. |
| 27 ** | |
| 28 ** $Id: mutex_noop.c,v 1.3 2008/12/05 17:17:08 drh Exp $ | |
| 29 */ | 27 */ |
| 30 #include "sqliteInt.h" | 28 #include "sqliteInt.h" |
| 31 | 29 |
| 30 #ifndef SQLITE_MUTEX_OMIT |
| 32 | 31 |
| 33 #if defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) | 32 #ifndef SQLITE_DEBUG |
| 34 /* | 33 /* |
| 35 ** Stub routines for all mutex methods. | 34 ** Stub routines for all mutex methods. |
| 36 ** | 35 ** |
| 37 ** This routines provide no mutual exclusion or error checking. | 36 ** This routines provide no mutual exclusion or error checking. |
| 38 */ | 37 */ |
| 39 static int noopMutexHeld(sqlite3_mutex *p){ return 1; } | |
| 40 static int noopMutexNotheld(sqlite3_mutex *p){ return 1; } | |
| 41 static int noopMutexInit(void){ return SQLITE_OK; } | 38 static int noopMutexInit(void){ return SQLITE_OK; } |
| 42 static int noopMutexEnd(void){ return SQLITE_OK; } | 39 static int noopMutexEnd(void){ return SQLITE_OK; } |
| 43 static sqlite3_mutex *noopMutexAlloc(int id){ return (sqlite3_mutex*)8; } | 40 static sqlite3_mutex *noopMutexAlloc(int id){ |
| 44 static void noopMutexFree(sqlite3_mutex *p){ return; } | 41 UNUSED_PARAMETER(id); |
| 45 static void noopMutexEnter(sqlite3_mutex *p){ return; } | 42 return (sqlite3_mutex*)8; |
| 46 static int noopMutexTry(sqlite3_mutex *p){ return SQLITE_OK; } | 43 } |
| 47 static void noopMutexLeave(sqlite3_mutex *p){ return; } | 44 static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
| 45 static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
| 46 static int noopMutexTry(sqlite3_mutex *p){ |
| 47 UNUSED_PARAMETER(p); |
| 48 return SQLITE_OK; |
| 49 } |
| 50 static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
| 48 | 51 |
| 49 sqlite3_mutex_methods *sqlite3DefaultMutex(void){ | 52 sqlite3_mutex_methods const *sqlite3NoopMutex(void){ |
| 50 static sqlite3_mutex_methods sMutex = { | 53 static const sqlite3_mutex_methods sMutex = { |
| 51 noopMutexInit, | 54 noopMutexInit, |
| 52 noopMutexEnd, | 55 noopMutexEnd, |
| 53 noopMutexAlloc, | 56 noopMutexAlloc, |
| 54 noopMutexFree, | 57 noopMutexFree, |
| 55 noopMutexEnter, | 58 noopMutexEnter, |
| 56 noopMutexTry, | 59 noopMutexTry, |
| 57 noopMutexLeave, | 60 noopMutexLeave, |
| 58 | 61 |
| 59 noopMutexHeld, | 62 0, |
| 60 noopMutexNotheld | 63 0, |
| 61 }; | 64 }; |
| 62 | 65 |
| 63 return &sMutex; | 66 return &sMutex; |
| 64 } | 67 } |
| 65 #endif /* defined(SQLITE_MUTEX_NOOP) && !defined(SQLITE_DEBUG) */ | 68 #endif /* !SQLITE_DEBUG */ |
| 66 | 69 |
| 67 #if defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG) | 70 #ifdef SQLITE_DEBUG |
| 68 /* | 71 /* |
| 69 ** In this implementation, error checking is provided for testing | 72 ** In this implementation, error checking is provided for testing |
| 70 ** and debugging purposes. The mutexes still do not provide any | 73 ** and debugging purposes. The mutexes still do not provide any |
| 71 ** mutual exclusion. | 74 ** mutual exclusion. |
| 72 */ | 75 */ |
| 73 | 76 |
| 74 /* | 77 /* |
| 75 ** The mutex object | 78 ** The mutex object |
| 76 */ | 79 */ |
| 77 struct sqlite3_mutex { | 80 typedef struct sqlite3_debug_mutex { |
| 78 int id; /* The mutex type */ | 81 int id; /* The mutex type */ |
| 79 int cnt; /* Number of entries without a matching leave */ | 82 int cnt; /* Number of entries without a matching leave */ |
| 80 }; | 83 } sqlite3_debug_mutex; |
| 81 | 84 |
| 82 /* | 85 /* |
| 83 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are | 86 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 84 ** intended for use inside assert() statements. | 87 ** intended for use inside assert() statements. |
| 85 */ | 88 */ |
| 86 static int debugMutexHeld(sqlite3_mutex *p){ | 89 static int debugMutexHeld(sqlite3_mutex *pX){ |
| 90 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 87 return p==0 || p->cnt>0; | 91 return p==0 || p->cnt>0; |
| 88 } | 92 } |
| 89 static int debugMutexNotheld(sqlite3_mutex *p){ | 93 static int debugMutexNotheld(sqlite3_mutex *pX){ |
| 94 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 90 return p==0 || p->cnt==0; | 95 return p==0 || p->cnt==0; |
| 91 } | 96 } |
| 92 | 97 |
| 93 /* | 98 /* |
| 94 ** Initialize and deinitialize the mutex subsystem. | 99 ** Initialize and deinitialize the mutex subsystem. |
| 95 */ | 100 */ |
| 96 static int debugMutexInit(void){ return SQLITE_OK; } | 101 static int debugMutexInit(void){ return SQLITE_OK; } |
| 97 static int debugMutexEnd(void){ return SQLITE_OK; } | 102 static int debugMutexEnd(void){ return SQLITE_OK; } |
| 98 | 103 |
| 99 /* | 104 /* |
| 100 ** The sqlite3_mutex_alloc() routine allocates a new | 105 ** The sqlite3_mutex_alloc() routine allocates a new |
| 101 ** mutex and returns a pointer to it. If it returns NULL | 106 ** mutex and returns a pointer to it. If it returns NULL |
| 102 ** that means that a mutex could not be allocated. | 107 ** that means that a mutex could not be allocated. |
| 103 */ | 108 */ |
| 104 static sqlite3_mutex *debugMutexAlloc(int id){ | 109 static sqlite3_mutex *debugMutexAlloc(int id){ |
| 105 static sqlite3_mutex aStatic[6]; | 110 static sqlite3_debug_mutex aStatic[6]; |
| 106 sqlite3_mutex *pNew = 0; | 111 sqlite3_debug_mutex *pNew = 0; |
| 107 switch( id ){ | 112 switch( id ){ |
| 108 case SQLITE_MUTEX_FAST: | 113 case SQLITE_MUTEX_FAST: |
| 109 case SQLITE_MUTEX_RECURSIVE: { | 114 case SQLITE_MUTEX_RECURSIVE: { |
| 110 pNew = sqlite3Malloc(sizeof(*pNew)); | 115 pNew = sqlite3Malloc(sizeof(*pNew)); |
| 111 if( pNew ){ | 116 if( pNew ){ |
| 112 pNew->id = id; | 117 pNew->id = id; |
| 113 pNew->cnt = 0; | 118 pNew->cnt = 0; |
| 114 } | 119 } |
| 115 break; | 120 break; |
| 116 } | 121 } |
| 117 default: { | 122 default: { |
| 118 assert( id-2 >= 0 ); | 123 assert( id-2 >= 0 ); |
| 119 assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) ); | 124 assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) ); |
| 120 pNew = &aStatic[id-2]; | 125 pNew = &aStatic[id-2]; |
| 121 pNew->id = id; | 126 pNew->id = id; |
| 122 break; | 127 break; |
| 123 } | 128 } |
| 124 } | 129 } |
| 125 return pNew; | 130 return (sqlite3_mutex*)pNew; |
| 126 } | 131 } |
| 127 | 132 |
| 128 /* | 133 /* |
| 129 ** This routine deallocates a previously allocated mutex. | 134 ** This routine deallocates a previously allocated mutex. |
| 130 */ | 135 */ |
| 131 static void debugMutexFree(sqlite3_mutex *p){ | 136 static void debugMutexFree(sqlite3_mutex *pX){ |
| 137 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 132 assert( p->cnt==0 ); | 138 assert( p->cnt==0 ); |
| 133 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); | 139 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); |
| 134 sqlite3_free(p); | 140 sqlite3_free(p); |
| 135 } | 141 } |
| 136 | 142 |
| 137 /* | 143 /* |
| 138 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt | 144 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt |
| 139 ** to enter a mutex. If another thread is already within the mutex, | 145 ** to enter a mutex. If another thread is already within the mutex, |
| 140 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return | 146 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return |
| 141 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK | 147 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK |
| 142 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can | 148 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can |
| 143 ** be entered multiple times by the same thread. In such cases the, | 149 ** be entered multiple times by the same thread. In such cases the, |
| 144 ** mutex must be exited an equal number of times before another thread | 150 ** mutex must be exited an equal number of times before another thread |
| 145 ** can enter. If the same thread tries to enter any other kind of mutex | 151 ** can enter. If the same thread tries to enter any other kind of mutex |
| 146 ** more than once, the behavior is undefined. | 152 ** more than once, the behavior is undefined. |
| 147 */ | 153 */ |
| 148 static void debugMutexEnter(sqlite3_mutex *p){ | 154 static void debugMutexEnter(sqlite3_mutex *pX){ |
| 149 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); | 155 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 156 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); |
| 150 p->cnt++; | 157 p->cnt++; |
| 151 } | 158 } |
| 152 static int debugMutexTry(sqlite3_mutex *p){ | 159 static int debugMutexTry(sqlite3_mutex *pX){ |
| 153 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); | 160 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 161 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); |
| 154 p->cnt++; | 162 p->cnt++; |
| 155 return SQLITE_OK; | 163 return SQLITE_OK; |
| 156 } | 164 } |
| 157 | 165 |
| 158 /* | 166 /* |
| 159 ** The sqlite3_mutex_leave() routine exits a mutex that was | 167 ** The sqlite3_mutex_leave() routine exits a mutex that was |
| 160 ** previously entered by the same thread. The behavior | 168 ** previously entered by the same thread. The behavior |
| 161 ** is undefined if the mutex is not currently entered or | 169 ** is undefined if the mutex is not currently entered or |
| 162 ** is not currently allocated. SQLite will never do either. | 170 ** is not currently allocated. SQLite will never do either. |
| 163 */ | 171 */ |
| 164 static void debugMutexLeave(sqlite3_mutex *p){ | 172 static void debugMutexLeave(sqlite3_mutex *pX){ |
| 165 assert( debugMutexHeld(p) ); | 173 sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; |
| 174 assert( debugMutexHeld(pX) ); |
| 166 p->cnt--; | 175 p->cnt--; |
| 167 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(p) ); | 176 assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); |
| 168 } | 177 } |
| 169 | 178 |
| 170 sqlite3_mutex_methods *sqlite3DefaultMutex(void){ | 179 sqlite3_mutex_methods const *sqlite3NoopMutex(void){ |
| 171 static sqlite3_mutex_methods sMutex = { | 180 static const sqlite3_mutex_methods sMutex = { |
| 172 debugMutexInit, | 181 debugMutexInit, |
| 173 debugMutexEnd, | 182 debugMutexEnd, |
| 174 debugMutexAlloc, | 183 debugMutexAlloc, |
| 175 debugMutexFree, | 184 debugMutexFree, |
| 176 debugMutexEnter, | 185 debugMutexEnter, |
| 177 debugMutexTry, | 186 debugMutexTry, |
| 178 debugMutexLeave, | 187 debugMutexLeave, |
| 179 | 188 |
| 180 debugMutexHeld, | 189 debugMutexHeld, |
| 181 debugMutexNotheld | 190 debugMutexNotheld |
| 182 }; | 191 }; |
| 183 | 192 |
| 184 return &sMutex; | 193 return &sMutex; |
| 185 } | 194 } |
| 186 #endif /* defined(SQLITE_MUTEX_NOOP) && defined(SQLITE_DEBUG) */ | 195 #endif /* SQLITE_DEBUG */ |
| 196 |
| 197 /* |
| 198 ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation |
| 199 ** is used regardless of the run-time threadsafety setting. |
| 200 */ |
| 201 #ifdef SQLITE_MUTEX_NOOP |
| 202 sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| 203 return sqlite3NoopMutex(); |
| 204 } |
| 205 #endif /* SQLITE_MUTEX_NOOP */ |
| 206 #endif /* SQLITE_MUTEX_OMIT */ |
| OLD | NEW |