From 27641703cc92a9fca8d3c5136808692413fc945e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 22 Aug 2007 02:56:42 +0000 Subject: [PATCH] A complete run of quick.test with mutex debugging enabled. (CVS 4266) FossilOrigin-Name: 783e07d561d1f5509de9475f3b9f38315f247002 --- manifest | 40 ++++----- manifest.uuid | 2 +- src/btree.c | 196 +++++++++++++++++++++++---------------------- src/btree.h | 4 +- src/main.c | 8 +- src/mutex.c | 10 +-- src/prepare.c | 5 +- src/test1.c | 47 ++++++++++- src/test3.c | 7 +- src/vdbeapi.c | 27 ++++--- src/vtab.c | 20 +++-- test/cache.test | 4 +- test/capi3.test | 4 +- test/incrblob.test | 6 +- test/io.test | 6 +- test/speed3.test | 5 +- test/vtab1.test | 3 +- 17 files changed, 238 insertions(+), 156 deletions(-) diff --git a/manifest b/manifest index b1e1d3fcbc..1b820f53ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reenable\sthe\smemory\smanagement\slogic.\s\sThe\squick.test\sscript\snow\sruns\swith\nSQLITE_MEMDEBUG\sand\sSQLITE_ENABLE_MEMORY_MANAGEMENT.\s7\sminor\serrors.\s(CVS\s4265) -D 2007-08-22T00:39:20 +C A\scomplete\srun\sof\squick.test\swith\smutex\sdebugging\senabled.\s(CVS\s4266) +D 2007-08-22T02:56:43 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -80,8 +80,8 @@ F src/alter.c f0aac0060ae8102e58f210b44d35b53438d53173 F src/analyze.c a14237d869c6bea0846493b59317e4097e81a0b6 F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8 F src/auth.c 083c1205b45e3f52291ec539d396b4fc557856b3 -F src/btree.c e35f1d7d662681a567cafaef6dba529ccd577a0d -F src/btree.h aeb85d6a48573785666fb97566bf5802d5f9b7ca +F src/btree.c 3e935a3074bfa498e74dc70f441cab64d364eab1 +F src/btree.h 76c89673981cb77575300c0b78a76eaa00a28743 F src/btreeInt.h 7fc6e51dc3d4bbed15639a8ea1aae737631d6670 F src/build.c 2159551184160e2cf17ff945e9a05fbe6f331c3d F src/callback.c fdd527372162a974094103eae82119fcfcf11260 @@ -97,12 +97,12 @@ F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c F src/legacy.c a83519a8fbb488c3155fca577b010d590ec479e9 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35 F src/loadext.c dd803303fd06ef0b13913faaa4a7fc7d8c8c4e77 -F src/main.c 316381eeaf9c166a9edfe0e7d65b363432ed95ca +F src/main.c ea11ee57f35ba85feb3c1f8ca81ac9caad718be2 F src/malloc.c f5ace943194fba04f09b590496a751a5ed6734f1 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217 F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe F src/mem2.c 482f0aaf14e8ef1db64cb8c5b9a9bfe708297c92 -F src/mutex.c 839c4226939081a4b736bb7ab6520b2f835be8ae +F src/mutex.c 9cf641f556a4119ef90ed41b82f2d5647f81686e F src/os.c 89b93d67bc436c2d9df4b5d296f30a59144e55bb F src/os.h 399c89cafa93b9ef35c3dc70f77644d10936b535 F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c @@ -118,7 +118,7 @@ F src/pager.c d68e8c7b7e258c3e22c7872b602ff1b00d6cb41a F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8 F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590 F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5 -F src/prepare.c 7c11bab711f44ef12950816a8cfe495ccb295648 +F src/prepare.c 29ea14cf6b0558f2f80aa53e112bff55f1119e36 F src/printf.c a8f46e0ed360c18d40e89aa636533be300b406c2 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2 @@ -130,9 +130,9 @@ F src/sqliteInt.h 23eb6a5b1f10d5d3d34c3c7846b7c3b93acf1276 F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008 F src/tclsqlite.c 92e06e076d613484aa2afc5ad830d9080de92347 -F src/test1.c d665d85c7a4e4aef588d5c6f01761082358d291d +F src/test1.c d7b8d6d15d10cc2e21f7a20a09c914d5aa84f1e2 F src/test2.c 4f742e99ed1bea5c14692f627bdb59a146f30504 -F src/test3.c 2e4da0fe90a0aa8cf9276ea34cbe92e91dc1db07 +F src/test3.c a7d011c51d6b2e2a73c43983d5c2b731d69c74d7 F src/test4.c d97b87919dc3db1cc5fccc04a33f030d5940e1a9 F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4 F src/test6.c da83a0e49c03e8a25f4ce6e25c537c6617c14fc0 @@ -159,12 +159,12 @@ F src/vacuum.c 318ccae7c4e3ddf241aeaee4d2611bfe1949a373 F src/vdbe.c 9d4d00589c174aad9a616f1615464ddddebba0ec F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3 F src/vdbeInt.h 39fb069ce04137545ca0bc790f80ddc64a8c99d9 -F src/vdbeapi.c 62cc5b08fc33c05fe8a74b6bd78aff5e0c0ba4f2 +F src/vdbeapi.c 81cb7f018e56c20b40365f005ff69e1af9ea9494 F src/vdbeaux.c b0aeed4ff33352904b392ee6c7408bae5b141b9b F src/vdbeblob.c d12ed95dac0992e1e372d079d76af047cc42f7c7 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6 F src/vdbemem.c 3de25d78e7b1d0af7a05199de905cea8c43aed5d -F src/vtab.c ee29237ecc9b310dc43c0c2ac5caa6c6a20787be +F src/vtab.c 8f80924af48fc2295d36f6fe360d3c99ae968f9d F src/where.c 2776a0caf8cbbfd6ec79cfb1cd9bc25074055e5e F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -204,9 +204,9 @@ F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f F test/btree8.test fadc112bcbd6a0c622d34c813fc8a648eacf8804 F test/btree9.test 5d8711b241145b90f65dd1795d5dd8290846fa5e F test/busy.test 0271c854738e23ad76e10d4096a698e5af29d211 -F test/cache.test 008668c54b38ba5b4c1134ba51447b01ac5520ec +F test/cache.test 3ff445c445742a7b6b9ba6e1d62a25263f9424b9 F test/capi2.test 3c5066836cbaa9923bcc8282c010aa227bb5efd4 -F test/capi3.test f4e77c300d870653f9fc1b20bef6788f0790b3f1 +F test/capi3.test b436e762c01a9cb2235d4de8b55af3b887f0e384 F test/capi3b.test 664eb55318132f292f2c436f90906f578cad6b97 F test/capi3c.test 76a3fb94755288a2977ee387e95305e6224c0198 F test/cast.test c4780b58b569bab4947458195410ae8791ac216b @@ -303,7 +303,7 @@ F test/hook.test 7e7645fd9a033f79cce8fdff151e32715e7ec50a F test/icu.test e6bfae7f625c88fd14df6f540fe835bdfc1e4329 F test/in.test 369cb2aa1eab02296b4ec470732fe8c131260b1d F test/in2.test b1f447f4f0f67e9f83ff931e7e2e30873f9ea055 -F test/incrblob.test 4d3d19f4001fe038cfed54f2119b0ec090317577 +F test/incrblob.test 7f95c929b719626443a996b105d2b0ff06f47818 F test/incrblob_err.test 2501bec57e317e7051451b5093b47fc61a96c85a F test/incrvacuum.test 569347726ea5940c3359e3d8cabb3505595cb82f F test/incrvacuum2.test 82397ceb5941cbe852fd29bb33fcdf5665bc80c2 @@ -317,7 +317,7 @@ F test/insert3.test 72ea6056811fd234f80d923f977c196089947381 F test/insert4.test 1e27f0a3e5670d5f03c1636f699aa44270945bca F test/interrupt.test 81555fb0f8179bb2d0dc7151fd75428223f93cf2 F test/intpkey.test af4fd826c4784ec5c93b444de07adea0254d0d30 -F test/io.test b2f21c23f920541ba64e7b3251674bd8773c6bc8 +F test/io.test 6b7ee16f78560c4b81b52da2ea1051b8a2a93ce3 F test/ioerr.test 491d42c49bbec598966d26b01ed7901f55e5ee2d F test/ioerr2.test f938eadb12108048813869b86beee4a2f98e34b8 F test/join.test af0443185378b64878750aa1cf4b83c216f246b4 @@ -401,7 +401,7 @@ F test/softheap1.test 0c49aa6eee25e7d32943e85e8d1f20eff566b1dc F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 F test/speed1.test 22e1b27af0683ed44dcd2f93ed817a9c3e65084a F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded -F test/speed3.test 27a71b5cc83c1f23baf6d0ee52e2f195e3c415f2 +F test/speed3.test 55e039b34d505aa442cee415f83c451ae28b3123 F test/sqllimits1.test c74c7cdbb23406c5408d2d9ddbe7da5b5a946c46 F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797 F test/subselect.test 974e87f8fc91c5f00dd565316d396a5a6c3106c4 @@ -461,7 +461,7 @@ F test/vacuum.test cf839fc3ff24d601057319bbb5c700ce9c8e0fb0 F test/vacuum2.test e198d81a1cbc3f3f6b8aeee27cadfffea8995d42 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/view.test 852bd4101e6d171c46ad682eb5c5faf662b2eba4 -F test/vtab1.test e740d4761b9125e6e541c62d199a3822f54614ff +F test/vtab1.test f05e77fa16c6e5a6a7fea4b5e9a97f36ee78fdae F test/vtab2.test 94bb3bf691ac10e34cf7dad46b1cf94b861d513c F test/vtab3.test f38d6d7d19f08bffdadce4d5b8cba078f8118587 F test/vtab4.test a9d7104d41a787754a734740d7aa61c807a69f87 @@ -558,7 +558,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 0f7941aef976aa4f3be3e0046edd1ae042e5d9a3 -R a1e419f66e7c78d94227b10198dd19bc +P 1914044b8832041f13b20ead613bd13725425d7a +R da84160f0df065e75198c0663969de9f U drh -Z 60989ee4c1d273be71e169d0d08476db +Z 4868a722cbf9dfdb786e2878b91cc4b4 diff --git a/manifest.uuid b/manifest.uuid index aaeb86537e..95be549187 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1914044b8832041f13b20ead613bd13725425d7a \ No newline at end of file +783e07d561d1f5509de9475f3b9f38315f247002 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c99e3ca0fe..0dd2299e1c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.407 2007/08/22 00:39:20 drh Exp $ +** $Id: btree.c,v 1.408 2007/08/22 02:56:43 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -96,7 +96,7 @@ static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){ BtShared *pBt = p->pBt; BtLock *pIter; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); /* This is a no-op if the shared-cache is not enabled */ if( !p->sharable ){ @@ -148,7 +148,7 @@ static int lockTable(Btree *p, Pgno iTable, u8 eLock){ BtLock *pLock = 0; BtLock *pIter; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); /* This is a no-op if the shared-cache is not enabled */ if( !p->sharable ){ @@ -214,7 +214,7 @@ static int lockTable(Btree *p, Pgno iTable, u8 eLock){ static void unlockAllTables(Btree *p){ BtLock **ppIter = &p->pBt->pLock; - assert( sqlite3_mutex_held(p->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pBt->mutex) ); assert( p->sharable || 0==*ppIter ); while( *ppIter ){ @@ -246,7 +246,7 @@ static void invalidateOverflowCache(BtCursor *pCur){ */ static void invalidateAllOverflowCache(BtShared *pBt){ BtCursor *p; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); for(p=pBt->pCursor; p; p=p->pNext){ invalidateOverflowCache(p); } @@ -265,7 +265,7 @@ static int saveCursorPosition(BtCursor *pCur){ assert( CURSOR_VALID==pCur->eState ); assert( 0==pCur->pKey ); - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); @@ -307,7 +307,7 @@ static int saveCursorPosition(BtCursor *pCur){ */ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ BtCursor *p; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); for(p=pBt->pCursor; p; p=p->pNext){ if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) && p->eState==CURSOR_VALID ){ @@ -324,7 +324,7 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ ** Clear the current cursor position. */ static void clearCursorPosition(BtCursor *pCur){ - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); sqlite3_free(pCur->pKey); pCur->pKey = 0; pCur->eState = CURSOR_INVALID; @@ -372,7 +372,7 @@ int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){ */ static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ int nPagesPerMapPage, iPtrMap, ret; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); nPagesPerMapPage = (pBt->usableSize/5)+1; iPtrMap = (pgno-2)/nPagesPerMapPage; ret = (iPtrMap*nPagesPerMapPage) + 2; @@ -396,7 +396,7 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){ int offset; /* Offset in pointer map page */ int rc; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); /* The master-journal page number must never be used as a pointer map page */ assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) ); @@ -439,7 +439,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ int offset; /* Offset of entry in pointer map */ int rc; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); iPtrmap = PTRMAP_PAGENO(pBt, key); rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage); @@ -483,7 +483,7 @@ u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell){ */ static u8 *findOverflowCell(MemPage *pPage, int iCell){ int i; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); for(i=pPage->nOverflow-1; i>=0; i--){ int k; struct _OvflCell *pOvfl; @@ -516,7 +516,7 @@ void sqlite3BtreeParseCellPtr( int n; /* Number bytes in cell content header */ u32 nPayload; /* Number of bytes of cell payload */ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); pInfo->pCell = pCell; assert( pPage->leaf==0 || pPage->leaf==1 ); @@ -630,7 +630,7 @@ static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){ */ static int ptrmapPutOvfl(MemPage *pPage, int iCell){ u8 *pCell; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); pCell = findOverflowCell(pPage, iCell); return ptrmapPutOvflPtr(pPage, pCell); } @@ -660,7 +660,7 @@ static int defragmentPage(MemPage *pPage){ assert( pPage->pBt!=0 ); assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); assert( pPage->nOverflow==0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); temp = sqlite3_malloc( pPage->pBt->pageSize ); if( temp==0 ) return SQLITE_NOMEM; data = pPage->aData; @@ -717,7 +717,7 @@ static int allocateSpace(MemPage *pPage, int nByte){ data = pPage->aData; assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); if( nByte<4 ) nByte = 4; if( pPage->nFreenOverflow>0 ) return 0; pPage->nFree -= nByte; @@ -776,7 +776,7 @@ static void freeSpace(MemPage *pPage, int start, int size){ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) ); assert( (start + size)<=pPage->pBt->usableSize ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); if( size<4 ) size = 4; #ifdef SQLITE_SECURE_DELETE @@ -837,7 +837,7 @@ static void decodeFlags(MemPage *pPage, int flagByte){ BtShared *pBt; /* A copy of pPage->pBt */ assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); pPage->intKey = (flagByte & (PTF_INTKEY|PTF_LEAFDATA))!=0; pPage->zeroData = (flagByte & PTF_ZERODATA)!=0; pPage->leaf = (flagByte & PTF_LEAF)!=0; @@ -884,7 +884,7 @@ int sqlite3BtreeInitPage( pBt = pPage->pBt; assert( pBt!=0 ); assert( pParent==0 || pParent->pBt==pBt ); - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] ); if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){ @@ -955,7 +955,7 @@ static void zeroPage(MemPage *pPage, int flags){ assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); assert( &data[pBt->pageSize] == (unsigned char*)pPage ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); memset(&data[hdr], 0, pBt->usableSize - hdr); data[hdr] = flags; first = hdr + 8 + 4*((flags&PTF_LEAF)==0); @@ -993,7 +993,7 @@ int sqlite3BtreeGetPage( MemPage *pPage; DbPage *pDbPage; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, noContent); if( rc ) return rc; pPage = (MemPage *)sqlite3PagerGetExtra(pDbPage); @@ -1018,7 +1018,7 @@ static int getAndInitPage( MemPage *pParent /* Parent of the page */ ){ int rc; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); if( pgno==0 ){ return SQLITE_CORRUPT_BKPT; } @@ -1038,7 +1038,7 @@ static void releasePage(MemPage *pPage){ assert( pPage->aData ); assert( pPage->pBt ); assert( &pPage->aData[pPage->pBt->pageSize]==(unsigned char*)pPage ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); sqlite3PagerUnref(pPage->pDbPage); } } @@ -1054,7 +1054,7 @@ static void pageDestructor(DbPage *pData, int pageSize){ pPage = (MemPage *)sqlite3PagerGetExtra(pData); if( pPage->pParent ){ MemPage *pParent = pPage->pParent; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); pPage->pParent = 0; releasePage(pParent); } @@ -1074,7 +1074,7 @@ static void pageReinit(DbPage *pData, int pageSize){ assert( (pageSize & 7)==0 ); pPage = (MemPage *)sqlite3PagerGetExtra(pData); if( pPage->isInit ){ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); pPage->isInit = 0; sqlite3BtreeInitPage(pPage, pPage->pParent); } @@ -1107,7 +1107,7 @@ int sqlite3BtreeOpen( }else{ pVfs = sqlite3_vfs_find(0); } - assert( pSqlite==0 || sqlite3_mutex_held(pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pSqlite->mutex) ); /* Set the variable isMemdb to true for an in-memory database, or ** false for a file-based database. This symbol is only required if @@ -1420,7 +1420,7 @@ void sqlite3BtreeEnter(Btree *p){ assert( p->sharable || p->wantToLock==0 ); /* We should already hold a lock on the database connection */ - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) ); if( !p->sharable ) return; p->wantToLock++; @@ -1683,7 +1683,7 @@ static int lockBtree(BtShared *pBt){ int rc, pageSize; MemPage *pPage1; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); if( pBt->pPage1 ) return SQLITE_OK; rc = sqlite3BtreeGetPage(pBt, 1, &pPage1, 0); if( rc!=SQLITE_OK ) return rc; @@ -1760,8 +1760,8 @@ page1_init_failed: static int lockBtreeWithRetry(Btree *pRef){ int rc = SQLITE_OK; - assert( sqlite3_mutex_held(pRef->pSqlite->mutex) ); - assert( sqlite3_mutex_held(pRef->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pRef->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pRef->pBt->mutex) ); if( pRef->inTrans==TRANS_NONE ){ u8 inTransaction = pRef->pBt->inTransaction; btreeIntegrity(pRef); @@ -1788,7 +1788,7 @@ static int lockBtreeWithRetry(Btree *pRef){ ** If there is a transaction in progress, this routine is a no-op. */ static void unlockBtreeIfUnused(BtShared *pBt){ - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){ if( sqlite3PagerRefcount(pBt->pPager)>=1 ){ if( pBt->pPage1->aData==0 ){ @@ -1813,7 +1813,7 @@ static int newDatabase(BtShared *pBt){ unsigned char *data; int rc; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); if( sqlite3PagerPagecount(pBt->pPager)>0 ) return SQLITE_OK; pP1 = pBt->pPage1; assert( pP1!=0 ); @@ -1962,7 +1962,7 @@ static int setChildPtrmaps(MemPage *pPage){ int isInitOrig = pPage->isInit; Pgno pgno = pPage->pgno; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); rc = sqlite3BtreeInitPage(pPage, pPage->pParent); if( rc!=SQLITE_OK ){ goto set_child_ptrmaps_out; @@ -2010,7 +2010,7 @@ set_child_ptrmaps_out: ** overflow page in the list. */ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); if( eType==PTRMAP_OVERFLOW2 ){ /* The pointer is always the first 4 bytes of the page in this case. */ if( get4byte(pPage->aData)!=iFrom ){ @@ -2076,7 +2076,7 @@ static int relocatePage( assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); /* 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", @@ -2155,7 +2155,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin){ Pgno iLastPg; /* Last page in the database */ Pgno nFreeList; /* Number of pages still on the free-list */ - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); iLastPg = pBt->nTrunc; if( iLastPg==0 ){ iLastPg = sqlite3PagerPagecount(pBt->pPager); @@ -2281,7 +2281,7 @@ static int autoVacuumCommit(BtShared *pBt, Pgno *pnTrunc){ int nRef = sqlite3PagerRefcount(pPager); #endif - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); invalidateAllOverflowCache(pBt); assert(pBt->autoVacuum); if( !pBt->incrVacuum ){ @@ -2685,7 +2685,7 @@ static int btreeCursor( BtCursor *pCur; BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); *ppCur = 0; if( wrFlag ){ if( pBt->readOnly ){ @@ -2936,7 +2936,7 @@ static int getOverflowPage( Pgno next = 0; int rc; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); /* One of these must not be NULL. Otherwise, why call this function? */ assert(ppPage || pPgnoNext); @@ -3076,7 +3076,7 @@ static int accessPayload( assert( pCur->eState==CURSOR_VALID ); assert( pCur->idx>=0 && pCur->idxnCell ); assert( offset>=0 ); - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); getCellInfo(pCur); aPayload = pCur->info.pCell + pCur->info.nHeader; @@ -3274,7 +3274,7 @@ static const unsigned char *fetchPayload( assert( pCur!=0 && pCur->pPage!=0 ); assert( pCur->eState==CURSOR_VALID ); - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); pPage = pCur->pPage; assert( pCur->idx>=0 && pCur->idxnCell ); getCellInfo(pCur); @@ -3314,14 +3314,14 @@ static const unsigned char *fetchPayload( ** in the common case where no overflow pages are used. */ const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){ - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); if( pCur->eState==CURSOR_VALID ){ return (const void*)fetchPayload(pCur, pAmt, 0); } return 0; } const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){ - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); if( pCur->eState==CURSOR_VALID ){ return (const void*)fetchPayload(pCur, pAmt, 1); } @@ -3339,7 +3339,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ MemPage *pOldPage; BtShared *pBt = pCur->pBtree->pBt; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); assert( pCur->eState==CURSOR_VALID ); rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage); if( rc ) return rc; @@ -3368,7 +3368,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ int sqlite3BtreeIsRootPage(MemPage *pPage){ MemPage *pParent; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); pParent = pPage->pParent; if( pParent==0 ) return 1; if( pParent->pgno>1 ) return 0; @@ -3415,8 +3415,8 @@ static int moveToRoot(BtCursor *pCur){ Btree *p = pCur->pBtree; BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); if( pCur->eState==CURSOR_REQUIRESEEK ){ clearCursorPosition(pCur); } @@ -3459,8 +3459,8 @@ static int moveToLeftmost(BtCursor *pCur){ int rc = SQLITE_OK; MemPage *pPage; - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) ); assert( pCur->eState==CURSOR_VALID ); while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ assert( pCur->idx>=0 && pCur->idxnCell ); @@ -3485,8 +3485,8 @@ static int moveToRightmost(BtCursor *pCur){ int rc = SQLITE_OK; MemPage *pPage; - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) ); assert( pCur->eState==CURSOR_VALID ); while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); @@ -3507,8 +3507,8 @@ static int moveToRightmost(BtCursor *pCur){ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ int rc; - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) ); rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ if( pCur->eState==CURSOR_INVALID ){ @@ -3531,8 +3531,8 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ int rc; - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) ); rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ if( CURSOR_INVALID==pCur->eState ){ @@ -3584,8 +3584,8 @@ int sqlite3BtreeMoveto( ){ int rc; - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) ); rc = moveToRoot(pCur); if( rc ){ return rc; @@ -3889,7 +3889,7 @@ static int allocateBtreePage( MemPage *pTrunk = 0; MemPage *pPrevTrunk = 0; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); pPage1 = pBt->pPage1; n = get4byte(&pPage1->aData[36]); if( n>0 ){ @@ -4122,7 +4122,7 @@ static int freePage(MemPage *pPage){ int rc, n, k; /* Prepare the page for freeing */ - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); assert( pPage->pgno>1 ); pPage->isInit = 0; releasePage(pPage->pParent); @@ -4205,7 +4205,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ int nOvfl; int ovflPageSize; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); sqlite3BtreeParseCellPtr(pPage, pCell, &info); if( info.iOverflow==0 ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ @@ -4262,7 +4262,7 @@ static int fillInCell( int nHeader; CellInfo info; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); /* Fill in the header. */ nHeader = 0; @@ -4376,7 +4376,7 @@ static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){ MemPage *pThis; DbPage *pDbPage; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); assert( pNewParent!=0 ); if( pgno==0 ) return SQLITE_OK; assert( pBt->pPager!=0 ); @@ -4420,7 +4420,7 @@ static int reparentChildPages(MemPage *pPage){ BtShared *pBt = pPage->pBt; int rc = SQLITE_OK; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); if( pPage->leaf ) return SQLITE_OK; for(i=0; inCell; i++){ @@ -4455,7 +4455,7 @@ static void dropCell(MemPage *pPage, int idx, int sz){ assert( idx>=0 && idxnCell ); assert( sz==cellSize(pPage, idx) ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); data = pPage->aData; ptr = &data[pPage->cellOffset + 2*idx]; pc = get2byte(ptr); @@ -4508,7 +4508,7 @@ static int insertCell( assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( sz==cellSizePtr(pPage, pCell) ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); if( pPage->nOverflow || sz+2>pPage->nFree ){ if( pTemp ){ memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); @@ -4588,7 +4588,7 @@ static void assemblePage( u8 *data; /* Data for the page */ assert( pPage->nOverflow==0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); totalSize = 0; for(i=0; ipBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); /* Allocate a new page. Insert the overflow cell from pPage ** into it. Then remove the overflow cell from pPage. @@ -4789,7 +4789,7 @@ static int balance_nonroot(MemPage *pPage){ u8 *aFrom = 0; #endif - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); /* ** Find the parent page. @@ -5342,7 +5342,7 @@ static int balance_shallower(MemPage *pPage){ assert( pPage->pParent==0 ); assert( pPage->nCell==0 ); - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); pBt = pPage->pBt; mxCellPerPage = MX_CELL(pBt); apCell = sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(int)) ); @@ -5447,7 +5447,7 @@ static int balance_deeper(MemPage *pPage){ assert( pPage->pParent==0 ); assert( pPage->nOverflow>0 ); pBt = pPage->pBt; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0); if( rc ) return rc; assert( sqlite3PagerIswriteable(pChild->pDbPage) ); @@ -5496,7 +5496,7 @@ balancedeeper_out: */ static int balance(MemPage *pPage, int insert){ int rc = SQLITE_OK; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); if( pPage->pParent==0 ){ rc = sqlite3PagerWrite(pPage->pDbPage); if( rc==SQLITE_OK && pPage->nOverflow>0 ){ @@ -5534,8 +5534,8 @@ static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){ BtCursor *p; BtShared *pBt = pBtree->pBt; sqlite3 *db = pBtree->pSqlite; - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( sqlite3_mutex_held(db->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(db->mutex) ); for(p=pBt->pCursor; p; p=p->pNext){ if( p==pExclude ) continue; if( p->eState!=CURSOR_VALID ) continue; @@ -5939,7 +5939,7 @@ static int clearDatabasePage( unsigned char *pCell; int i; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); if( pgno>sqlite3PagerPagecount(pBt->pPager) ){ return SQLITE_CORRUPT_BKPT; } @@ -6021,7 +6021,7 @@ static int btreeDropTable(Btree *p, int iTable, int *piMoved){ MemPage *pPage = 0; BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pBt->mutex) ); if( p->inTrans!=TRANS_WRITE ){ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; } @@ -6222,7 +6222,7 @@ int sqlite3BtreeFlags(BtCursor *pCur){ ** restoreOrClearCursorPosition() here. */ MemPage *pPage = pCur->pPage; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pPage->pBt->mutex) ); return pPage ? pPage->aData[pPage->hdrOffset] : 0; } @@ -6232,8 +6232,8 @@ int sqlite3BtreeFlags(BtCursor *pCur){ ** testing and debugging only. */ Pager *sqlite3BtreePager(Btree *p){ - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - assert( sqlite3_mutex_held(p->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pBt->mutex) ); return p->pBt->pPager; } @@ -6680,7 +6680,7 @@ char *sqlite3BtreeIntegrityCheck( */ const char *sqlite3BtreeGetFilename(Btree *p){ assert( p->pBt->pPager!=0 ); - assert( sqlite3_mutex_held(p->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pBt->mutex) ); return sqlite3PagerFilename(p->pBt->pPager); } @@ -6689,7 +6689,7 @@ const char *sqlite3BtreeGetFilename(Btree *p){ */ const char *sqlite3BtreeGetDirname(Btree *p){ assert( p->pBt->pPager!=0 ); - assert( sqlite3_mutex_held(p->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pBt->mutex) ); return sqlite3PagerDirname(p->pBt->pPager); } @@ -6700,7 +6700,7 @@ const char *sqlite3BtreeGetDirname(Btree *p){ */ const char *sqlite3BtreeGetJournalname(Btree *p){ assert( p->pBt->pPager!=0 ); - assert( sqlite3_mutex_held(p->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pBt->mutex) ); return sqlite3PagerJournalname(p->pBt->pPager); } @@ -6780,8 +6780,8 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ ** Return non-zero if a transaction is active. */ int sqlite3BtreeIsInTrans(Btree *p){ - assert( sqlite3_mutex_held(p->pBt->mutex) ); - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) ); return (p && (p->inTrans==TRANS_WRITE)); } @@ -6789,8 +6789,8 @@ int sqlite3BtreeIsInTrans(Btree *p){ ** Return non-zero if a statement transaction is active. */ int sqlite3BtreeIsInStmt(Btree *p){ - assert( sqlite3_mutex_held(p->pBt->mutex) ); - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) ); return (p->pBt && p->pBt->inStmt); } @@ -6798,8 +6798,8 @@ int sqlite3BtreeIsInStmt(Btree *p){ ** Return non-zero if a read (or write) transaction is active. */ int sqlite3BtreeIsInReadTrans(Btree *p){ - assert( sqlite3_mutex_held(p->pBt->mutex) ); - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) ); return (p && (p->inTrans!=TRANS_NONE)); } @@ -6821,12 +6821,13 @@ int sqlite3BtreeIsInReadTrans(Btree *p){ */ void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ BtShared *pBt = p->pBt; - assert( sqlite3_mutex_held(pBt->mutex) ); - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) ); + sqlite3BtreeEnter(p); if( !pBt->pSchema ){ pBt->pSchema = sqlite3MallocZero(nBytes); pBt->xFreeSchema = xFree; } + sqlite3BtreeLeave(p); return pBt->pSchema; } @@ -6835,9 +6836,12 @@ void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ ** handle holds an exclusive lock on the sqlite_master table. */ int sqlite3BtreeSchemaLocked(Btree *p){ - assert( sqlite3_mutex_held(p->pBt->mutex) ); - assert( sqlite3_mutex_held(p->pSqlite->mutex) ); - return (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK); + int rc; + assert( sqlite3BtreeMutexHeld(p->pSqlite->mutex) ); + sqlite3BtreeEnter(p); + rc = (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK); + sqlite3BtreeLeave(p); + return rc; } @@ -6869,8 +6873,8 @@ int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ ** to change the length of the data stored. */ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ - assert( sqlite3_mutex_held(pCsr->pBtree->pBt->mutex) ); - assert( sqlite3_mutex_held(pCsr->pBtree->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pCsr->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCsr->pBtree->pSqlite->mutex) ); assert(pCsr->isIncrblobHandle); if( pCsr->eState==CURSOR_REQUIRESEEK ){ return SQLITE_ABORT; @@ -6907,8 +6911,8 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ ** sqlite3BtreePutData()). */ void sqlite3BtreeCacheOverflow(BtCursor *pCur){ - assert( sqlite3_mutex_held(pCur->pBtree->pBt->mutex) ); - assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pBt->mutex) ); + assert( sqlite3BtreeMutexHeld(pCur->pBtree->pSqlite->mutex) ); assert(!pCur->isIncrblobHandle); assert(!pCur->aOverflow); pCur->isIncrblobHandle = 1; diff --git a/src/btree.h b/src/btree.h index b358562553..60e0c887d0 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.85 2007/08/21 19:33:56 drh Exp $ +** @(#) $Id: btree.h,v 1.86 2007/08/22 02:56:43 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -103,9 +103,11 @@ int sqlite3BtreeLockTable(Btree *, int, u8); #if SQLITE_THREADSAFE && !defined(SQLITE_OMIT_SHARED_CACHE) void sqlite3BtreeEnter(Btree*); void sqlite3BtreeLeave(Btree*); +# define sqlite3BtreeMutexHeld(X) sqlite3_mutex_held(X) #else # define sqlite3BtreeEnter(X) # define sqlite3BtreeLeave(X) +# define sqlite3BtreeMutexHeld(X) 1 #endif const char *sqlite3BtreeGetFilename(Btree *); diff --git a/src/main.c b/src/main.c index 1793911a5d..6baea4bacc 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.394 2007/08/22 00:39:20 drh Exp $ +** $Id: main.c,v 1.395 2007/08/22 02:56:44 drh Exp $ */ #include "sqliteInt.h" #include @@ -142,6 +142,7 @@ int sqlite3_close(sqlite3 *db){ if( db->pVdbe ){ sqlite3Error(db, SQLITE_BUSY, "Unable to close due to unfinalised statements"); + sqlite3_mutex_leave(db->mutex); return SQLITE_BUSY; } assert( !sqlite3SafetyCheck(db) ); @@ -156,6 +157,7 @@ int sqlite3_close(sqlite3 *db){ */ if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){ /* printf("DID NOT CLOSE\n"); fflush(stdout); */ + sqlite3_mutex_leave(db->mutex); return SQLITE_ERROR; } @@ -770,10 +772,10 @@ const char *sqlite3_errmsg(sqlite3 *db){ if( !db ){ return sqlite3ErrStr(SQLITE_NOMEM); } - sqlite3_mutex_enter(db->mutex); if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){ return sqlite3ErrStr(SQLITE_MISUSE); } + sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); z = (char*)sqlite3_value_text(db->pErr); if( z==0 ){ @@ -946,6 +948,7 @@ static int openDatabase( db->mallocFailed = 1; goto opendb_out; } + sqlite3_mutex_enter(db->mutex); db->pVfs = sqlite3_vfs_find(zVfs); db->errMask = 0xff; db->priorNewRowid = 0; @@ -1073,6 +1076,7 @@ static int openDatabase( #endif opendb_out: + sqlite3_mutex_leave(db->mutex); if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){ sqlite3_close(db); db = 0; diff --git a/src/mutex.c b/src/mutex.c index 4e52935c63..bbcaf22272 100644 --- a/src/mutex.c +++ b/src/mutex.c @@ -12,7 +12,7 @@ ** This file contains the C functions that implement mutexes for ** use by the SQLite core. ** -** $Id: mutex.c,v 1.7 2007/08/22 00:39:20 drh Exp $ +** $Id: mutex.c,v 1.8 2007/08/22 02:56:44 drh Exp $ */ /* ** If SQLITE_MUTEX_APPDEF is defined, then this whole module is @@ -30,11 +30,11 @@ ** Figure out what version of the code to use */ #define SQLITE_MUTEX_NOOP 1 /* The default */ -#if 0 #if defined(SQLITE_DEBUG) && !SQLITE_THREADSAFE # undef SQLITE_MUTEX_NOOP # define SQLITE_MUTEX_NOOP_DEBUG #endif +#if 0 #if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_UNIX # undef SQLITE_MUTEX_NOOP # define SQLITE_MUTEX_PTHREAD @@ -139,9 +139,9 @@ sqlite3_mutex *sqlite3_mutex_alloc(int id){ break; } default: { - assert( id-SQLITE_MUTEX_STATIC_MASTER >= 0 ); - assert( id-SQLITE_MUTEX_STATIC_MASTER < count(aStatic) ); - pNew = &aStatic[id-SQLITE_MUTEX_STATIC_MASTER]; + assert( id-2 >= 0 ); + assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) ); + pNew = &aStatic[id-2]; pNew->id = id; break; } diff --git a/src/prepare.c b/src/prepare.c index 2609f06a03..68cd5a7fd0 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.57 2007/08/22 00:39:20 drh Exp $ +** $Id: prepare.c,v 1.58 2007/08/22 02:56:44 drh Exp $ */ #include "sqliteInt.h" #include @@ -571,6 +571,9 @@ static int sqlite3LockAndPrepare( const char **pzTail /* OUT: End of parsed string */ ){ int rc; + if( sqlite3SafetyCheck(db) ){ + return SQLITE_MISUSE; + } sqlite3_mutex_enter(db->mutex); rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail); sqlite3_mutex_leave(db->mutex); diff --git a/src/test1.c b/src/test1.c index 6f54ffc2f2..c250d2b36f 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.268 2007/08/22 00:39:21 drh Exp $ +** $Id: test1.c,v 1.269 2007/08/22 02:56:44 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -322,6 +322,45 @@ static int test_exec_printf( return TCL_OK; } +/* +** Usage: db_enter DB +** db_leave DB +** +** Enter or leave the mutex on a database connection. +*/ +static int db_enter( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + char **argv /* Text of each argument */ +){ + sqlite3 *db; + if( argc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " DB", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; + sqlite3_mutex_enter(db->mutex); + return TCL_OK; +} +static int db_leave( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + char **argv /* Text of each argument */ +){ + sqlite3 *db; + if( argc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " DB", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; + sqlite3_mutex_leave(db->mutex); + return TCL_OK; +} + /* ** Usage: sqlite3_exec DB SQL ** @@ -916,7 +955,7 @@ static int test_create_function( ** because it is not tested anywhere else. */ if( rc==SQLITE_OK ){ sqlite3_value *pVal; - pVal = sqlite3ValueNew(db); + pVal = sqlite3ValueNew(0); sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); rc = sqlite3_create_function16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), @@ -4103,8 +4142,10 @@ static int test_pager_refcounts( if( db->aDb[i].pBt==0 ){ v = -1; }else{ + sqlite3_mutex_enter(db->mutex); a = sqlite3PagerStats(sqlite3BtreePager(db->aDb[i].pBt)); v = a[0]; + sqlite3_mutex_leave(db->mutex); } Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(v)); } @@ -4158,6 +4199,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ char *zName; Tcl_CmdProc *xProc; } aCmd[] = { + { "db_enter", (Tcl_CmdProc*)db_enter }, + { "db_leave", (Tcl_CmdProc*)db_leave }, { "sqlite3_mprintf_int", (Tcl_CmdProc*)sqlite3_mprintf_int }, { "sqlite3_mprintf_int64", (Tcl_CmdProc*)sqlite3_mprintf_int64 }, { "sqlite3_mprintf_str", (Tcl_CmdProc*)sqlite3_mprintf_str }, diff --git a/src/test3.c b/src/test3.c index 3a1191fd59..a98d658e18 100644 --- a/src/test3.c +++ b/src/test3.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test3.c,v 1.80 2007/08/21 10:44:16 drh Exp $ +** $Id: test3.c,v 1.81 2007/08/22 02:56:44 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -78,6 +78,7 @@ static int btree_open( if( nRefSqlite3==1 ){ sDb.pVfs = sqlite3_vfs_find(0); sDb.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); + sqlite3_mutex_enter(sDb.mutex); } rc = sqlite3BtreeOpen(argv[1], &sDb, &pBt, flags); if( rc!=SQLITE_OK ){ @@ -116,6 +117,7 @@ static int btree_close( } nRefSqlite3--; if( nRefSqlite3==0 ){ + sqlite3_mutex_leave(sDb.mutex); sqlite3_mutex_free(sDb.mutex); sDb.mutex = 0; sqlite3_vfs_release(sDb.pVfs); @@ -124,6 +126,7 @@ static int btree_close( return TCL_OK; } + /* ** Usage: btree_begin_transaction ID ** @@ -528,6 +531,7 @@ static int btree_pager_stats( return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); + sqlite3BtreeEnter(pBt); a = sqlite3PagerStats(sqlite3BtreePager(pBt)); for(i=0; i<11; i++){ static char *zName[] = { @@ -539,6 +543,7 @@ static int btree_pager_stats( sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]); Tcl_AppendElement(interp, zBuf); } + sqlite3BtreeLeave(pBt); return TCL_OK; } diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 4091d5123f..fc7fc73f56 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -560,7 +560,10 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ pOut = &pVm->pTos[(1-vals)+i]; }else{ static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL }; - sqlite3Error(pVm->db, SQLITE_RANGE, 0); + if( pVm->db ){ + sqlite3_mutex_enter(pVm->db->mutex); + sqlite3Error(pVm->db, SQLITE_RANGE, 0); + } pOut = (Mem*)&nullMem; } return pOut; @@ -846,16 +849,15 @@ static int bindText( } sqlite3_mutex_enter(p->db->mutex); rc = vdbeUnbind(p, i); - if( rc || zData==0 ){ - return rc; + if( rc==SQLITE_OK && zData!=0 ){ + pVar = &p->aVar[i-1]; + rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); + if( rc==SQLITE_OK && encoding!=0 ){ + rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); + } + sqlite3Error(p->db, rc, 0); + rc = sqlite3ApiExit(p->db, rc); } - pVar = &p->aVar[i-1]; - rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); - if( rc==SQLITE_OK && encoding!=0 ){ - rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); - } - sqlite3Error(p->db, rc, 0); - rc = sqlite3ApiExit(p->db, rc); sqlite3_mutex_leave(p->db->mutex); return rc; } @@ -1029,17 +1031,20 @@ int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ Vdbe *pTo = (Vdbe*)pToStmt; int i, rc = SQLITE_OK; if( (pFrom->magic!=VDBE_MAGIC_RUN && pFrom->magic!=VDBE_MAGIC_HALT) - || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) ){ + || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) + || pTo->db!=pFrom->db ){ return SQLITE_MISUSE; } if( pFrom->nVar!=pTo->nVar ){ return SQLITE_ERROR; } + sqlite3_mutex_enter(pTo->db->mutex); for(i=0; rc==SQLITE_OK && inVar; i++){ sqlite3MallocDisallow(); rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); sqlite3MallocAllow(); } + sqlite3_mutex_leave(pTo->db->mutex); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); return rc; } diff --git a/src/vtab.c b/src/vtab.c index 29dbc3aa9c..ac54516fd1 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.51 2007/08/17 01:14:39 drh Exp $ +** $Id: vtab.c,v 1.52 2007/08/22 02:56:44 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -23,7 +23,10 @@ static int createModule( void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ) { - int nName = strlen(zName); + int rc, nName; + + sqlite3_mutex_enter(db->mutex); + nName = strlen(zName); Module *pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); if( pMod ){ char *zCopy = (char *)(&pMod[1]); @@ -39,7 +42,9 @@ static int createModule( sqlite3_free(pMod); sqlite3ResetInternalSchema(db, 0); } - return sqlite3ApiExit(db, SQLITE_OK); + rc = sqlite3ApiExit(db, SQLITE_OK); + sqlite3_mutex_leave(db->mutex); + return rc; } @@ -525,11 +530,14 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Parse sParse; int rc = SQLITE_OK; - Table *pTab = db->pVTab; + Table *pTab; char *zErr = 0; + sqlite3_mutex_enter(db->mutex); + pTab = db->pVTab; if( !pTab ){ sqlite3Error(db, SQLITE_MISUSE, 0); + sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE; } assert(pTab->isVirtual && pTab->nCol==0 && pTab->aCol==0); @@ -561,7 +569,9 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sParse.pNewTable = 0; assert( (rc&0xff)==rc ); - return sqlite3ApiExit(db, rc); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + return rc; } /* diff --git a/test/cache.test b/test/cache.test index 6a463aa8c3..dd51c7cd1f 100644 --- a/test/cache.test +++ b/test/cache.test @@ -9,7 +9,7 @@ # #*********************************************************************** # -# $Id: cache.test,v 1.3 2007/08/12 20:07:59 drh Exp $ +# $Id: cache.test,v 1.4 2007/08/22 02:56:44 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -22,7 +22,9 @@ sqlite3_soft_heap_limit 0 proc pager_cache_size {db} { set bt [btree_from_db $db] + db_enter $db array set stats [btree_pager_stats $bt] + db_leave $db return $stats(page) } diff --git a/test/capi3.test b/test/capi3.test index 650cf09a04..3fa8040064 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # -# $Id: capi3.test,v 1.51 2007/08/12 20:07:59 drh Exp $ +# $Id: capi3.test,v 1.52 2007/08/22 02:56:44 drh Exp $ # set testdir [file dirname $argv0] @@ -603,10 +603,8 @@ set ::ENC [execsql {pragma encoding}] db close do_test capi3-6.0 { -btree_breakpoint sqlite3 db test.db set DB [sqlite3_connection_pointer db] -btree_breakpoint sqlite3_key $DB xyzzy set sql {SELECT a FROM t1 order by rowid} set STMT [sqlite3_prepare $DB $sql -1 TAIL] diff --git a/test/incrblob.test b/test/incrblob.test index 434ac9aaa7..c4b98da0b3 100644 --- a/test/incrblob.test +++ b/test/incrblob.test @@ -9,7 +9,7 @@ # #*********************************************************************** # -# $Id: incrblob.test,v 1.13 2007/08/12 20:07:59 drh Exp $ +# $Id: incrblob.test,v 1.14 2007/08/22 02:56:44 drh Exp $ # set testdir [file dirname $argv0] @@ -96,12 +96,16 @@ do_test incrblob-1.3.10 { # proc nRead {db} { set bt [btree_from_db $db] + db_enter $db array set stats [btree_pager_stats $bt] + db_leave $db return $stats(read) } proc nWrite {db} { set bt [btree_from_db $db] + db_enter $db array set stats [btree_pager_stats $bt] + db_leave $db return $stats(write) } diff --git a/test/io.test b/test/io.test index d29f469179..1cb264fff8 100644 --- a/test/io.test +++ b/test/io.test @@ -13,7 +13,7 @@ # IO traffic generated by SQLite (making sure SQLite is not writing out # more database pages than it has to, stuff like that). # -# $Id: io.test,v 1.1 2007/08/21 13:30:07 danielk1977 Exp $ +# $Id: io.test,v 1.2 2007/08/22 02:56:44 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -21,8 +21,9 @@ source $testdir/tester.tcl set ::nWrite 0 proc nWrite {db} { set bt [btree_from_db $db] + db_enter $db array set stats [btree_pager_stats $bt] - + db_leave $db set res [expr $stats(write) - $::nWrite] set ::nWrite $stats(write) set res @@ -88,4 +89,3 @@ do_test io-1.5 { #db eval {select * from sqlite_master} {btree_tree_dump [btree_from_db db] 2} finish_test - diff --git a/test/speed3.test b/test/speed3.test index bcc621f1e2..0f8f2a84f2 100644 --- a/test/speed3.test +++ b/test/speed3.test @@ -12,7 +12,7 @@ # focus of this script is testing that the overflow-page related # enhancements added after version 3.3.17 speed things up. # -# $Id: speed3.test,v 1.2 2007/05/17 18:28:11 danielk1977 Exp $ +# $Id: speed3.test,v 1.3 2007/08/22 02:56:44 drh Exp $ # #--------------------------------------------------------------------- @@ -89,8 +89,10 @@ proc populate_t1 {db} { proc io_log {db} { + db_enter db array set stats1 [btree_pager_stats [btree_from_db db]] array set stats2 [btree_pager_stats [btree_from_db db 2]] + db_leave db # puts "1: [array get stats1]" # puts "2: [array get stats2]" puts "Incrvacuum: Read $stats1(read), wrote $stats1(write)" @@ -176,4 +178,3 @@ speed_trial speed3-2.normal $::NROW row {SELECT c FROM aux.t1} io_log db finish_test - diff --git a/test/vtab1.test b/test/vtab1.test index 98d5625fab..a30cb8d7cf 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is creating and dropping virtual tables. # -# $Id: vtab1.test,v 1.43 2007/06/27 15:53:35 danielk1977 Exp $ +# $Id: vtab1.test,v 1.44 2007/08/22 02:56:44 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -814,6 +814,7 @@ do_test vtab1.10-1 { do_test vtab1.10-2 { set rc [catch { set ptr [sqlite3_connection_pointer db] +btree_breakpoint sqlite3_declare_vtab $ptr {CREATE TABLE abc(a, b, c)} } msg] list $rc $msg