aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/os_unix.c')
-rw-r--r--src/os_unix.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index 7573c9175..602c02386 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -1670,13 +1670,30 @@ int sqlite3UnixSleep(int ms){
}
/*
-** Static variables used for thread synchronization
+** Static variables used for thread synchronization.
+**
+** inMutex the nesting depth of the recursive mutex. The thread
+** holding mutexMain can read this variable at any time.
+** But is must hold mutexAux to change this variable. Other
+** threads must hold mutexAux to read the variable.
+**
+** mutexOwner The thread id of the thread holding mutexMain. Same
+** access rules as for inMutex.
+**
+** mutexOwnerValid True if the value in mutexOwner is valid.
+**
+** mutexMain The main mutex. Hold this mutex in order to get exclusive
+** access to SQLite data structures.
+**
+** mutexAux An auxiliary mutex needed to access variables defined above.
+**
*/
static int inMutex = 0;
#ifdef SQLITE_UNIX_THREADS
-static pthread_t mutexOwner;
-static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t mutexOwner; /* Thread holding the mutex */
+static int mutexOwnerValid = 0; /* True if mutexOwner is valid */
+static pthread_mutex_t mutexMain = PTHREAD_MUTEX_INITIALIZER; /* The mutex */
+static pthread_mutex_t mutexAux = PTHREAD_MUTEX_INITIALIZER; /* Aux mutex */
#endif
/*
@@ -1691,25 +1708,34 @@ static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
*/
void sqlite3UnixEnterMutex(){
#ifdef SQLITE_UNIX_THREADS
- pthread_mutex_lock(&mutex1);
- if( inMutex==0 ){
- pthread_mutex_lock(&mutex2);
+ pthread_mutex_lock(&mutexAux);
+ if( !mutexOwnerValid || !pthread_equal(mutexOwner, pthread_self()) ){
+ pthread_mutex_unlock(&mutexAux);
+ pthread_mutex_lock(&mutexMain);
+ assert( inMutex==0 );
+ assert( !mutexOwnerValid );
+ pthread_mutex_lock(&mutexAux);
mutexOwner = pthread_self();
+ mutexOwnerValid = 1;
}
- pthread_mutex_unlock(&mutex1);
-#endif
inMutex++;
+ pthread_mutex_unlock(&mutexAux);
+#else
+ inMutex++
+#endif
}
void sqlite3UnixLeaveMutex(){
assert( inMutex>0 );
#ifdef SQLITE_UNIX_THREADS
- assert( pthread_equal(mutexOwner, pthread_self()) );
- pthread_mutex_lock(&mutex1);
+ pthread_mutex_lock(&mutexAux);
inMutex--;
+ assert( pthread_equal(mutexOwner, pthread_self()) );
if( inMutex==0 ){
- pthread_mutex_unlock(&mutex2);
+ assert( mutexOwnerValid );
+ mutexOwnerValid = 0;
+ pthread_mutex_unlock(&mutexMain);
}
- pthread_mutex_unlock(&mutex1);
+ pthread_mutex_unlock(&mutexAux);
#else
inMutex--;
#endif
@@ -1718,14 +1744,17 @@ void sqlite3UnixLeaveMutex(){
/*
** Return TRUE if the mutex is currently held.
**
-** If the thisThreadOnly parameter is true, return true only if the
+** If the thisThrd parameter is true, return true only if the
** calling thread holds the mutex. If the parameter is false, return
** true if any thread holds the mutex.
*/
-int sqlite3UnixInMutex(int thisThreadOnly){
+int sqlite3UnixInMutex(int thisThrd){
#ifdef SQLITE_UNIX_THREADS
- return inMutex>0 &&
- (thisThreadOnly==0 || pthread_equal(mutexOwner, pthread_self()));
+ int rc;
+ pthread_mutex_lock(&mutexAux);
+ rc = inMutex>0 && (thisThrd==0 || pthread_equal(mutexOwner,pthread_self()));
+ pthread_mutex_unlock(&mutexAux);
+ return rc;
#else
return inMutex>0;
#endif