mirror of https://github.com/sqlite/sqlite
Fix to cause BtShared.db to be set correctly on shared-cache
connections in SQLITE_THREADSAFE=0 builds. Added assert()s to verify the correct setting of BtShared.db. FossilOrigin-Name: 2d96aeba2460779a0a20356739a0ba49144c8a85
This commit is contained in:
commit
cad2486543
21
manifest
21
manifest
|
@ -1,5 +1,5 @@
|
|||
C Small\sperformance\sand\ssize\soptimization\sspotted\swhile\sworking\son\sthe\nshared-cache\sproblem.
|
||||
D 2016-01-07T17:09:43.631
|
||||
C Fix\sto\scause\sBtShared.db\sto\sbe\sset\scorrectly\son\sshared-cache\nconnections\sin\sSQLITE_THREADSAFE=0\sbuilds.\s\sAdded\sassert()s\sto\sverify\nthe\scorrect\ssetting\sof\sBtShared.db.
|
||||
D 2016-01-07T17:19:24.484
|
||||
F Makefile.in 7c8cc4c2f0179efc6fa9492141d1fb65f4807054
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc e45d8b9b56dfa3f2cd860b2c28bd9d304513b042
|
||||
|
@ -275,9 +275,9 @@ F src/attach.c e944d0052b577703b9b83aac1638452ff42a8395
|
|||
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
|
||||
F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
|
||||
F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
|
||||
F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79
|
||||
F src/btree.c 4d3452b2a3daf875490ac4f0a278da7f85fabe12
|
||||
F src/btree.h 2d76dee44704c47eed323356a758662724b674a0
|
||||
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
|
||||
F src/btree.c 09ec3ca5e7a6b8c277cef6c4471a1427cab5fa01
|
||||
F src/btree.h 68ef301795e00cdf1d3ab93abc44a43b7fe771e0
|
||||
F src/btreeInt.h b5f2651b41808f038dee9282c5dc0232ce6532d3
|
||||
F src/build.c 9d497ff4bf3c82cecb520436e0e9963785627583
|
||||
F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0
|
||||
|
@ -400,9 +400,9 @@ F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70
|
|||
F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
|
||||
F src/vdbe.c 6ac8e5d808d48afc369316e147c191102f0584c1
|
||||
F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637
|
||||
F src/vdbeInt.h 75c2e82ee3357e9210c06474f8d9bdf12c81105d
|
||||
F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189
|
||||
F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca
|
||||
F src/vdbeaux.c 3308a07a6b0b64e22e83cbcc76773eaf330b056a
|
||||
F src/vdbeaux.c 5d8c7c04e0f677033efb1292248a5f9056bbc34c
|
||||
F src/vdbeblob.c fdc4a81605ae7a35ae94a55bd768b66d6be16f15
|
||||
F src/vdbemem.c fdd1578e47bea61390d472de53c565781d81e045
|
||||
F src/vdbesort.c a7ec02da4494c59dfd071126dd3726be5a11459d
|
||||
|
@ -1406,7 +1406,8 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
|
|||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P 4f80440bf566959306f6ca8cbb1fd29d138ee38b
|
||||
R f265718df82e1345668e0777962739f6
|
||||
P 828958ff77a5c239d55302f570077835c093e0fa 359277e0e5338f6d7743d58cf99e1c934a8460d5
|
||||
R 6a20a209200c5a1c13b83cee78194e2e
|
||||
T +closed 359277e0e5338f6d7743d58cf99e1c934a8460d5
|
||||
U drh
|
||||
Z e6c791f6b7ef0a212def33d53e341994
|
||||
Z 1846b22def634146b1c38f34bfdda1cc
|
||||
|
|
|
@ -1 +1 @@
|
|||
828958ff77a5c239d55302f570077835c093e0fa
|
||||
2d96aeba2460779a0a20356739a0ba49144c8a85
|
|
@ -169,21 +169,6 @@ int sqlite3BtreeHoldsMutex(Btree *p){
|
|||
#endif
|
||||
|
||||
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
/*
|
||||
** Enter and leave a mutex on a Btree given a cursor owned by that
|
||||
** Btree. These entry points are used by incremental I/O and can be
|
||||
** omitted if that module is not used.
|
||||
*/
|
||||
void sqlite3BtreeEnterCursor(BtCursor *pCur){
|
||||
sqlite3BtreeEnter(pCur->pBtree);
|
||||
}
|
||||
void sqlite3BtreeLeaveCursor(BtCursor *pCur){
|
||||
sqlite3BtreeLeave(pCur->pBtree);
|
||||
}
|
||||
#endif /* SQLITE_OMIT_INCRBLOB */
|
||||
|
||||
|
||||
/*
|
||||
** Enter the mutex on every Btree associated with a database
|
||||
** connection. This is needed (for example) prior to parsing
|
||||
|
@ -217,14 +202,6 @@ void sqlite3BtreeLeaveAll(sqlite3 *db){
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if a particular Btree requires a lock. Return FALSE if
|
||||
** no lock is ever required since it is not sharable.
|
||||
*/
|
||||
int sqlite3BtreeSharable(Btree *p){
|
||||
return p->sharable;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/*
|
||||
** Return true if the current thread holds the database connection
|
||||
|
@ -298,4 +275,23 @@ void sqlite3BtreeEnterAll(sqlite3 *db){
|
|||
}
|
||||
}
|
||||
#endif /* if SQLITE_THREADSAFE */
|
||||
|
||||
#ifndef SQLITE_OMIT_INCRBLOB
|
||||
/*
|
||||
** Enter a mutex on a Btree given a cursor owned by that Btree.
|
||||
**
|
||||
** These entry points are used by incremental I/O only. Enter() is required
|
||||
** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not
|
||||
** the build is threadsafe. Leave() is only required by threadsafe builds.
|
||||
*/
|
||||
void sqlite3BtreeEnterCursor(BtCursor *pCur){
|
||||
sqlite3BtreeEnter(pCur->pBtree);
|
||||
}
|
||||
# if SQLITE_THREADSAFE
|
||||
void sqlite3BtreeLeaveCursor(BtCursor *pCur){
|
||||
sqlite3BtreeLeave(pCur->pBtree);
|
||||
}
|
||||
# endif
|
||||
#endif /* ifndef SQLITE_OMIT_INCRBLOB */
|
||||
|
||||
#endif /* ifndef SQLITE_OMIT_SHARED_CACHE */
|
||||
|
|
49
src/btree.c
49
src/btree.c
|
@ -450,6 +450,10 @@ static void releasePage(MemPage *pPage); /* Forward reference */
|
|||
static int cursorHoldsMutex(BtCursor *p){
|
||||
return sqlite3_mutex_held(p->pBt->mutex);
|
||||
}
|
||||
static int cursorOwnsBtShared(BtCursor *p){
|
||||
assert( cursorHoldsMutex(p) );
|
||||
return (p->pBtree->db==p->pBt->db);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -786,7 +790,7 @@ static int btreeMoveto(
|
|||
static int btreeRestoreCursorPosition(BtCursor *pCur){
|
||||
int rc;
|
||||
int skipNext;
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->eState>=CURSOR_REQUIRESEEK );
|
||||
if( pCur->eState==CURSOR_FAULT ){
|
||||
return pCur->skipNext;
|
||||
|
@ -4286,7 +4290,7 @@ int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
|
|||
** to return an integer result code for historical reasons.
|
||||
*/
|
||||
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage>=0 );
|
||||
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
|
||||
|
@ -4666,7 +4670,7 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
|
|||
}
|
||||
#endif
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
rc = restoreCursorPosition(pCur);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
|
@ -4704,7 +4708,7 @@ static const void *fetchPayload(
|
|||
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
|
||||
assert( pCur->info.nSize>0 );
|
||||
assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
|
||||
|
@ -4750,7 +4754,7 @@ const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){
|
|||
static int moveToChild(BtCursor *pCur, u32 newPgno){
|
||||
BtShared *pBt = pCur->pBt;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
|
||||
assert( pCur->iPage>=0 );
|
||||
|
@ -4796,7 +4800,7 @@ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
|
|||
** the largest cell index.
|
||||
*/
|
||||
static void moveToParent(BtCursor *pCur){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
assert( pCur->iPage>0 );
|
||||
assert( pCur->apPage[pCur->iPage] );
|
||||
|
@ -4836,7 +4840,7 @@ static int moveToRoot(BtCursor *pCur){
|
|||
MemPage *pRoot;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
|
||||
assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
|
||||
assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
|
||||
|
@ -4915,7 +4919,7 @@ static int moveToLeftmost(BtCursor *pCur){
|
|||
int rc = SQLITE_OK;
|
||||
MemPage *pPage;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
|
||||
|
@ -4940,7 +4944,7 @@ static int moveToRightmost(BtCursor *pCur){
|
|||
int rc = SQLITE_OK;
|
||||
MemPage *pPage = 0;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->eState==CURSOR_VALID );
|
||||
while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
|
||||
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
|
||||
|
@ -4961,7 +4965,7 @@ static int moveToRightmost(BtCursor *pCur){
|
|||
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
||||
int rc;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
rc = moveToRoot(pCur);
|
||||
if( rc==SQLITE_OK ){
|
||||
|
@ -4984,7 +4988,7 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
|||
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
||||
int rc;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
|
||||
/* If the cursor already points to the last entry, this is a no-op. */
|
||||
|
@ -5062,7 +5066,7 @@ int sqlite3BtreeMovetoUnpacked(
|
|||
int rc;
|
||||
RecordCompare xRecordCompare;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||
assert( pRes );
|
||||
assert( (pIdxKey==0)==(pCur->pKeyInfo==0) );
|
||||
|
@ -5310,7 +5314,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
|||
int idx;
|
||||
MemPage *pPage;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||
assert( *pRes==0 );
|
||||
if( pCur->eState!=CURSOR_VALID ){
|
||||
|
@ -5374,7 +5378,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
|
|||
}
|
||||
int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
|
||||
MemPage *pPage;
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pRes!=0 );
|
||||
assert( *pRes==0 || *pRes==1 );
|
||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||
|
@ -5419,7 +5423,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
|||
int rc;
|
||||
MemPage *pPage;
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pRes!=0 );
|
||||
assert( *pRes==0 );
|
||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||
|
@ -5475,7 +5479,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
|
|||
return rc;
|
||||
}
|
||||
int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pRes!=0 );
|
||||
assert( *pRes==0 || *pRes==1 );
|
||||
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
|
||||
|
@ -7955,7 +7959,7 @@ int sqlite3BtreeInsert(
|
|||
return pCur->skipNext;
|
||||
}
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( (pCur->curFlags & BTCF_WriteFlag)!=0
|
||||
&& pBt->inTransaction==TRANS_WRITE
|
||||
&& (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||
|
@ -8102,7 +8106,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){
|
|||
u16 szCell; /* Size of the cell being deleted */
|
||||
int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
|
||||
|
||||
assert( cursorHoldsMutex(pCur) );
|
||||
assert( cursorOwnsBtShared(pCur) );
|
||||
assert( pBt->inTransaction==TRANS_WRITE );
|
||||
assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
|
||||
assert( pCur->curFlags & BTCF_WriteFlag );
|
||||
|
@ -9564,7 +9568,7 @@ int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
|
|||
*/
|
||||
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
||||
int rc;
|
||||
assert( cursorHoldsMutex(pCsr) );
|
||||
assert( cursorOwnsBtShared(pCsr) );
|
||||
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
|
||||
assert( pCsr->curFlags & BTCF_Incrblob );
|
||||
|
||||
|
@ -9671,3 +9675,10 @@ int sqlite3BtreeIsReadonly(Btree *p){
|
|||
** Return the size of the header added to each page by this module.
|
||||
*/
|
||||
int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
|
||||
|
||||
/*
|
||||
** Return true if the Btree passed as the only argument is sharable.
|
||||
*/
|
||||
int sqlite3BtreeSharable(Btree *p){
|
||||
return p->sharable;
|
||||
}
|
||||
|
|
|
@ -287,15 +287,17 @@ void sqlite3BtreeCursorList(Btree*);
|
|||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
void sqlite3BtreeEnter(Btree*);
|
||||
void sqlite3BtreeEnterAll(sqlite3*);
|
||||
int sqlite3BtreeSharable(Btree*);
|
||||
void sqlite3BtreeEnterCursor(BtCursor*);
|
||||
#else
|
||||
# define sqlite3BtreeEnter(X)
|
||||
# define sqlite3BtreeEnterAll(X)
|
||||
# define sqlite3BtreeSharable(X) 0
|
||||
# define sqlite3BtreeEnterCursor(X)
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
|
||||
int sqlite3BtreeSharable(Btree*);
|
||||
void sqlite3BtreeLeave(Btree*);
|
||||
void sqlite3BtreeEnterCursor(BtCursor*);
|
||||
void sqlite3BtreeLeaveCursor(BtCursor*);
|
||||
void sqlite3BtreeLeaveAll(sqlite3*);
|
||||
#ifndef NDEBUG
|
||||
|
@ -306,9 +308,7 @@ void sqlite3BtreeCursorList(Btree*);
|
|||
#endif
|
||||
#else
|
||||
|
||||
# define sqlite3BtreeSharable(X) 0
|
||||
# define sqlite3BtreeLeave(X)
|
||||
# define sqlite3BtreeEnterCursor(X)
|
||||
# define sqlite3BtreeLeaveCursor(X)
|
||||
# define sqlite3BtreeLeaveAll(X)
|
||||
|
||||
|
|
|
@ -489,11 +489,15 @@ int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
|
|||
int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
|
||||
int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE)
|
||||
void sqlite3VdbeEnter(Vdbe*);
|
||||
void sqlite3VdbeLeave(Vdbe*);
|
||||
#else
|
||||
# define sqlite3VdbeEnter(X)
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
|
||||
void sqlite3VdbeLeave(Vdbe*);
|
||||
#else
|
||||
# define sqlite3VdbeLeave(X)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1317,7 +1317,7 @@ void sqlite3VdbeUsesBtree(Vdbe *p, int i){
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE)
|
||||
/*
|
||||
** If SQLite is compiled to support shared-cache mode and to be threadsafe,
|
||||
** this routine obtains the mutex associated with each BtShared structure
|
||||
|
|
Loading…
Reference in New Issue