From: drh Date: Fri, 29 Jan 2010 21:23:35 +0000 (+0000) Subject: Fix a missing mutex on page cache truncation during vacuum and auto-vacuum X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10f1b20a69950e699a7f8ed756f298c65b69b66d;p=thirdparty%2Fsqlite.git Fix a missing mutex on page cache truncation during vacuum and auto-vacuum when SQLITE_ENABLE_MEMORY_MANAGEMENT is engaged. FossilOrigin-Name: ea3b941a7182851117fab9851e98e175ebb356e2 --- diff --git a/manifest b/manifest index 66ecdfc09e..a5dbb16448 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Version\s3.5.9\s(CVS\s5131) -D 2008-05-14T16:18:11 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Fix\sa\smissing\smutex\son\spage\scache\struncation\sduring\svacuum\sand\sauto-vacuum\s\nwhen\sSQLITE_ENABLE_MEMORY_MANAGEMENT\sis\sengaged. +D 2010-01-29T21:23:35 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 79aeba12300a54903f1b1257c1e7c190234045dd F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -121,7 +124,7 @@ F src/os_common.h e8b748b2f2ecc8a498e50bfe5d8721f189c19d2a F src/os_os2.c 0c3a5802bc4fdb7cb5f66771552b081c4e48a216 F src/os_unix.c a810e2aefdaddacf479407f76f8f4ca381d231b2 F src/os_win.c 3a60bddd07ea6f8adb2314dd5996ac97b988f403 -F src/pager.c 2607309c4848bfb8a5766d94d74157b54a44c6c0 +F src/pager.c 38743db63f91064ed68dba0b415cccf603be036a F src/pager.h 4f051fd856de6fd3c19aef5f82eace54122b9173 F src/parse.y fc4bd35c6088901f7c8daead26c6fb11c87d22e7 F src/pragma.c 2e4bb2e76e48a32750529fdc4bfe86ac5f54e01b @@ -634,7 +637,18 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P e4aab150042bd22868ab02645151cb69a1c02ba0 -R c25ac8c50b83839e3cddbf23a801f9cb +P b6129f4cc28f6ba55d19039545555b33857ffd72 +R 298ea4553820c86bc49de9db5217cdcf +T *bgcolor * #8696fe +T *branch * branch-3.5.9 +T *sym-branch-3.5.9 * +T -sym-trunk * U drh -Z 5d9759a5b998826f7607e53c2a3b8fed +Z bc97c693bc947a5ae3e3ed014689d2e7 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFLY1HaoxKgR168RlERAoniAJwOUHTFrCPOA7r6/18Q/Dp5vxUEAwCdGNnZ +0OTkC0QU7xRU5btnXdQ92nY= +=Y3Su +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index b6a07d33f1..d56c3d99d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6129f4cc28f6ba55d19039545555b33857ffd72 \ No newline at end of file +ea3b941a7182851117fab9851e98e175ebb356e2 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index a8d7b4200e..f89101e3a6 100644 --- a/src/pager.c +++ b/src/pager.c @@ -403,6 +403,7 @@ struct Pager { Pager *pPrev; /* sqlite3_release_memory() will work */ int iInUseMM; /* Non-zero if unavailable to MM */ int iInUseDB; /* Non-zero if in sqlite3_release_memory() */ + u8 onPagerList; /* True if part of the sqlite3PagerList */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ char dbFileVers[16]; /* Changes whenever database file changes */ @@ -511,6 +512,10 @@ static const unsigned char aJournalMagic[] = { ** function. It does not prevent, for example, two Btrees from accessing ** the same pager at the same time. Other general-purpose mutexes in ** the btree layer handle that chore. +** +** The pagerMutexHeld(X) macro is for sanity checking. This macro verifies +** that the database-connection mutex is held for pager X and asserts if it +** is not. */ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT static void pagerEnter(Pager *p){ @@ -531,9 +536,11 @@ static const unsigned char aJournalMagic[] = { p->iInUseDB--; assert( p->iInUseDB>=0 ); } +# define pagerMutexHeld(X) assert( (X)->iInUseDB>0 || !(X)->onPagerList ) #else # define pagerEnter(X) # define pagerLeave(X) +# define pagerMutexHeld(X) #endif /* @@ -1273,6 +1280,7 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ static void pager_reset(Pager *pPager){ PgHdr *pPg, *pNext; if( pPager->errCode ) return; + pagerMutexHeld(pPager); for(pPg=pPager->pAll; pPg; pPg=pNext){ IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno)); PAGER_INCR(sqlite3_pager_pgfree_count); @@ -2373,6 +2381,7 @@ int sqlite3PagerOpen( } pPager->pPrev = 0; sqlite3PagerList = pPager; + pPager->onPagerList = 1; sqlite3_mutex_leave(mutex); } #endif @@ -2637,6 +2646,7 @@ static void pager_truncate_cache(Pager *pPager){ PgHdr **ppPg; int dbSize = pPager->dbSize; + pagerMutexHeld(pPager); ppPg = &pPager->pAll; while( (pPg = *ppPg)!=0 ){ if( pPg->pgno<=dbSize ){ @@ -2707,7 +2717,9 @@ int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){ } if( MEMDB ){ pPager->dbSize = nPage; + pagerEnter(pPager); pager_truncate_cache(pPager); + pagerLeave(pPager); return SQLITE_OK; } pagerEnter(pPager); @@ -2720,12 +2732,10 @@ int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){ /* Get an exclusive lock on the database before truncating. */ pagerEnter(pPager); rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); - pagerLeave(pPager); - if( rc!=SQLITE_OK ){ - return rc; + if( rc==SQLITE_OK ){ + rc = pager_truncate(pPager, nPage); } - - rc = pager_truncate(pPager, nPage); + pagerLeave(pPager); return rc; } @@ -2759,6 +2769,7 @@ int sqlite3PagerClose(Pager *pPager){ pPager->pNext->pPrev = pPager->pPrev; } sqlite3_mutex_leave(mutex); + pPager->onPagerList = 0; } #endif