1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-05 15:55:57 +03:00

Better asserts(). But now some of the tests are busted again. (CVS 4320)

FossilOrigin-Name: e8060f85e7871572e2a38dc96f03e6e1f34cc8fd
This commit is contained in:
drh
2007-08-29 04:00:57 +00:00
parent b1ab8ea7f3
commit 1fee73e74a
7 changed files with 207 additions and 185 deletions

View File

@@ -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;
}