1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Always set BtShared.db when entering the BtShared mutex. Ticket #3793. (CVS 6480)

FossilOrigin-Name: ed6620ba589ddbb6ca86f42a7652e3b019195647
This commit is contained in:
danielk1977
2009-04-10 09:47:06 +00:00
parent 8c5d152b53
commit 2a50ff0309
5 changed files with 173 additions and 53 deletions

View File

@@ -10,7 +10,7 @@
**
*************************************************************************
**
** $Id: btmutex.c,v 1.13 2009/03/05 04:20:32 shane Exp $
** $Id: btmutex.c,v 1.14 2009/04/10 09:47:07 danielk1977 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
@@ -20,6 +20,34 @@
#include "btreeInt.h"
#if SQLITE_THREADSAFE && !defined(SQLITE_OMIT_SHARED_CACHE)
/*
** Obtain the BtShared mutex associated with B-Tree handle p. Also,
** set BtShared.db to the database handle associated with p and the
** p->locked boolean to true.
*/
static void lockBtreeMutex(Btree *p){
assert( p->locked==0 );
assert( sqlite3_mutex_notheld(p->pBt->mutex) );
assert( sqlite3_mutex_held(p->db->mutex) );
sqlite3_mutex_enter(p->pBt->mutex);
p->pBt->db = p->db;
p->locked = 1;
}
/*
** Release the BtShared mutex associated with B-Tree handle p and
** clear the p->locked boolean.
*/
static void unlockBtreeMutex(Btree *p){
assert( p->locked==1 );
assert( sqlite3_mutex_held(p->pBt->mutex) );
assert( sqlite3_mutex_held(p->db->mutex) );
assert( p->db==p->pBt->db );
sqlite3_mutex_leave(p->pBt->mutex);
p->locked = 0;
}
/*
** Enter a mutex on the given BTree object.
@@ -57,6 +85,10 @@ void sqlite3BtreeEnter(Btree *p){
/* We should already hold a lock on the database connection */
assert( sqlite3_mutex_held(p->db->mutex) );
/* Unless the database is sharable and unlocked, then BtShared.db
** should already be set correctly. */
assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db );
if( !p->sharable ) return;
p->wantToLock++;
if( p->locked ) return;
@@ -66,6 +98,7 @@ void sqlite3BtreeEnter(Btree *p){
** procedure that follows. Just be sure not to block.
*/
if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){
p->pBt->db = p->db;
p->locked = 1;
return;
}
@@ -80,16 +113,13 @@ void sqlite3BtreeEnter(Btree *p){
assert( pLater->pNext==0 || pLater->pNext->pBt>pLater->pBt );
assert( !pLater->locked || pLater->wantToLock>0 );
if( pLater->locked ){
sqlite3_mutex_leave(pLater->pBt->mutex);
pLater->locked = 0;
unlockBtreeMutex(pLater);
}
}
sqlite3_mutex_enter(p->pBt->mutex);
p->locked = 1;
lockBtreeMutex(p);
for(pLater=p->pNext; pLater; pLater=pLater->pNext){
if( pLater->wantToLock ){
sqlite3_mutex_enter(pLater->pBt->mutex);
pLater->locked = 1;
lockBtreeMutex(pLater);
}
}
}
@@ -102,25 +132,25 @@ void sqlite3BtreeLeave(Btree *p){
assert( p->wantToLock>0 );
p->wantToLock--;
if( p->wantToLock==0 ){
assert( p->locked );
sqlite3_mutex_leave(p->pBt->mutex);
p->locked = 0;
unlockBtreeMutex(p);
}
}
}
#ifndef NDEBUG
/*
** Return true if the BtShared mutex is held on the btree.
**
** This routine makes no determination one way or another if the
** database connection mutex is held.
** Return true if the BtShared mutex is held on the btree, or if the
** B-Tree is not marked as sharable.
**
** This routine is used only from within assert() statements.
*/
int sqlite3BtreeHoldsMutex(Btree *p){
return (p->sharable==0 ||
(p->locked && p->wantToLock && sqlite3_mutex_held(p->pBt->mutex)));
assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 );
assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db );
assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) );
assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) );
return (p->sharable==0 || p->locked);
}
#endif
@@ -160,6 +190,7 @@ void sqlite3BtreeEnterAll(sqlite3 *db){
assert( sqlite3_mutex_held(db->mutex) );
for(i=0; i<db->nDb; i++){
p = db->aDb[i].pBt;
assert( !p || (p->locked==0 && p->sharable) || p->pBt->db==p->db );
if( p && p->sharable ){
p->wantToLock++;
if( !p->locked ){
@@ -168,13 +199,11 @@ void sqlite3BtreeEnterAll(sqlite3 *db){
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;
unlockBtreeMutex(pLater);
}
}
while( p ){
sqlite3_mutex_enter(p->pBt->mutex);
p->locked++;
lockBtreeMutex(p);
p = p->pNext;
}
}
@@ -191,9 +220,7 @@ void sqlite3BtreeLeaveAll(sqlite3 *db){
assert( p->wantToLock>0 );
p->wantToLock--;
if( p->wantToLock==0 ){
assert( p->locked );
sqlite3_mutex_leave(p->pBt->mutex);
p->locked = 0;
unlockBtreeMutex(p);
}
}
}
@@ -282,8 +309,7 @@ void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){
p->wantToLock++;
if( !p->locked && p->sharable ){
sqlite3_mutex_enter(p->pBt->mutex);
p->locked = 1;
lockBtreeMutex(p);
}
}
}
@@ -305,8 +331,7 @@ void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){
p->wantToLock--;
if( p->wantToLock==0 && p->locked ){
sqlite3_mutex_leave(p->pBt->mutex);
p->locked = 0;
unlockBtreeMutex(p);
}
}
}