xref: /sqlite-3.40.0/src/mutex_noop.c (revision 93de6538)
118472fa7Sdrh /*
218472fa7Sdrh ** 2008 October 07
318472fa7Sdrh **
418472fa7Sdrh ** The author disclaims copyright to this source code.  In place of
518472fa7Sdrh ** a legal notice, here is a blessing:
618472fa7Sdrh **
718472fa7Sdrh **    May you do good and not evil.
818472fa7Sdrh **    May you find forgiveness for yourself and forgive others.
918472fa7Sdrh **    May you share freely, never taking more than you give.
1018472fa7Sdrh **
1118472fa7Sdrh *************************************************************************
1218472fa7Sdrh ** This file contains the C functions that implement mutexes.
1318472fa7Sdrh **
1418472fa7Sdrh ** This implementation in this file does not provide any mutual
1518472fa7Sdrh ** exclusion and is thus suitable for use only in applications
1618472fa7Sdrh ** that use SQLite in a single thread.  The routines defined
1718472fa7Sdrh ** here are place-holders.  Applications can substitute working
1818472fa7Sdrh ** mutex routines at start-time using the
1918472fa7Sdrh **
2018472fa7Sdrh **     sqlite3_config(SQLITE_CONFIG_MUTEX,...)
2118472fa7Sdrh **
2218472fa7Sdrh ** interface.
2318472fa7Sdrh **
2418472fa7Sdrh ** If compiled with SQLITE_DEBUG, then additional logic is inserted
2518472fa7Sdrh ** that does error checking on mutexes to make sure they are being
2618472fa7Sdrh ** called correctly.
2718472fa7Sdrh */
2818472fa7Sdrh #include "sqliteInt.h"
2918472fa7Sdrh 
30e874d9edSdrh #ifndef SQLITE_MUTEX_OMIT
3118472fa7Sdrh 
3292d76523Sdrh #ifndef SQLITE_DEBUG
3318472fa7Sdrh /*
3418472fa7Sdrh ** Stub routines for all mutex methods.
3518472fa7Sdrh **
3618472fa7Sdrh ** This routines provide no mutual exclusion or error checking.
3718472fa7Sdrh */
noopMutexInit(void)3818472fa7Sdrh static int noopMutexInit(void){ return SQLITE_OK; }
noopMutexEnd(void)3918472fa7Sdrh static int noopMutexEnd(void){ return SQLITE_OK; }
noopMutexAlloc(int id)40ff82894fSdrh static sqlite3_mutex *noopMutexAlloc(int id){
41ff82894fSdrh   UNUSED_PARAMETER(id);
42ff82894fSdrh   return (sqlite3_mutex*)8;
43ff82894fSdrh }
noopMutexFree(sqlite3_mutex * p)44ff82894fSdrh static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
noopMutexEnter(sqlite3_mutex * p)45ff82894fSdrh static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
noopMutexTry(sqlite3_mutex * p)46ff82894fSdrh static int noopMutexTry(sqlite3_mutex *p){
47ff82894fSdrh   UNUSED_PARAMETER(p);
48ff82894fSdrh   return SQLITE_OK;
49ff82894fSdrh }
noopMutexLeave(sqlite3_mutex * p)50ff82894fSdrh static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; }
5118472fa7Sdrh 
sqlite3NoopMutex(void)52558814f8Sdan sqlite3_mutex_methods const *sqlite3NoopMutex(void){
53558814f8Sdan   static const sqlite3_mutex_methods sMutex = {
5418472fa7Sdrh     noopMutexInit,
5518472fa7Sdrh     noopMutexEnd,
5618472fa7Sdrh     noopMutexAlloc,
5718472fa7Sdrh     noopMutexFree,
5818472fa7Sdrh     noopMutexEnter,
5918472fa7Sdrh     noopMutexTry,
6018472fa7Sdrh     noopMutexLeave,
6118472fa7Sdrh 
62e404de05Sdrh     0,
63e404de05Sdrh     0,
6418472fa7Sdrh   };
6518472fa7Sdrh 
6618472fa7Sdrh   return &sMutex;
6718472fa7Sdrh }
6892d76523Sdrh #endif /* !SQLITE_DEBUG */
6918472fa7Sdrh 
7092d76523Sdrh #ifdef SQLITE_DEBUG
7118472fa7Sdrh /*
7218472fa7Sdrh ** In this implementation, error checking is provided for testing
7318472fa7Sdrh ** and debugging purposes.  The mutexes still do not provide any
7418472fa7Sdrh ** mutual exclusion.
7518472fa7Sdrh */
7618472fa7Sdrh 
7718472fa7Sdrh /*
7818472fa7Sdrh ** The mutex object
7918472fa7Sdrh */
80fc34ad29Sdrh typedef struct sqlite3_debug_mutex {
8118472fa7Sdrh   int id;     /* The mutex type */
8218472fa7Sdrh   int cnt;    /* Number of entries without a matching leave */
83fc34ad29Sdrh } sqlite3_debug_mutex;
8418472fa7Sdrh 
8518472fa7Sdrh /*
8618472fa7Sdrh ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
8718472fa7Sdrh ** intended for use inside assert() statements.
8818472fa7Sdrh */
debugMutexHeld(sqlite3_mutex * pX)89fc34ad29Sdrh static int debugMutexHeld(sqlite3_mutex *pX){
90fc34ad29Sdrh   sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
9118472fa7Sdrh   return p==0 || p->cnt>0;
9218472fa7Sdrh }
debugMutexNotheld(sqlite3_mutex * pX)93fc34ad29Sdrh static int debugMutexNotheld(sqlite3_mutex *pX){
94fc34ad29Sdrh   sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
9518472fa7Sdrh   return p==0 || p->cnt==0;
9618472fa7Sdrh }
9718472fa7Sdrh 
9818472fa7Sdrh /*
9918472fa7Sdrh ** Initialize and deinitialize the mutex subsystem.
10018472fa7Sdrh */
debugMutexInit(void)10118472fa7Sdrh static int debugMutexInit(void){ return SQLITE_OK; }
debugMutexEnd(void)10218472fa7Sdrh static int debugMutexEnd(void){ return SQLITE_OK; }
10318472fa7Sdrh 
10418472fa7Sdrh /*
10518472fa7Sdrh ** The sqlite3_mutex_alloc() routine allocates a new
10618472fa7Sdrh ** mutex and returns a pointer to it.  If it returns NULL
10718472fa7Sdrh ** that means that a mutex could not be allocated.
10818472fa7Sdrh */
debugMutexAlloc(int id)10918472fa7Sdrh static sqlite3_mutex *debugMutexAlloc(int id){
110*93de6538Smistachkin   static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_VFS3 - 1];
111fc34ad29Sdrh   sqlite3_debug_mutex *pNew = 0;
11218472fa7Sdrh   switch( id ){
11318472fa7Sdrh     case SQLITE_MUTEX_FAST:
11418472fa7Sdrh     case SQLITE_MUTEX_RECURSIVE: {
11518472fa7Sdrh       pNew = sqlite3Malloc(sizeof(*pNew));
11618472fa7Sdrh       if( pNew ){
11718472fa7Sdrh         pNew->id = id;
11818472fa7Sdrh         pNew->cnt = 0;
11918472fa7Sdrh       }
12018472fa7Sdrh       break;
12118472fa7Sdrh     }
12218472fa7Sdrh     default: {
12396c707a3Sdrh #ifdef SQLITE_ENABLE_API_ARMOR
12496c707a3Sdrh       if( id-2<0 || id-2>=ArraySize(aStatic) ){
12596c707a3Sdrh         (void)SQLITE_MISUSE_BKPT;
12696c707a3Sdrh         return 0;
12796c707a3Sdrh       }
12896c707a3Sdrh #endif
12918472fa7Sdrh       pNew = &aStatic[id-2];
13018472fa7Sdrh       pNew->id = id;
13118472fa7Sdrh       break;
13218472fa7Sdrh     }
13318472fa7Sdrh   }
134fc34ad29Sdrh   return (sqlite3_mutex*)pNew;
13518472fa7Sdrh }
13618472fa7Sdrh 
13718472fa7Sdrh /*
13818472fa7Sdrh ** This routine deallocates a previously allocated mutex.
13918472fa7Sdrh */
debugMutexFree(sqlite3_mutex * pX)140fc34ad29Sdrh static void debugMutexFree(sqlite3_mutex *pX){
141fc34ad29Sdrh   sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
14218472fa7Sdrh   assert( p->cnt==0 );
14396c707a3Sdrh   if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){
14418472fa7Sdrh     sqlite3_free(p);
14596c707a3Sdrh   }else{
14696c707a3Sdrh #ifdef SQLITE_ENABLE_API_ARMOR
14796c707a3Sdrh     (void)SQLITE_MISUSE_BKPT;
14896c707a3Sdrh #endif
14996c707a3Sdrh   }
15018472fa7Sdrh }
15118472fa7Sdrh 
15218472fa7Sdrh /*
15318472fa7Sdrh ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
15418472fa7Sdrh ** to enter a mutex.  If another thread is already within the mutex,
15518472fa7Sdrh ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
15618472fa7Sdrh ** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
15718472fa7Sdrh ** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
15818472fa7Sdrh ** be entered multiple times by the same thread.  In such cases the,
15918472fa7Sdrh ** mutex must be exited an equal number of times before another thread
16018472fa7Sdrh ** can enter.  If the same thread tries to enter any other kind of mutex
16118472fa7Sdrh ** more than once, the behavior is undefined.
16218472fa7Sdrh */
debugMutexEnter(sqlite3_mutex * pX)163fc34ad29Sdrh static void debugMutexEnter(sqlite3_mutex *pX){
164fc34ad29Sdrh   sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
165fc34ad29Sdrh   assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
16618472fa7Sdrh   p->cnt++;
16718472fa7Sdrh }
debugMutexTry(sqlite3_mutex * pX)168fc34ad29Sdrh static int debugMutexTry(sqlite3_mutex *pX){
169fc34ad29Sdrh   sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
170fc34ad29Sdrh   assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
17118472fa7Sdrh   p->cnt++;
17218472fa7Sdrh   return SQLITE_OK;
17318472fa7Sdrh }
17418472fa7Sdrh 
17518472fa7Sdrh /*
17618472fa7Sdrh ** The sqlite3_mutex_leave() routine exits a mutex that was
17718472fa7Sdrh ** previously entered by the same thread.  The behavior
17818472fa7Sdrh ** is undefined if the mutex is not currently entered or
17918472fa7Sdrh ** is not currently allocated.  SQLite will never do either.
18018472fa7Sdrh */
debugMutexLeave(sqlite3_mutex * pX)181fc34ad29Sdrh static void debugMutexLeave(sqlite3_mutex *pX){
182fc34ad29Sdrh   sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
183fc34ad29Sdrh   assert( debugMutexHeld(pX) );
18418472fa7Sdrh   p->cnt--;
185fc34ad29Sdrh   assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) );
18618472fa7Sdrh }
18718472fa7Sdrh 
sqlite3NoopMutex(void)188558814f8Sdan sqlite3_mutex_methods const *sqlite3NoopMutex(void){
189558814f8Sdan   static const sqlite3_mutex_methods sMutex = {
19018472fa7Sdrh     debugMutexInit,
19118472fa7Sdrh     debugMutexEnd,
19218472fa7Sdrh     debugMutexAlloc,
19318472fa7Sdrh     debugMutexFree,
19418472fa7Sdrh     debugMutexEnter,
19518472fa7Sdrh     debugMutexTry,
19618472fa7Sdrh     debugMutexLeave,
19718472fa7Sdrh 
19818472fa7Sdrh     debugMutexHeld,
19918472fa7Sdrh     debugMutexNotheld
20018472fa7Sdrh   };
20118472fa7Sdrh 
20218472fa7Sdrh   return &sMutex;
20318472fa7Sdrh }
20492d76523Sdrh #endif /* SQLITE_DEBUG */
20592d76523Sdrh 
20692d76523Sdrh /*
20792d76523Sdrh ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation
20892d76523Sdrh ** is used regardless of the run-time threadsafety setting.
20992d76523Sdrh */
21092d76523Sdrh #ifdef SQLITE_MUTEX_NOOP
sqlite3DefaultMutex(void)211558814f8Sdan sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
2127750ab48Sdrh   return sqlite3NoopMutex();
21392d76523Sdrh }
214e4c88c0cSdrh #endif /* defined(SQLITE_MUTEX_NOOP) */
215e4c88c0cSdrh #endif /* !defined(SQLITE_MUTEX_OMIT) */
216