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