123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- /*
- ** 2008 October 07
- **
- ** The author disclaims copyright to this source code. In place of
- ** a legal notice, here is a blessing:
- **
- ** May you do good and not evil.
- ** May you find forgiveness for yourself and forgive others.
- ** May you share freely, never taking more than you give.
- **
- *************************************************************************
- ** This file contains the C functions that implement mutexes.
- **
- ** This implementation in this file does not provide any mutual
- ** exclusion and is thus suitable for use only in applications
- ** that use SQLite in a single thread. The routines defined
- ** here are place-holders. Applications can substitute working
- ** mutex routines at start-time using the
- **
- ** sqlite3_config(SQLITE_CONFIG_MUTEX,...)
- **
- ** interface.
- **
- ** If compiled with SQLITE_DEBUG, then additional logic is inserted
- ** that does error checking on mutexes to make sure they are being
- ** called correctly.
- */
- #include "sqliteInt.h"
- #ifndef SQLITE_MUTEX_OMIT
- #ifndef SQLITE_DEBUG
- /*
- ** Stub routines for all mutex methods.
- **
- ** This routines provide no mutual exclusion or error checking.
- */
- static int noopMutexInit(void){ return SQLITE_OK; }
- static int noopMutexEnd(void){ return SQLITE_OK; }
- static sqlite3_mutex *noopMutexAlloc(int id){
- UNUSED_PARAMETER(id);
- return (sqlite3_mutex*)8;
- }
- static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
- static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
- static int noopMutexTry(sqlite3_mutex *p){
- UNUSED_PARAMETER(p);
- return SQLITE_OK;
- }
- static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
- sqlite3_mutex_methods const *sqlite3NoopMutex(void){
- static const sqlite3_mutex_methods sMutex = {
- noopMutexInit,
- noopMutexEnd,
- noopMutexAlloc,
- noopMutexFree,
- noopMutexEnter,
- noopMutexTry,
- noopMutexLeave,
- 0,
- 0,
- };
- return &sMutex;
- }
- #endif /* !SQLITE_DEBUG */
- #ifdef SQLITE_DEBUG
- /*
- ** In this implementation, error checking is provided for testing
- ** and debugging purposes. The mutexes still do not provide any
- ** mutual exclusion.
- */
- /*
- ** The mutex object
- */
- typedef struct sqlite3_debug_mutex {
- int id; /* The mutex type */
- int cnt; /* Number of entries without a matching leave */
- } sqlite3_debug_mutex;
- /*
- ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
- ** intended for use inside assert() statements.
- */
- static int debugMutexHeld(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- return p==0 || p->cnt>0;
- }
- static int debugMutexNotheld(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- return p==0 || p->cnt==0;
- }
- /*
- ** Initialize and deinitialize the mutex subsystem.
- */
- static int debugMutexInit(void){ return SQLITE_OK; }
- static int debugMutexEnd(void){ return SQLITE_OK; }
- /*
- ** The sqlite3_mutex_alloc() routine allocates a new
- ** mutex and returns a pointer to it. If it returns NULL
- ** that means that a mutex could not be allocated.
- */
- static sqlite3_mutex *debugMutexAlloc(int id){
- static sqlite3_debug_mutex aStatic[6];
- sqlite3_debug_mutex *pNew = 0;
- switch( id ){
- case SQLITE_MUTEX_FAST:
- case SQLITE_MUTEX_RECURSIVE: {
- pNew = sqlite3Malloc(sizeof(*pNew));
- if( pNew ){
- pNew->id = id;
- pNew->cnt = 0;
- }
- break;
- }
- default: {
- assert( id-2 >= 0 );
- assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
- pNew = &aStatic[id-2];
- pNew->id = id;
- break;
- }
- }
- return (sqlite3_mutex*)pNew;
- }
- /*
- ** This routine deallocates a previously allocated mutex.
- */
- static void debugMutexFree(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- assert( p->cnt==0 );
- assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
- sqlite3_free(p);
- }
- /*
- ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
- ** to enter a mutex. If another thread is already within the mutex,
- ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
- ** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK
- ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can
- ** be entered multiple times by the same thread. In such cases the,
- ** mutex must be exited an equal number of times before another thread
- ** can enter. If the same thread tries to enter any other kind of mutex
- ** more than once, the behavior is undefined.
- */
- static void debugMutexEnter(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
- p->cnt++;
- }
- static int debugMutexTry(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
- p->cnt++;
- return SQLITE_OK;
- }
- /*
- ** The sqlite3_mutex_leave() routine exits a mutex that was
- ** previously entered by the same thread. The behavior
- ** is undefined if the mutex is not currently entered or
- ** is not currently allocated. SQLite will never do either.
- */
- static void debugMutexLeave(sqlite3_mutex *pX){
- sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
- assert( debugMutexHeld(pX) );
- p->cnt--;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
- }
- sqlite3_mutex_methods const *sqlite3NoopMutex(void){
- static const sqlite3_mutex_methods sMutex = {
- debugMutexInit,
- debugMutexEnd,
- debugMutexAlloc,
- debugMutexFree,
- debugMutexEnter,
- debugMutexTry,
- debugMutexLeave,
- debugMutexHeld,
- debugMutexNotheld
- };
- return &sMutex;
- }
- #endif /* SQLITE_DEBUG */
- /*
- ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
- ** is used regardless of the run-time threadsafety setting.
- */
- #ifdef SQLITE_MUTEX_NOOP
- sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
- return sqlite3NoopMutex();
- }
- #endif /* defined(SQLITE_MUTEX_NOOP) */
- #endif /* !defined(SQLITE_MUTEX_OMIT) */
|