From 058897a92e22baf055595ab4239972cf5bcd926d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 25 Aug 2007 14:39:45 +0000 Subject: [PATCH] Use recursive mutexes in pthreads. If the pthreads implementation does not support recursive mutexes, then you cannot compile SQLite with SQLITE_THREADSAFE=1. Ticket #2588. (CVS 4297) FossilOrigin-Name: 1668284d151e78d16b0d83bf55dfd9d349a452a7 --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/mutex.c | 64 ++++++++++++++++++++++++++++++------------------- src/sqliteInt.h | 3 ++- 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 1408c67ea4..bc4bc882b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\srest\sof\sthe\smalloc\sfailure\stest\sscripts\sto\suse\sthe\snew\sinterface.\s(CVS\s4296) -D 2007-08-25T13:37:49 +C Use\srecursive\smutexes\sin\spthreads.\s\sIf\sthe\spthreads\simplementation\sdoes\snot\nsupport\srecursive\smutexes,\sthen\syou\scannot\scompile\sSQLite\swith\nSQLITE_THREADSAFE=1.\s\sTicket\s#2588.\s(CVS\s4297) +D 2007-08-25T14:39:46 F Makefile.in 938f2769921fa1b30c633548f153804021eb1512 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -103,7 +103,7 @@ F src/malloc.c d4282f50964ab1ca31f504c97b7cf2fdb4d4195d F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217 F src/mem1.c afe2fbf6d7e8247c6c9f69c1481358b1cad60c08 F src/mem2.c 1a2ca756a285b5365d667841508cc1f98938b8d8 -F src/mutex.c 2337e3105ee274be77b743e43ffb053a1bca89e2 +F src/mutex.c 81e4c57389ba5851b6bc78c704508f0a1d8659b8 F src/os.c a8ed3c495161475dbce255f7003144144fb425f1 F src/os.h 2bfbbad126a775e4d8c7d59eb4d9585a5fd7dfb5 F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c @@ -127,7 +127,7 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb F src/sqlite.h.in 22397464e1026437a755489c3eeb459346ae8749 F src/sqlite3ext.h 9a26028378c288af500d8b94ed079666fed5806b -F src/sqliteInt.h ea7a14a33c0a03479d2d98ce9ac83fe5e7f4bb55 +F src/sqliteInt.h 13c908f5f156a192fcd247f993ac513bfaf81f53 F src/sqliteLimit.h 1bcbbdfa856f8b71b561abb31edb864b0eca1d12 F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008 F src/tclsqlite.c d76af53f45c9e9f7f7d39531fa4c7bee7d0adad6 @@ -561,7 +561,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P e5ec17071720a973bbd213a8b23038d3aff25315 -R a2a459ce4d89b3260dd62868dc774bc5 -U danielk1977 -Z 07d9ea0b58d791968ed1c4e04f1541a3 +P b076e1655d6bae5ae10e6ceee646f502435da66a +R edf973d5cbe24872437fb8ece94bf656 +U drh +Z efa71bea2fd6dc4b3f3ab38d3c01a446 diff --git a/manifest.uuid b/manifest.uuid index bf9c1afedb..27d0237c56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b076e1655d6bae5ae10e6ceee646f502435da66a \ No newline at end of file +1668284d151e78d16b0d83bf55dfd9d349a452a7 \ No newline at end of file diff --git a/src/mutex.c b/src/mutex.c index 7bf66949ba..731469a0c3 100644 --- a/src/mutex.c +++ b/src/mutex.c @@ -12,7 +12,7 @@ ** This file contains the C functions that implement mutexes for ** use by the SQLite core. ** -** $Id: mutex.c,v 1.10 2007/08/25 03:59:09 drh Exp $ +** $Id: mutex.c,v 1.11 2007/08/25 14:39:46 drh Exp $ */ /* ** If SQLITE_MUTEX_APPDEF is defined, then this whole module is @@ -208,10 +208,10 @@ int sqlite3_mutex_notheld(sqlite3_mutex *p){ #ifdef SQLITE_MUTEX_PTHREAD -/**************** Non-recursive Pthread Mutex Implementation ***************** +/******************** Pthread Mutex Implementation ********************* ** ** This implementation of mutexes is built using a version of pthreads that -** does not have native support for recursive mutexes. +** has native support for recursive mutexes. */ #include @@ -274,8 +274,27 @@ sqlite3_mutex *sqlite3_mutex_alloc(int iType){ }; sqlite3_mutex *p; switch( iType ){ - case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { + static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER; + static int isInit = 0; + static pthread_mutexattr_t recursiveAttr; + if( !isInit ){ + pthread_mutex_lock(&initMutex); + if( !isInit ){ + pthread_mutexattr_init(&recursiveAttr); + pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); + } + isInit = 1; + pthread_mutex_unlock(&initMutex); + } + p = sqlite3MallocZero( sizeof(*p) ); + if( p ){ + p->id = iType; + pthread_mutex_init(&p->mutex, &recursiveAttr); + } + break; + } + case SQLITE_MUTEX_FAST: { p = sqlite3MallocZero( sizeof(*p) ); if( p ){ p->id = iType; @@ -320,27 +339,20 @@ void sqlite3_mutex_free(sqlite3_mutex *p){ ** more than once, the behavior is undefined. */ void sqlite3_mutex_enter(sqlite3_mutex *p){ - 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; - } + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); + pthread_mutex_lock(&p->mutex); + p->owner = pthread_self(); + p->nRef++; } int sqlite3_mutex_try(sqlite3_mutex *p){ - pthread_t self = pthread_self(); int rc; - if( p->nRef>0 && pthread_equal(p->owner, self) ){ + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); + if( pthread_mutex_trylock(&p->mutex)==0 ){ + p->owner = pthread_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; } @@ -354,12 +366,10 @@ int sqlite3_mutex_try(sqlite3_mutex *p){ ** is not currently allocated. SQLite will never do either. */ void sqlite3_mutex_leave(sqlite3_mutex *p){ - assert( pthread_equal(p->owner, pthread_self()) ); - assert( p->nRef>0 ); + assert( p ); + assert( sqlite3_mutex_held(p) ); p->nRef--; - if( p->nRef==0 ){ - pthread_mutex_unlock(&p->mutex); - } + pthread_mutex_unlock(&p->mutex); } /* @@ -493,12 +503,16 @@ void sqlite3_mutex_free(sqlite3_mutex *p){ ** more than once, the behavior is undefined. */ void sqlite3_mutex_enter(sqlite3_mutex *p){ + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); EnterCriticalSection(&p->mutex); p->owner = GetCurrentThreadId(); p->nRef++; } int sqlite3_mutex_try(sqlite3_mutex *p){ int rc; + assert( p ); + assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) ); if( TryEnterCriticalSection(&p->mutex) ){ p->owner = GetCurrentThreadId(); p->nRef++; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 171919940c..7e0c59f6ac 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,12 +11,13 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.599 2007/08/24 08:15:54 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.600 2007/08/25 14:39:46 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ #include "sqliteLimit.h" +#define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */ #if defined(SQLITE_TCL) || defined(TCLSH) # include -- 2.47.3