mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Fix for #2854. "BEGIN EXCLUSIVE" excludes other shared cache users from using the database. (CVS 4642)
FossilOrigin-Name: 2e59b1d07ee422bd799b5b7aeea44ebc998d9481
This commit is contained in:
35
src/btree.c
35
src/btree.c
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.433 2007/12/13 21:54:11 drh Exp $
|
||||
** $Id: btree.c,v 1.434 2007/12/21 04:47:26 danielk1977 Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** See the header comment on "btreeInt.h" for additional information.
|
||||
@@ -103,6 +103,13 @@ static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/* If some other connection is holding an exclusive lock, the
|
||||
** requested lock may not be obtained.
|
||||
*/
|
||||
if( pBt->pExclusive && pBt->pExclusive!=p ){
|
||||
return SQLITE_LOCKED;
|
||||
}
|
||||
|
||||
/* This (along with lockTable()) is where the ReadUncommitted flag is
|
||||
** dealt with. If the caller is querying for a read-lock and the flag is
|
||||
** set, it is unconditionally granted - even if there are write-locks
|
||||
@@ -212,13 +219,15 @@ static int lockTable(Btree *p, Pgno iTable, u8 eLock){
|
||||
** procedure) held by Btree handle p.
|
||||
*/
|
||||
static void unlockAllTables(Btree *p){
|
||||
BtLock **ppIter = &p->pBt->pLock;
|
||||
BtShared *pBt = p->pBt;
|
||||
BtLock **ppIter = &pBt->pLock;
|
||||
|
||||
assert( sqlite3BtreeHoldsMutex(p) );
|
||||
assert( p->sharable || 0==*ppIter );
|
||||
|
||||
while( *ppIter ){
|
||||
BtLock *pLock = *ppIter;
|
||||
assert( pBt->pExclusive==0 || pBt->pExclusive==pLock->pBtree );
|
||||
if( pLock->pBtree==p ){
|
||||
*ppIter = pLock->pNext;
|
||||
sqlite3_free(pLock);
|
||||
@@ -226,6 +235,10 @@ static void unlockAllTables(Btree *p){
|
||||
ppIter = &pLock->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
if( pBt->pExclusive==p ){
|
||||
pBt->pExclusive = 0;
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_OMIT_SHARED_CACHE */
|
||||
|
||||
@@ -1850,6 +1863,18 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
||||
goto trans_begun;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
if( wrflag>1 ){
|
||||
BtLock *pIter;
|
||||
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
|
||||
if( pIter->pBtree!=p ){
|
||||
rc = SQLITE_BUSY;
|
||||
goto trans_begun;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
do {
|
||||
if( pBt->pPage1==0 ){
|
||||
rc = lockBtree(pBt);
|
||||
@@ -1882,6 +1907,12 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
||||
if( p->inTrans>pBt->inTransaction ){
|
||||
pBt->inTransaction = p->inTrans;
|
||||
}
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
if( wrflag>1 ){
|
||||
assert( !pBt->pExclusive );
|
||||
pBt->pExclusive = p;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user