aboutsummaryrefslogtreecommitdiff
path: root/src/mutex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mutex.c')
-rw-r--r--src/mutex.c177
1 files changed, 146 insertions, 31 deletions
diff --git a/src/mutex.c b/src/mutex.c
index 23c0422f6..3eded653b 100644
--- a/src/mutex.c
+++ b/src/mutex.c
@@ -19,10 +19,115 @@
** implementation is suitable for testing.
** debugging purposes
**
-** $Id: mutex.c,v 1.20 2008/06/15 02:51:48 drh Exp $
+** $Id: mutex.c,v 1.21 2008/06/17 17:21:18 danielk1977 Exp $
*/
#include "sqliteInt.h"
+#ifndef SQLITE_MUTEX_NOOP
+/*
+** Initialize the mutex system.
+*/
+int sqlite3_mutex_init(void){
+ int rc;
+ if( !sqlite3Config.mutex.xMutexAlloc ){
+ sqlite3_mutex_methods *p = sqlite3DefaultMutex();
+ sqlite3_mutex *pMaster;
+
+ rc = p->xMutexInit();
+ if( rc==SQLITE_OK ){
+ pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+ p->xMutexEnter(pMaster);
+ assert( sqlite3Config.mutex.xMutexAlloc==0
+ || sqlite3Config.mutex.xMutexAlloc==p->xMutexAlloc
+ );
+ if( !sqlite3Config.mutex.xMutexAlloc ){
+ sqlite3Config.mutex = *p;
+ }
+ p->xMutexLeave(pMaster);
+ }
+
+ }else{
+ rc = sqlite3Config.mutex.xMutexInit();
+ }
+
+ return rc;
+}
+
+/*
+** Shutdown the mutex system. This call frees resources allocated by
+** sqlite3_mutex_init().
+*/
+int sqlite3_mutex_end(void){
+ int rc = SQLITE_OK;
+ rc = sqlite3Config.mutex.xMutexEnd();
+ return rc;
+}
+
+/*
+** Retrieve a pointer to a static mutex or allocate a new dynamic one.
+*/
+sqlite3_mutex *sqlite3_mutex_alloc(int id){
+ return sqlite3Config.mutex.xMutexAlloc(id);
+}
+
+/*
+** Free a dynamic mutex.
+*/
+void sqlite3_mutex_free(sqlite3_mutex *p){
+ if( p ){
+ sqlite3Config.mutex.xMutexFree(p);
+ }
+}
+
+/*
+** Obtain the mutex p. If some other thread already has the mutex, block
+** until it can be obtained.
+*/
+void sqlite3_mutex_enter(sqlite3_mutex *p){
+ if( p ){
+ sqlite3Config.mutex.xMutexEnter(p);
+ }
+}
+
+/*
+** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
+** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
+*/
+int sqlite3_mutex_try(sqlite3_mutex *p){
+ int rc = SQLITE_OK;
+ if( p ){
+ return sqlite3Config.mutex.xMutexTry(p);
+ }
+ return rc;
+}
+
+/*
+** 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. If a NULL pointer is passed as an argument
+** this function is a no-op.
+*/
+void sqlite3_mutex_leave(sqlite3_mutex *p){
+ if( p ){
+ sqlite3Config.mutex.xMutexLeave(p);
+ }
+}
+
+#ifndef NDEBUG
+/*
+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
+** intended for use inside assert() statements.
+*/
+int sqlite3_mutex_held(sqlite3_mutex *p){
+ return p==0 || sqlite3Config.mutex.xMutexHeld(p);
+}
+int sqlite3_mutex_notheld(sqlite3_mutex *p){
+ return p==0 || sqlite3Config.mutex.xMutexNotheld(p);
+}
+#endif
+
+#endif
+
#ifdef SQLITE_MUTEX_NOOP_DEBUG
/*
** In this implementation, mutexes do not provide any mutual exclusion.
@@ -39,17 +144,28 @@ struct sqlite3_mutex {
};
/*
+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
+** intended for use inside assert() statements.
+*/
+static int noopMutexHeld(sqlite3_mutex *p){
+ return p==0 || p->cnt>0;
+}
+static int noopMutexNotheld(sqlite3_mutex *p){
+ return p==0 || p->cnt==0;
+}
+
+/*
** Initialize and deinitialize the mutex subsystem.
*/
-int sqlite3_mutex_init(void){ return SQLITE_OK; }
-int sqlite3_mutex_end(void){ return SQLITE_OK; }
+static int noopMutexInit(void){ return SQLITE_OK; }
+static int noopMutexEnd(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.
*/
-sqlite3_mutex *sqlite3_mutex_alloc(int id){
+static sqlite3_mutex *noopMutexAlloc(int id){
static sqlite3_mutex aStatic[6];
sqlite3_mutex *pNew = 0;
switch( id ){
@@ -76,8 +192,7 @@ sqlite3_mutex *sqlite3_mutex_alloc(int id){
/*
** This routine deallocates a previously allocated mutex.
*/
-void sqlite3_mutex_free(sqlite3_mutex *p){
- if( p==0 ) return;
+static void noopMutexFree(sqlite3_mutex *p){
assert( p->cnt==0 );
assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
sqlite3_free(p);
@@ -94,17 +209,13 @@ void sqlite3_mutex_free(sqlite3_mutex *p){
** can enter. If the same thread tries to enter any other kind of mutex
** more than once, the behavior is undefined.
*/
-void sqlite3_mutex_enter(sqlite3_mutex *p){
- if( p ){
- assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
- p->cnt++;
- }
+static void noopMutexEnter(sqlite3_mutex *p){
+ assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) );
+ p->cnt++;
}
-int sqlite3_mutex_try(sqlite3_mutex *p){
- if( p ){
- assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
- p->cnt++;
- }
+static int noopMutexTry(sqlite3_mutex *p){
+ assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) );
+ p->cnt++;
return SQLITE_OK;
}
@@ -114,22 +225,26 @@ int sqlite3_mutex_try(sqlite3_mutex *p){
** is undefined if the mutex is not currently entered or
** is not currently allocated. SQLite will never do either.
*/
-void sqlite3_mutex_leave(sqlite3_mutex *p){
- if( p ){
- assert( sqlite3_mutex_held(p) );
- p->cnt--;
- assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
- }
+static void noopMutexLeave(sqlite3_mutex *p){
+ assert( sqlite3_mutex_held(p) );
+ p->cnt--;
+ assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
}
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use inside assert() statements.
-*/
-int sqlite3_mutex_held(sqlite3_mutex *p){
- return p==0 || p->cnt>0;
-}
-int sqlite3_mutex_notheld(sqlite3_mutex *p){
- return p==0 || p->cnt==0;
+sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+ static sqlite3_mutex_methods sMutex = {
+ noopMutexInit,
+ noopMutexAlloc,
+ noopMutexFree,
+ noopMutexEnter,
+ noopMutexTry,
+ noopMutexLeave,
+ noopMutexEnd,
+
+ noopMutexHeld,
+ noopMutexNotheld
+ };
+
+ return &sMutex;
}
#endif /* SQLITE_MUTEX_NOOP_DEBUG */