]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add an implementation of recursive mutexes for unix systems that
authordrh <drh@noemail.net>
Wed, 28 Nov 2007 00:51:34 +0000 (00:51 +0000)
committerdrh <drh@noemail.net>
Wed, 28 Nov 2007 00:51:34 +0000 (00:51 +0000)
lack pthreads recursive mutexes (ex: Solaris 2.6).  Modern unix
systems continue to use the recursive mutexes provided by pthreads. (CVS 4573)

FossilOrigin-Name: f366a776c1b2dda42b4f10fdb8be66029165d084

manifest
manifest.uuid
src/mutex_unix.c

index e12ef3f4fb3c219ea4bee87d54929e566d1a0511..ab0c62c0ff804afae44ba4e725bea3a97fa803d2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\stest\scases\sto\sverify\sthat\sthe\sfile\sformat\sis\spreserved\sacross\nVACUUM.\s\sTicket\s#2804.\s(CVS\s4572)
-D 2007-11-27T23:36:59
+C Add\san\simplementation\sof\srecursive\smutexes\sfor\sunix\ssystems\sthat\nlack\spthreads\srecursive\smutexes\s(ex:\sSolaris\s2.6).\s\sModern\sunix\nsystems\scontinue\sto\suse\sthe\srecursive\smutexes\sprovided\sby\spthreads.\s(CVS\s4573)
+D 2007-11-28T00:51:35
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 35396fd58890420b29edcf27b6c0e2d054862a6b
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -110,7 +110,7 @@ F src/mem3.c a9857cf92c9e4c889184b2cf1ca1839c801fc942
 F src/mutex.c 3259f62c2429967aee6dc112117a6d2f499ef061
 F src/mutex.h 079fa6fe9da18ceb89e79012c010594c6672addb
 F src/mutex_os2.c 7fe4773e98ed74a63b2e54fc557929eb155f6269
-F src/mutex_unix.c ff77650261a245035b79c5c8a174f4e05d3cae8a
+F src/mutex_unix.c 69e996b7c26bb50619c79c173dbba21658b65d2f
 F src/mutex_w32.c 6e197765f283815496193e78e9548b5d0e53b68e
 F src/os.c 8360932f1450b2b45edb608a3b184b031f7d00cc
 F src/os.h b75506ab40d222300f38023acb56fe08df5ffe33
@@ -593,7 +593,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 07f7dde8a636aa05b917daa6b248c6f98654aab8
-R 3c60f3c335bef3e1e830e41efbe0e631
+P 57400f50c600a59b56ba6eadfdc740235c194cd6
+R 8dde434a6ff58760125bd11cf8e8307f
 U drh
-Z 6de36b7ac21f25e08677d9c3cdbdc203
+Z d10de234723bedb4b88498db89c73bc6
index 8988fefbdb84113dfe1e8236dff694e620d9b526..2649449ab29f6bf8cda82f8a6a9df9beac537277 100644 (file)
@@ -1 +1 @@
-57400f50c600a59b56ba6eadfdc740235c194cd6
\ No newline at end of file
+f366a776c1b2dda42b4f10fdb8be66029165d084
\ No newline at end of file
index ff088fb53124f0824e219c5b351e029389ea29c0..20a4e0ea741e7d80b894dbdc94d390aa4875f495 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains the C functions that implement mutexes for pthreads
 **
-** $Id: mutex_unix.c,v 1.2 2007/08/28 22:24:35 drh Exp $
+** $Id: mutex_unix.c,v 1.3 2007/11/28 00:51:35 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -26,6 +26,7 @@
 
 #include <pthread.h>
 
+
 /*
 ** Each recursive mutex is an instance of the following structure.
 */
@@ -93,11 +94,18 @@ sqlite3_mutex *sqlite3_mutex_alloc(int iType){
     case SQLITE_MUTEX_RECURSIVE: {
       p = sqlite3MallocZero( sizeof(*p) );
       if( p ){
+#ifdef PTHREAD_MUTEX_RECURSIVE
+        /* Use a recursive mutex if it is available */
         pthread_mutexattr_t recursiveAttr;
         pthread_mutexattr_init(&recursiveAttr);
         pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
         pthread_mutex_init(&p->mutex, &recursiveAttr);
         pthread_mutexattr_destroy(&recursiveAttr);
+#else
+        /* If recursive mutexes are not available, we will have to
+        ** build our own.  See below. */
+        pthread_mutex_init(&p->mutex, 0);
+#endif
         p->id = iType;
       }
       break;
@@ -149,9 +157,34 @@ void sqlite3_mutex_free(sqlite3_mutex *p){
 void sqlite3_mutex_enter(sqlite3_mutex *p){
   assert( p );
   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+
+#ifdef PTHREAD_MUTEX_RECURSIVE
+  /* Use the built-in recursive mutexes if they are available.
+  ** That they are not available on all systems.
+  */
   pthread_mutex_lock(&p->mutex);
   p->owner = pthread_self();
   p->nRef++;
+#else
+  /* If recursive mutexes are not available, then we have to grow
+  ** our own.  This implementation assumes that pthread_equal()
+  ** is atomic - that it cannot be deceived into thinking self
+  ** and p->owner are equal if p->owner changes between two values
+  ** that are not equal to self while the comparison is taking place.
+  */
+  {
+    pthread_t self = pthread_self();
+    if( p->nRef>0 && pthread_equal(p->owner, self) ){
+      p->nRef++;
+    }else{
+      pthread_mutex_lock(&p->mutex);
+      assert( p->nRef==0 );
+      p->owner = self;
+      p->nRef = 1;
+    }
+  }
+#endif
+
 #ifdef SQLITE_DEBUG
   if( p->trace ){
     printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
@@ -162,18 +195,46 @@ int sqlite3_mutex_try(sqlite3_mutex *p){
   int rc;
   assert( p );
   assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+
+#ifdef PTHREAD_MUTEX_RECURSIVE
+  /* Use the built-in recursive mutexes if they are available.
+  ** That they are not available on all systems.
+  */
   if( pthread_mutex_trylock(&p->mutex)==0 ){
     p->owner = pthread_self();
     p->nRef++;
     rc = SQLITE_OK;
-#ifdef SQLITE_DEBUG
-    if( p->trace ){
-      printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
-    }
-#endif
   }else{
     rc = SQLITE_BUSY;
   }
+#else
+  /* If recursive mutexes are not available, then we have to grow
+  ** our own.  This implementation assumes that pthread_equal()
+  ** is atomic - that it cannot be deceived into thinking self
+  ** and p->owner are equal if p->owner changes between two values
+  ** that are not equal to self while the comparison is taking place.
+  */
+  {
+    pthread_t self = pthread_self();
+    if( p->nRef>0 && pthread_equal(p->owner, self) ){
+      p->nRef++;
+      rc = SQLITE_OK;
+    }else if( pthread_mutex_lock(&p->mutex)==0 ){
+      assert( p->nRef==0 );
+      p->owner = self;
+      p->nRef = 1;
+      rc = SQLITE_OK;
+    }else{
+      rc = SQLITE_BUSY;
+    }
+  }
+#endif
+
+#ifdef SQLITE_DEBUG
+  if( rc==SQLITE_OK && p->trace ){
+    printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
+  }
+#endif
   return rc;
 }
 
@@ -188,12 +249,20 @@ void sqlite3_mutex_leave(sqlite3_mutex *p){
   assert( sqlite3_mutex_held(p) );
   p->nRef--;
   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
+
+#ifdef PTHREAD_RECURSIVE_MUTEX
+  pthread_mutex_unlock(&p->mutex);
+#else
+  if( p->nRef==0 ){
+    pthread_mutex_unlock(&p->mutex);
+  }
+#endif
+
 #ifdef SQLITE_DEBUG
   if( p->trace ){
     printf("leave mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef);
   }
 #endif
-  pthread_mutex_unlock(&p->mutex);
 }
 
 /*