diff options
author | drh <drh@noemail.net> | 2007-08-29 04:00:57 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2007-08-29 04:00:57 +0000 |
commit | 1fee73e74acab48412a3c596d4cd68deecadeef6 (patch) | |
tree | 10aec18d0d28cd9a1a55c6db8d1d128a8afb0716 /src/btmutex.c | |
parent | b1ab8ea7f36073eff200639169fdf73cba1bef8c (diff) | |
download | sqlite-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.c | 102 |
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; } |