aboutsummaryrefslogtreecommitdiff
path: root/src/btmutex.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2007-08-29 04:00:57 +0000
committerdrh <drh@noemail.net>2007-08-29 04:00:57 +0000
commit1fee73e74acab48412a3c596d4cd68deecadeef6 (patch)
tree10aec18d0d28cd9a1a55c6db8d1d128a8afb0716 /src/btmutex.c
parentb1ab8ea7f36073eff200639169fdf73cba1bef8c (diff)
downloadsqlite-1fee73e74acab48412a3c596d4cd68deecadeef6.tar.gz
sqlite-1fee73e74acab48412a3c596d4cd68deecadeef6.zip
Better asserts(). But now some of the tests are busted again. (CVS 4320)
FossilOrigin-Name: e8060f85e7871572e2a38dc96f03e6e1f34cc8fd
Diffstat (limited to 'src/btmutex.c')
-rw-r--r--src/btmutex.c102
1 files changed, 71 insertions, 31 deletions
diff --git a/src/btmutex.c b/src/btmutex.c
index b3dbc3641..7df445770 100644
--- a/src/btmutex.c
+++ b/src/btmutex.c
@@ -10,7 +10,7 @@
**
*************************************************************************
**
-** $Id: btmutex.c,v 1.4 2007/08/29 00:33:07 drh Exp $
+** $Id: btmutex.c,v 1.5 2007/08/29 04:00:58 drh Exp $
**
** This file contains code used to implement mutexes on Btree objects.
** This code really belongs in btree.c. But btree.c is getting too
@@ -55,7 +55,7 @@ void sqlite3BtreeEnter(Btree *p){
assert( p->sharable || p->wantToLock==0 );
/* We should already hold a lock on the database connection */
- assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
if( !p->sharable ) return;
p->wantToLock++;
@@ -109,6 +109,20 @@ void sqlite3BtreeLeave(Btree *p){
}
}
+#ifndef NDEBUG
+/*
+** Return true if a mutex is held on the btree.
+**
+** This routine is used only from within assert() statements.
+*/
+int sqlite3BtreeHoldsMutex(Btree *p){
+ return sqlite3_mutex_held(p->pSqlite->mutex) &&
+ (p->sharable==0 ||
+ (p->locked && p->wantToLock && sqlite3_mutex_held(p->pBt->mutex)));
+}
+#endif
+
+
/*
** Enter the mutex on every Btree associated with a database
** connection. This is needed (for example) prior to parsing
@@ -125,24 +139,28 @@ void sqlite3BtreeLeave(Btree *p){
*/
void sqlite3BtreeEnterAll(sqlite3 *db){
int i;
- Btree *p;
+ Btree *p, *pLater;
assert( sqlite3_mutex_held(db->mutex) );
- for(i=0; i<db->nDb && ((p = db->aDb[i].pBt)==0 || p->sharable==0); i++){}
- if( i<db->nDb ){
- while( p->pNext ) p = p->pNext;
- while( 1 ){
- if( p->locked ){
- sqlite3_mutex_leave(p->pBt->mutex);
- p->locked = 0;
- }
- if( p->pPrev==0 ) break;
- p = p->pPrev;
- }
- while( p ){
+ for(i=0; i<db->nDb; i++){
+ p = db->aDb[i].pBt;
+ if( p && p->sharable ){
p->wantToLock++;
- sqlite3_mutex_enter(p->pBt->mutex);
- p->locked = 1;
- p = p->pNext;
+ if( !p->locked ){
+ assert( p->wantToLock==1 );
+ while( p->pPrev ) p = p->pPrev;
+ while( p->locked && p->pNext ) p = p->pNext;
+ for(pLater = p->pNext; pLater; pLater=pLater->pNext){
+ if( pLater->locked ){
+ sqlite3_mutex_leave(pLater->pBt->mutex);
+ pLater->locked = 0;
+ }
+ }
+ while( p ){
+ sqlite3_mutex_enter(p->pBt->mutex);
+ p->locked++;
+ p = p->pNext;
+ }
+ }
}
}
}
@@ -150,20 +168,44 @@ void sqlite3BtreeLeaveAll(sqlite3 *db){
int i;
Btree *p;
assert( sqlite3_mutex_held(db->mutex) );
- for(i=0; i<db->nDb && ((p = db->aDb[i].pBt)==0 || p->sharable==0); i++){}
- if( i<db->nDb ){
- while( p->pPrev ) p = p->pPrev;
- while( p ){
+ for(i=0; i<db->nDb; i++){
+ p = db->aDb[i].pBt;
+ if( p && p->sharable ){
+ assert( p->wantToLock>0 );
p->wantToLock--;
if( p->wantToLock==0 ){
+ assert( p->locked );
sqlite3_mutex_leave(p->pBt->mutex);
p->locked = 0;
}
- p = p->pNext;
}
}
}
+#ifndef NDEBUG
+/*
+** Return true if the current thread holds the database connection
+** mutex and all required BtShared mutexes.
+**
+** This routine is used inside assert() statements only.
+*/
+int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){
+ int i;
+ if( !sqlite3_mutex_held(db->mutex) ){
+ return 0;
+ }
+ for(i=0; i<db->nDb; i++){
+ Btree *p;
+ p = db->aDb[i].pBt;
+ if( p && p->sharable &&
+ (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif /* NDEBUG */
+
/*
** Potentially dd a new Btree pointer to a BtreeMutexArray.
** Really only add the Btree if it can possibly be shared with
@@ -180,7 +222,7 @@ void sqlite3BtreeLeaveAll(sqlite3 *db){
void sqlite3BtreeMutexArrayInsert(BtreeMutexArray *pArray, Btree *pBtree){
int i, j;
BtShared *pBt;
- if( !pBtree->sharable ) return;
+ if( pBtree->sharable==0 ) return;
#ifndef NDEBUG
{
for(i=0; i<pArray->nMutex; i++){
@@ -217,13 +259,12 @@ void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){
/* Some basic sanity checking */
assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
assert( !p->locked || p->wantToLock>0 );
- assert( p->sharable );
/* We should already hold a lock on the database connection */
- assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
p->wantToLock++;
- if( !p->locked ){
+ if( !p->locked && p->sharable ){
sqlite3_mutex_enter(p->pBt->mutex);
p->locked = 1;
}
@@ -239,15 +280,14 @@ void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){
Btree *p = pArray->aBtree[i];
/* Some basic sanity checking */
assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
- assert( p->locked );
- assert( p->sharable );
+ assert( p->locked || !p->sharable );
assert( p->wantToLock>0 );
/* We should already hold a lock on the database connection */
- assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
p->wantToLock--;
- if( p->wantToLock==0 ){
+ if( p->wantToLock==0 && p->locked ){
sqlite3_mutex_leave(p->pBt->mutex);
p->locked = 0;
}