mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Add the new sqlite3PagerUnrefPageOne() pager method to deal with the special
case of unreferencing page1. FossilOrigin-Name: b2e2100cf766da1cb499aec0ca0a9969d7af5d93312ab8cf895fbf4a6ffb9b2f
This commit is contained in:
31
src/pager.c
31
src/pager.c
@@ -5350,7 +5350,8 @@ int sqlite3PagerSharedLock(Pager *pPager){
|
||||
** nothing to rollback, so this routine is a no-op.
|
||||
*/
|
||||
static void pagerUnlockIfUnused(Pager *pPager){
|
||||
if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
|
||||
if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){
|
||||
assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */
|
||||
pagerUnlockAndRollback(pPager);
|
||||
}
|
||||
}
|
||||
@@ -5636,25 +5637,39 @@ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
|
||||
/*
|
||||
** Release a page reference.
|
||||
**
|
||||
** If the number of references to the page drop to zero, then the
|
||||
** page is added to the LRU list. When all references to all pages
|
||||
** are released, a rollback occurs and the lock on the database is
|
||||
** removed.
|
||||
** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be
|
||||
** used if we know that the page being released is not the last page.
|
||||
** The btree layer always holds page1 open until the end, so these first
|
||||
** to routines can be used to release any page other than BtShared.pPage1.
|
||||
**
|
||||
** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine
|
||||
** checks the total number of outstanding pages and if the number of
|
||||
** pages reaches zero it drops the database lock.
|
||||
*/
|
||||
void sqlite3PagerUnrefNotNull(DbPage *pPg){
|
||||
Pager *pPager;
|
||||
TESTONLY( Pager *pPager = pPg->pPager; )
|
||||
assert( pPg!=0 );
|
||||
pPager = pPg->pPager;
|
||||
if( pPg->flags & PGHDR_MMAP ){
|
||||
assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */
|
||||
pagerReleaseMapPage(pPg);
|
||||
}else{
|
||||
sqlite3PcacheRelease(pPg);
|
||||
}
|
||||
pagerUnlockIfUnused(pPager);
|
||||
/* Do not use this routine to release the last reference to page1 */
|
||||
assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
|
||||
}
|
||||
void sqlite3PagerUnref(DbPage *pPg){
|
||||
if( pPg ) sqlite3PagerUnrefNotNull(pPg);
|
||||
}
|
||||
void sqlite3PagerUnrefPageOne(DbPage *pPg){
|
||||
Pager *pPager;
|
||||
assert( pPg!=0 );
|
||||
assert( pPg->pgno==1 );
|
||||
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
|
||||
pPager = pPg->pPager;
|
||||
sqlite3PcacheRelease(pPg);
|
||||
pagerUnlockIfUnused(pPager);
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called at the start of every write transaction.
|
||||
|
Reference in New Issue
Block a user