-C Fix\smemory\sleak\sof\sInteriorReader.term.\s\sComes\sup\swhen\sdoing\squeries\nagainst\slarge\ssegments.\s(CVS\s4315)
-D 2007-08-28T20:36:54
+C Clean\sup\sthe\slocking\sin\sthe\sbtree\slogic.\s(CVS\s4316)
+D 2007-08-28T22:24:35
F Makefile.in bfcc303429a5d9dcd552d807ee016c77427418c3
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8
F src/auth.c 083c1205b45e3f52291ec539d396b4fc557856b3
F src/btmutex.c 3a19fcb311d0d09e63d397779be881d4273f4518
-F src/btree.c 850cd5de860e01233153ade9b24ffc775a794e8e
+F src/btree.c 8796aa42fd16feb587844489a0fce8c66e52ac02
F src/btree.h a8fb26c56b745b57446c2bf29133619261313051
-F src/btreeInt.h c1ba892252bc4dd76ad66da056536c64b23456e3
-F src/build.c 08001e8a12b06178193dc4a8f24610f58de80dae
+F src/btreeInt.h 5b1bc919cb80f0dd6baec1cdbae737f9806a7e3b
+F src/build.c 99b0b0c44ce7673c00d8c0c97ce536e3b796328b
F src/callback.c a542236a68060caad378efa30006ca46cf77b1b2
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
F src/date.c af235f38f50809abd0a96da3bb3e0cc32be6226e
F src/mutex.c 40e5ba09d56863895882a0204d93832e9960ea78
F src/mutex.h 4d3babe3a691533ac980967d394da512140b5143
F src/mutex_os2.c d47e9bd495583dd31263d8fe55160a31eb600a3c
-F src/mutex_unix.c 84ae0344b0bd6591e3bfea2cb6d375233d39f8a4
+F src/mutex_unix.c ff77650261a245035b79c5c8a174f4e05d3cae8a
F src/mutex_w32.c 8716478c5f1829b27fd2c9a0759230a9dc3aa9e3
F src/os.c a8ed3c495161475dbce255f7003144144fb425f1
F src/os.h 2bfbbad126a775e4d8c7d59eb4d9585a5fd7dfb5
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
F src/os_win.c 3ffd3aacff4cb69848284e29dcec0feff23b0752
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c 51ca27639ab25c8838afc856d3cc6045a98752a7
-F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
+F src/pager.c 97fd0bb853e01e6890ad9aae97e7f9155330ebdc
+F src/pager.h a9872db184613ae90ae80921f5fd956aa8f3522e
F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590
F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5
F src/prepare.c 29ea14cf6b0558f2f80aa53e112bff55f1119e36
F src/util.c 3f9c0387b54f977726790f52ab92cd3d9379b367
F src/vacuum.c 5ec133b69edf581a232af7e2b01f45c9f2b8be32
F src/vdbe.c 62d210babaac906a5847d7bd4c71e7b114595e85
-F src/vdbe.h 5b3ee0fd91a08579f514713038fa7dbef9edf407
-F src/vdbeInt.h 0681e0b74a43d3adfec65780d73b2db8f826c7c9
+F src/vdbe.h 498e9ddade4baf70f2fc39e585670131dde07caa
+F src/vdbeInt.h a9dcd0688783abbd60981aff7ecc5b57a9559765
F src/vdbeapi.c bdd0aea216744482dd1b7fab56de18ba5b6fbdf4
-F src/vdbeaux.c bffdf7b69de21a70520260d359e19df64f31aea4
+F src/vdbeaux.c 0bbc8fbb6bcd610e98ce8eef77d0db660710f9dd
F src/vdbeblob.c d12ed95dac0992e1e372d079d76af047cc42f7c7
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
F src/vdbemem.c 896fa3f8df9d2661eb15c7ce361857741b447268
F test/shared.test 08b30d5f1939efff0517e7ff8ec7b74ad31c151b
F test/shared2.test 0ee9de8964d70e451936a48c41cb161d9134ccf4
F test/shared3.test 01e3e124dbb3859788aabc7cfb82f7ea04421749
-F test/shared_err.test 9fa070e3e7d63022a81b6156ac71f114c0678e3d
+F test/shared_err.test 99d3d87924cedc1db2233ef59f38c389dd358698
F test/soak.test 64f9b27fbcdec43335a88c546ce1983e6ba40d7b
F test/softheap1.test 0c49aa6eee25e7d32943e85e8d1f20eff566b1dc
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P dd43a2de3ed1659d70361370d07a184dd8ece45f
-R 70912c36e1c512cb72f986c6f3262b7a
-U shess
-Z e249b078ef5ae37e1d80116148f5bc5a
+P 6c617bd89fc57881a2a308a6360e8ebb42835d46
+R 45b11caba5c119849cdae69b051cb491
+U drh
+Z 8c8847e04e8b6bae7d208c08aa3c66c5
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.413 2007/08/28 02:27:52 drh Exp $
+** $Id: btree.c,v 1.414 2007/08/28 22:24:35 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
BtShared *pBt = p->pBt;
BtLock *pIter;
+ assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
assert( sqlite3BtreeMutexHeld(pBt->mutex) );
/* This is a no-op if the shared-cache is not enabled */
BtLock *pLock = 0;
BtLock *pIter;
+ assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
assert( sqlite3BtreeMutexHeld(pBt->mutex) );
/* This is a no-op if the shared-cache is not enabled */
static void unlockAllTables(Btree *p){
BtLock **ppIter = &p->pBt->pLock;
+ assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
assert( sqlite3BtreeMutexHeld(p->pBt->mutex) );
assert( p->sharable || 0==*ppIter );
** Invalidate the overflow page-list cache for cursor pCur, if any.
*/
static void invalidateOverflowCache(BtCursor *pCur){
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
sqlite3_free(pCur->aOverflow);
pCur->aOverflow = 0;
}
assert( CURSOR_VALID==pCur->eState );
assert( 0==pCur->pKey );
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
BtCursor *p;
assert( sqlite3BtreeMutexHeld(pBt->mutex) );
+ assert( pExcept==0 || pExcept->pBt==pBt );
for(p=pBt->pCursor; p; p=p->pNext){
if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) &&
p->eState==CURSOR_VALID ){
** Clear the current cursor position.
*/
static void clearCursorPosition(BtCursor *pCur){
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
sqlite3_free(pCur->pKey);
pCur->pKey = 0;
pCur->eState = CURSOR_INVALID;
*/
int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){
int rc;
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
assert( pCur->eState==CURSOR_REQUIRESEEK );
#ifndef SQLITE_OMIT_INCRBLOB
if( pCur->isIncrblobHandle ){
MemPage *pPage;
assert( (pageSize & 7)==0 );
pPage = (MemPage *)sqlite3PagerGetExtra(pData);
+ assert( pPage->isInit==0 || sqlite3BtreeMutexHeld(pPage->pBt->mutex) );
if( pPage->pParent ){
MemPage *pParent = pPage->pParent;
- assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) );
+ assert( pPage->isInit==1 );
+ assert( pParent->pBt==pPage->pBt );
pPage->pParent = 0;
releasePage(pParent);
}
#endif
#endif
- if( pSqlite ){
- pVfs = pSqlite->pVfs;
- }else{
- pVfs = sqlite3_vfs_find(0);
- }
- assert( sqlite3BtreeMutexHeld(pSqlite->mutex) );
+ assert( pSqlite!=0 );
+ assert( sqlite3_mutex_held(pSqlite->mutex) );
+ pVfs = pSqlite->pVfs;
p = sqlite3MallocZero(sizeof(Btree));
if( !p ){
return SQLITE_NOMEM;
*/
if( (flags & BTREE_PRIVATE)==0
&& isMemdb==0
- && (pSqlite==0 || (pSqlite->flags &SQLITE_Vtab)==0)
+ && (pSqlite->flags & SQLITE_Vtab)==0
&& zFilename && zFilename[0]
&& sqlite3SharedCacheEnabled
){
sqlite3_mutex_enter(mutexShared);
for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){
assert( pBt->nRef>0 );
- if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) ){
+ if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
+ && sqlite3PagerVfs(pBt->pPager)==pVfs ){
p->pBt = pBt;
pBt->nRef++;
break;
BtCursor *pCur;
/* Close all cursors opened via this handle. */
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
sqlite3BtreeEnter(p);
pCur = pBt->pCursor;
while( pCur ){
/*
** Short-cuts for entering and leaving mutexes on a cursor.
*/
-static void cursorLeave(BtCursor *p){
- sqlite3BtreeLeave(p->pBtree);
-}
-static void cursorEnter(BtCursor *pCur){
- sqlite3BtreeEnter(pCur->pBtree);
-}
+# define cursorEnter(X) assert( sqlite3_mutex_held(X->pBt->mutex) )
+# define cursorLeave(X)
#else
# define cursorEnter(X)
# define cursorLeave(X)
*/
int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){
BtShared *pBt = p->pBt;
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
sqlite3BtreeEnter(p);
pBt->pBusyHandler = pHandler;
sqlite3PagerSetBusyhandler(pBt->pPager, pHandler);
*/
int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
BtShared *pBt = p->pBt;
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
sqlite3BtreeEnter(p);
sqlite3PagerSetCachesize(pBt->pPager, mxPage);
sqlite3BtreeLeave(p);
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
BtShared *pBt = p->pBt;
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
sqlite3BtreeEnter(p);
sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync);
sqlite3BtreeLeave(p);
int sqlite3BtreeSyncDisabled(Btree *p){
BtShared *pBt = p->pBt;
int rc;
- assert( pBt && pBt->pPager );
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
sqlite3BtreeEnter(p);
+ assert( pBt && pBt->pPager );
rc = sqlite3PagerNosync(pBt->pPager);
sqlite3BtreeLeave(p);
return rc;
assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 ||
eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
assert( sqlite3BtreeMutexHeld(pBt->mutex) );
+ assert( pDbPage->pBt==pBt );
/* Move page iDbPage from it's current location to page number iFreePage */
TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
BtShared *pBt = p->pBt;
assert( sqlite3BtreeMutexHeld(pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
*ppCur = 0;
if( wrFlag ){
if( pBt->readOnly ){
pCur->xCompare = xCmp ? xCmp : dfltCompare;
pCur->pArg = pArg;
pCur->pBtree = p;
+ pCur->pBt = pBt;
pCur->wrFlag = wrFlag;
pCur->pNext = pBt->pCursor;
if( pCur->pNext ){
** when the last cursor is closed.
*/
int sqlite3BtreeCloseCursor(BtCursor *pCur){
- BtShared *pBt = pCur->pBtree->pBt;
+ BtShared *pBt = pCur->pBt;
- cursorEnter(pCur);
+ assert( sqlite3_mutex_held(pCur->pBt->mutex) );
+ assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
clearCursorPosition(pCur);
if( pCur->pPrev ){
pCur->pPrev->pNext = pCur->pNext;
releasePage(pCur->pPage);
unlockBtreeIfUnused(pBt);
invalidateOverflowCache(pCur);
- cursorLeave(pCur);
sqlite3_free(pCur);
return SQLITE_OK;
}
** The temporary cursor is not on the cursor list for the Btree.
*/
void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur){
+ cursorEnter(pCur);
memcpy(pTempCur, pCur, sizeof(*pCur));
pTempCur->pNext = 0;
pTempCur->pPrev = 0;
if( pTempCur->pPage ){
- cursorEnter(pCur);
sqlite3PagerRef(pTempCur->pPage->pDbPage);
- cursorLeave(pCur);
}
+ cursorLeave(pCur);
}
/*
** function above.
*/
void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){
+ cursorEnter(pCur);
if( pCur->pPage ){
- cursorEnter(pCur);
sqlite3PagerUnref(pCur->pPage->pDbPage);
- cursorLeave(pCur);
}
+ cursorLeave(pCur);
}
/*
int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
int rc;
- sqlite3BtreeEnter(pCur->pBtree);
+ assert( sqlite3_mutex_held(pCur->pBt->mutex) );
rc = restoreOrClearCursorPosition(pCur);
if( rc==SQLITE_OK ){
assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
*pSize = pCur->info.nKey;
}
}
- sqlite3BtreeLeave(pCur->pBtree);
return rc;
}
int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
int rc;
- sqlite3BtreeEnter(pCur->pBtree);
+ assert( sqlite3_mutex_held(pCur->pBt->mutex) );
rc = restoreOrClearCursorPosition(pCur);
if( rc==SQLITE_OK ){
assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
*pSize = pCur->info.nData;
}
}
- sqlite3BtreeLeave(pCur->pBtree);
return rc;
}
int rc = SQLITE_OK;
u32 nKey;
int iIdx = 0;
- MemPage *pPage = pCur->pPage; /* Btree page of current cursor entry */
- BtShared *pBt = pCur->pBtree->pBt; /* Btree this cursor belongs to */
+ MemPage *pPage = pCur->pPage; /* Btree page of current cursor entry */
+ BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
assert( pPage );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
assert( offset>=0 );
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
getCellInfo(pCur);
aPayload = pCur->info.pCell + pCur->info.nHeader;
int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
int rc;
- sqlite3BtreeEnter(pCur->pBtree);
+ cursorEnter(pCur);
rc = restoreOrClearCursorPosition(pCur);
if( rc==SQLITE_OK ){
assert( pCur->eState==CURSOR_VALID );
assert( pCur->pPage!=0 );
if( pCur->pPage->intKey ){
- sqlite3BtreeLeave(pCur->pBtree);
+ cursorLeave(pCur);
return SQLITE_CORRUPT_BKPT;
}
assert( pCur->pPage->intKey==0 );
assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0, 0);
}
- sqlite3BtreeLeave(pCur->pBtree);
+ cursorLeave(pCur);
return rc;
}
int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
int rc;
- sqlite3BtreeEnter(pCur->pBtree);
+ cursorEnter(pCur);
rc = restoreOrClearCursorPosition(pCur);
if( rc==SQLITE_OK ){
assert( pCur->eState==CURSOR_VALID );
assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
rc = accessPayload(pCur, offset, amt, pBuf, 1, 0);
}
- sqlite3BtreeLeave(pCur->pBtree);
+ cursorLeave(pCur);
return rc;
}
assert( pCur!=0 && pCur->pPage!=0 );
assert( pCur->eState==CURSOR_VALID );
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
pPage = pCur->pPage;
assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
getCellInfo(pCur);
** in the common case where no overflow pages are used.
*/
const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
if( pCur->eState==CURSOR_VALID ){
return (const void*)fetchPayload(pCur, pAmt, 0);
}
return 0;
}
const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
if( pCur->eState==CURSOR_VALID ){
return (const void*)fetchPayload(pCur, pAmt, 1);
}
int rc;
MemPage *pNewPage;
MemPage *pOldPage;
- BtShared *pBt = pCur->pBtree->pBt;
+ BtShared *pBt = pCur->pBt;
assert( sqlite3BtreeMutexHeld(pBt->mutex) );
assert( pCur->eState==CURSOR_VALID );
MemPage *pPage;
int idxParent;
- sqlite3BtreeEnter(pCur->pBtree);
+ cursorEnter(pCur);
assert( pCur->eState==CURSOR_VALID );
pPage = pCur->pPage;
assert( pPage!=0 );
pCur->info.nSize = 0;
assert( pParent->idxShift==0 );
pCur->idx = idxParent;
- sqlite3BtreeLeave(pCur->pBtree);
+ cursorLeave(pCur);
}
/*
Btree *p = pCur->pBtree;
BtShared *pBt = p->pBt;
- assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
assert( sqlite3BtreeMutexHeld(pBt->mutex) );
if( pCur->eState==CURSOR_REQUIRESEEK ){
clearCursorPosition(pCur);
int rc = SQLITE_OK;
MemPage *pPage;
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
assert( pCur->eState==CURSOR_VALID );
while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
int rc = SQLITE_OK;
MemPage *pPage;
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
assert( pCur->eState==CURSOR_VALID );
while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
int rc;
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) );
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
int rc;
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) );
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
){
int rc;
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) );
rc = moveToRoot(pCur);
if( rc ){
** Return the database connection handle for a cursor.
*/
sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
+ assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
return pCur->pBtree->pSqlite;
}
int rc;
MemPage *pPage;
+ assert( sqlite3_mutex_held(pCur->pBt->mutex) );
rc = restoreOrClearCursorPosition(pCur);
if( rc!=SQLITE_OK ){
return rc;
Pgno pgno;
MemPage *pPage;
+ assert( sqlite3_mutex_held(pCur->pBt->mutex) );
rc = restoreOrClearCursorPosition(pCur);
if( rc!=SQLITE_OK ){
return rc;
unsigned char *oldCell;
unsigned char *newCell = 0;
- sqlite3BtreeEnter(p);
+ cursorEnter(pCur);
if( pBt->inTransaction!=TRANS_WRITE ){
/* Must start a transaction before doing an insert */
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return rc;
}
assert( !pBt->readOnly );
if( !pCur->wrFlag ){
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return SQLITE_PERM; /* Cursor not open for writing */
}
if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return SQLITE_LOCKED; /* The table pCur points to has a read lock */
}
SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) ||
SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc))
){
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return rc;
}
}
end_insert:
sqlite3_free(newCell);
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return rc;
}
Btree *p = pCur->pBtree;
BtShared *pBt = p->pBt;
- sqlite3BtreeEnter(p);
+ cursorEnter(pCur);
assert( pPage->isInit );
if( pBt->inTransaction!=TRANS_WRITE ){
/* Must start a transaction before doing a delete */
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return rc;
}
assert( !pBt->readOnly );
if( pCur->idx >= pPage->nCell ){
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return SQLITE_ERROR; /* The cursor is not pointing to anything */
}
if( !pCur->wrFlag ){
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return SQLITE_PERM; /* Did not open this cursor for writing */
}
if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return SQLITE_LOCKED; /* The table pCur points to has a read lock */
}
(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 ||
(rc = sqlite3PagerWrite(pPage->pDbPage))!=0
){
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return rc;
}
}
rc = clearCell(pPage, pCell);
if( rc ){
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return rc;
}
if( rc==SQLITE_OK ){
moveToRoot(pCur);
}
- sqlite3BtreeLeave(p);
+ cursorLeave(pCur);
return rc;
}
Pgno pgnoRoot;
int rc;
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
+ assert( sqlite3_mutex_held(pBt->mutex) );
if( pBt->inTransaction!=TRANS_WRITE ){
/* Must start a transaction first */
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
*/
MemPage *pPage = pCur->pPage;
assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) );
+ assert( pPage->pBt==pCur->pBt );
return pPage ? pPage->aData[pPage->hdrOffset] : 0;
}
** testing and debugging only.
*/
Pager *sqlite3BtreePager(Btree *p){
- assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
- assert( sqlite3BtreeMutexHeld(p->pBt->mutex) );
return p->pBt->pPager;
}
/*
** Return the full pathname of the underlying database file.
+**
+** The pager filename is invariant as long as the pager is
+** open so it is safe to access without the BtShared mutex.
*/
const char *sqlite3BtreeGetFilename(Btree *p){
assert( p->pBt->pPager!=0 );
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
return sqlite3PagerFilename(p->pBt->pPager);
}
/*
** Return the pathname of the directory that contains the database file.
+**
+** The pager directory name is invariant as long as the pager is
+** open so it is safe to access without the BtShared mutex.
*/
const char *sqlite3BtreeGetDirname(Btree *p){
assert( p->pBt->pPager!=0 );
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
return sqlite3PagerDirname(p->pBt->pPager);
}
** Return the pathname of the journal file for this database. The return
** value of this routine is the same regardless of whether the journal file
** has been created or not.
+**
+** The pager journal filename is invariant as long as the pager is
+** open so it is safe to access without the BtShared mutex.
*/
const char *sqlite3BtreeGetJournalname(Btree *p){
assert( p->pBt->pPager!=0 );
+ assert( sqlite3_mutex_held(p->pSqlite->mutex) );
return sqlite3PagerJournalname(p->pBt->pPager);
}
** Return non-zero if a transaction is active.
*/
int sqlite3BtreeIsInTrans(Btree *p){
- assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
+ assert( p==0 || sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
return (p && (p->inTrans==TRANS_WRITE));
}
*/
void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
BtShared *pBt = p->pBt;
- assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) );
sqlite3BtreeEnter(p);
if( !pBt->pSchema ){
pBt->pSchema = sqlite3MallocZero(nBytes);
** to change the length of the data stored.
*/
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
- assert( sqlite3BtreeMutexHeld(pCsr->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCsr->pBt->mutex) );
assert( sqlite3BtreeMutexHeld(pCsr->pBtree->pSqlite->mutex) );
assert(pCsr->isIncrblobHandle);
if( pCsr->eState==CURSOR_REQUIRESEEK ){
if( !pCsr->wrFlag ){
return SQLITE_READONLY;
}
- assert( !pCsr->pBtree->pBt->readOnly
- && pCsr->pBtree->pBt->inTransaction==TRANS_WRITE );
+ assert( !pCsr->pBt->readOnly
+ && pCsr->pBt->inTransaction==TRANS_WRITE );
if( checkReadLocks(pCsr->pBtree, pCsr->pgnoRoot, pCsr) ){
return SQLITE_LOCKED; /* The table pCur points to has a read lock */
}
** sqlite3BtreePutData()).
*/
void sqlite3BtreeCacheOverflow(BtCursor *pCur){
- assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) );
+ assert( sqlite3BtreeMutexHeld(pCur->pBt->mutex) );
assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) );
assert(!pCur->isIncrblobHandle);
assert(!pCur->aOverflow);