| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 ** 2007 August 28 | |
| 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 for pthreads | |
| 13 ** | |
| 14 ** $Id: mutex_unix.c,v 1.16 2008/12/08 18:19:18 drh Exp $ | |
| 15 */ | |
| 16 #include "sqliteInt.h" | |
| 17 | |
| 18 /* | |
| 19 ** The code in this file is only used if we are compiling threadsafe | |
| 20 ** under unix with pthreads. | |
| 21 ** | |
| 22 ** Note that this implementation requires a version of pthreads that | |
| 23 ** supports recursive mutexes. | |
| 24 */ | |
| 25 #ifdef SQLITE_MUTEX_PTHREADS | |
| 26 | |
| 27 #include <pthread.h> | |
| 28 | |
| 29 | |
| 30 /* | |
| 31 ** Each recursive mutex is an instance of the following structure. | |
| 32 */ | |
| 33 struct sqlite3_mutex { | |
| 34 pthread_mutex_t mutex; /* Mutex controlling the lock */ | |
| 35 int id; /* Mutex type */ | |
| 36 int nRef; /* Number of entrances */ | |
| 37 pthread_t owner; /* Thread that is within this mutex */ | |
| 38 #ifdef SQLITE_DEBUG | |
| 39 int trace; /* True to trace changes */ | |
| 40 #endif | |
| 41 }; | |
| 42 #ifdef SQLITE_DEBUG | |
| 43 #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)
0, 0 } | |
| 44 #else | |
| 45 #define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)
0 } | |
| 46 #endif | |
| 47 | |
| 48 /* | |
| 49 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are | |
| 50 ** intended for use only inside assert() statements. On some platforms, | |
| 51 ** there might be race conditions that can cause these routines to | |
| 52 ** deliver incorrect results. In particular, if pthread_equal() is | |
| 53 ** not an atomic operation, then these routines might delivery | |
| 54 ** incorrect results. On most platforms, pthread_equal() is a | |
| 55 ** comparison of two integers and is therefore atomic. But we are | |
| 56 ** told that HPUX is not such a platform. If so, then these routines | |
| 57 ** will not always work correctly on HPUX. | |
| 58 ** | |
| 59 ** On those platforms where pthread_equal() is not atomic, SQLite | |
| 60 ** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to | |
| 61 ** make sure no assert() statements are evaluated and hence these | |
| 62 ** routines are never called. | |
| 63 */ | |
| 64 #if !defined(NDEBUG) || defined(SQLITE_DEBUG) | |
| 65 static int pthreadMutexHeld(sqlite3_mutex *p){ | |
| 66 return (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); | |
| 67 } | |
| 68 static int pthreadMutexNotheld(sqlite3_mutex *p){ | |
| 69 return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; | |
| 70 } | |
| 71 #endif | |
| 72 | |
| 73 /* | |
| 74 ** Initialize and deinitialize the mutex subsystem. | |
| 75 */ | |
| 76 static int pthreadMutexInit(void){ return SQLITE_OK; } | |
| 77 static int pthreadMutexEnd(void){ return SQLITE_OK; } | |
| 78 | |
| 79 /* | |
| 80 ** The sqlite3_mutex_alloc() routine allocates a new | |
| 81 ** mutex and returns a pointer to it. If it returns NULL | |
| 82 ** that means that a mutex could not be allocated. SQLite | |
| 83 ** will unwind its stack and return an error. The argument | |
| 84 ** to sqlite3_mutex_alloc() is one of these integer constants: | |
| 85 ** | |
| 86 ** <ul> | |
| 87 ** <li> SQLITE_MUTEX_FAST | |
| 88 ** <li> SQLITE_MUTEX_RECURSIVE | |
| 89 ** <li> SQLITE_MUTEX_STATIC_MASTER | |
| 90 ** <li> SQLITE_MUTEX_STATIC_MEM | |
| 91 ** <li> SQLITE_MUTEX_STATIC_MEM2 | |
| 92 ** <li> SQLITE_MUTEX_STATIC_PRNG | |
| 93 ** <li> SQLITE_MUTEX_STATIC_LRU | |
| 94 ** <li> SQLITE_MUTEX_STATIC_LRU2 | |
| 95 ** </ul> | |
| 96 ** | |
| 97 ** The first two constants cause sqlite3_mutex_alloc() to create | |
| 98 ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE | |
| 99 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. | |
| 100 ** The mutex implementation does not need to make a distinction | |
| 101 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does | |
| 102 ** not want to. But SQLite will only request a recursive mutex in | |
| 103 ** cases where it really needs one. If a faster non-recursive mutex | |
| 104 ** implementation is available on the host platform, the mutex subsystem | |
| 105 ** might return such a mutex in response to SQLITE_MUTEX_FAST. | |
| 106 ** | |
| 107 ** The other allowed parameters to sqlite3_mutex_alloc() each return | |
| 108 ** a pointer to a static preexisting mutex. Six static mutexes are | |
| 109 ** used by the current version of SQLite. Future versions of SQLite | |
| 110 ** may add additional static mutexes. Static mutexes are for internal | |
| 111 ** use by SQLite only. Applications that use SQLite mutexes should | |
| 112 ** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or | |
| 113 ** SQLITE_MUTEX_RECURSIVE. | |
| 114 ** | |
| 115 ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST | |
| 116 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() | |
| 117 ** returns a different mutex on every call. But for the static | |
| 118 ** mutex types, the same mutex is returned on every call that has | |
| 119 ** the same type number. | |
| 120 */ | |
| 121 static sqlite3_mutex *pthreadMutexAlloc(int iType){ | |
| 122 static sqlite3_mutex staticMutexes[] = { | |
| 123 SQLITE3_MUTEX_INITIALIZER, | |
| 124 SQLITE3_MUTEX_INITIALIZER, | |
| 125 SQLITE3_MUTEX_INITIALIZER, | |
| 126 SQLITE3_MUTEX_INITIALIZER, | |
| 127 SQLITE3_MUTEX_INITIALIZER, | |
| 128 SQLITE3_MUTEX_INITIALIZER | |
| 129 }; | |
| 130 sqlite3_mutex *p; | |
| 131 switch( iType ){ | |
| 132 case SQLITE_MUTEX_RECURSIVE: { | |
| 133 p = sqlite3MallocZero( sizeof(*p) ); | |
| 134 if( p ){ | |
| 135 #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX | |
| 136 /* If recursive mutexes are not available, we will have to | |
| 137 ** build our own. See below. */ | |
| 138 pthread_mutex_init(&p->mutex, 0); | |
| 139 #else | |
| 140 /* Use a recursive mutex if it is available */ | |
| 141 pthread_mutexattr_t recursiveAttr; | |
| 142 pthread_mutexattr_init(&recursiveAttr); | |
| 143 pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); | |
| 144 pthread_mutex_init(&p->mutex, &recursiveAttr); | |
| 145 pthread_mutexattr_destroy(&recursiveAttr); | |
| 146 #endif | |
| 147 p->id = iType; | |
| 148 } | |
| 149 break; | |
| 150 } | |
| 151 case SQLITE_MUTEX_FAST: { | |
| 152 p = sqlite3MallocZero( sizeof(*p) ); | |
| 153 if( p ){ | |
| 154 p->id = iType; | |
| 155 pthread_mutex_init(&p->mutex, 0); | |
| 156 } | |
| 157 break; | |
| 158 } | |
| 159 default: { | |
| 160 assert( iType-2 >= 0 ); | |
| 161 assert( iType-2 < ArraySize(staticMutexes) ); | |
| 162 p = &staticMutexes[iType-2]; | |
| 163 p->id = iType; | |
| 164 break; | |
| 165 } | |
| 166 } | |
| 167 return p; | |
| 168 } | |
| 169 | |
| 170 | |
| 171 /* | |
| 172 ** This routine deallocates a previously | |
| 173 ** allocated mutex. SQLite is careful to deallocate every | |
| 174 ** mutex that it allocates. | |
| 175 */ | |
| 176 static void pthreadMutexFree(sqlite3_mutex *p){ | |
| 177 assert( p->nRef==0 ); | |
| 178 assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); | |
| 179 pthread_mutex_destroy(&p->mutex); | |
| 180 sqlite3_free(p); | |
| 181 } | |
| 182 | |
| 183 /* | |
| 184 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt | |
| 185 ** to enter a mutex. If another thread is already within the mutex, | |
| 186 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return | |
| 187 ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK | |
| 188 ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can | |
| 189 ** be entered multiple times by the same thread. In such cases the, | |
| 190 ** mutex must be exited an equal number of times before another thread | |
| 191 ** can enter. If the same thread tries to enter any other kind of mutex | |
| 192 ** more than once, the behavior is undefined. | |
| 193 */ | |
| 194 static void pthreadMutexEnter(sqlite3_mutex *p){ | |
| 195 assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); | |
| 196 | |
| 197 #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX | |
| 198 /* If recursive mutexes are not available, then we have to grow | |
| 199 ** our own. This implementation assumes that pthread_equal() | |
| 200 ** is atomic - that it cannot be deceived into thinking self | |
| 201 ** and p->owner are equal if p->owner changes between two values | |
| 202 ** that are not equal to self while the comparison is taking place. | |
| 203 ** This implementation also assumes a coherent cache - that | |
| 204 ** separate processes cannot read different values from the same | |
| 205 ** address at the same time. If either of these two conditions | |
| 206 ** are not met, then the mutexes will fail and problems will result. | |
| 207 */ | |
| 208 { | |
| 209 pthread_t self = pthread_self(); | |
| 210 if( p->nRef>0 && pthread_equal(p->owner, self) ){ | |
| 211 p->nRef++; | |
| 212 }else{ | |
| 213 pthread_mutex_lock(&p->mutex); | |
| 214 assert( p->nRef==0 ); | |
| 215 p->owner = self; | |
| 216 p->nRef = 1; | |
| 217 } | |
| 218 } | |
| 219 #else | |
| 220 /* Use the built-in recursive mutexes if they are available. | |
| 221 */ | |
| 222 pthread_mutex_lock(&p->mutex); | |
| 223 p->owner = pthread_self(); | |
| 224 p->nRef++; | |
| 225 #endif | |
| 226 | |
| 227 #ifdef SQLITE_DEBUG | |
| 228 if( p->trace ){ | |
| 229 printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 230 } | |
| 231 #endif | |
| 232 } | |
| 233 static int pthreadMutexTry(sqlite3_mutex *p){ | |
| 234 int rc; | |
| 235 assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); | |
| 236 | |
| 237 #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX | |
| 238 /* If recursive mutexes are not available, then we have to grow | |
| 239 ** our own. This implementation assumes that pthread_equal() | |
| 240 ** is atomic - that it cannot be deceived into thinking self | |
| 241 ** and p->owner are equal if p->owner changes between two values | |
| 242 ** that are not equal to self while the comparison is taking place. | |
| 243 ** This implementation also assumes a coherent cache - that | |
| 244 ** separate processes cannot read different values from the same | |
| 245 ** address at the same time. If either of these two conditions | |
| 246 ** are not met, then the mutexes will fail and problems will result. | |
| 247 */ | |
| 248 { | |
| 249 pthread_t self = pthread_self(); | |
| 250 if( p->nRef>0 && pthread_equal(p->owner, self) ){ | |
| 251 p->nRef++; | |
| 252 rc = SQLITE_OK; | |
| 253 }else if( pthread_mutex_trylock(&p->mutex)==0 ){ | |
| 254 assert( p->nRef==0 ); | |
| 255 p->owner = self; | |
| 256 p->nRef = 1; | |
| 257 rc = SQLITE_OK; | |
| 258 }else{ | |
| 259 rc = SQLITE_BUSY; | |
| 260 } | |
| 261 } | |
| 262 #else | |
| 263 /* Use the built-in recursive mutexes if they are available. | |
| 264 */ | |
| 265 if( pthread_mutex_trylock(&p->mutex)==0 ){ | |
| 266 p->owner = pthread_self(); | |
| 267 p->nRef++; | |
| 268 rc = SQLITE_OK; | |
| 269 }else{ | |
| 270 rc = SQLITE_BUSY; | |
| 271 } | |
| 272 #endif | |
| 273 | |
| 274 #ifdef SQLITE_DEBUG | |
| 275 if( rc==SQLITE_OK && p->trace ){ | |
| 276 printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 277 } | |
| 278 #endif | |
| 279 return rc; | |
| 280 } | |
| 281 | |
| 282 /* | |
| 283 ** The sqlite3_mutex_leave() routine exits a mutex that was | |
| 284 ** previously entered by the same thread. The behavior | |
| 285 ** is undefined if the mutex is not currently entered or | |
| 286 ** is not currently allocated. SQLite will never do either. | |
| 287 */ | |
| 288 static void pthreadMutexLeave(sqlite3_mutex *p){ | |
| 289 assert( pthreadMutexHeld(p) ); | |
| 290 p->nRef--; | |
| 291 assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); | |
| 292 | |
| 293 #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX | |
| 294 if( p->nRef==0 ){ | |
| 295 pthread_mutex_unlock(&p->mutex); | |
| 296 } | |
| 297 #else | |
| 298 pthread_mutex_unlock(&p->mutex); | |
| 299 #endif | |
| 300 | |
| 301 #ifdef SQLITE_DEBUG | |
| 302 if( p->trace ){ | |
| 303 printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); | |
| 304 } | |
| 305 #endif | |
| 306 } | |
| 307 | |
| 308 sqlite3_mutex_methods *sqlite3DefaultMutex(void){ | |
| 309 static sqlite3_mutex_methods sMutex = { | |
| 310 pthreadMutexInit, | |
| 311 pthreadMutexEnd, | |
| 312 pthreadMutexAlloc, | |
| 313 pthreadMutexFree, | |
| 314 pthreadMutexEnter, | |
| 315 pthreadMutexTry, | |
| 316 pthreadMutexLeave, | |
| 317 #ifdef SQLITE_DEBUG | |
| 318 pthreadMutexHeld, | |
| 319 pthreadMutexNotheld | |
| 320 #else | |
| 321 0, | |
| 322 0 | |
| 323 #endif | |
| 324 }; | |
| 325 | |
| 326 return &sMutex; | |
| 327 } | |
| 328 | |
| 329 #endif /* SQLITE_MUTEX_PTHREAD */ | |
| OLD | NEW |