aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backup.c34
-rw-r--r--src/pager.c4
2 files changed, 23 insertions, 15 deletions
diff --git a/src/backup.c b/src/backup.c
index 781b4b0bc..09e61b6c7 100644
--- a/src/backup.c
+++ b/src/backup.c
@@ -12,7 +12,7 @@
** This file contains the implementation of the sqlite3_backup_XXX()
** API functions and the related features.
**
-** $Id: backup.c,v 1.13 2009/03/16 13:19:36 danielk1977 Exp $
+** $Id: backup.c,v 1.14 2009/05/13 07:52:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"
@@ -44,6 +44,7 @@ struct sqlite3_backup {
Pgno nRemaining; /* Number of pages left to copy */
Pgno nPagecount; /* Total number of pages to copy */
+ int isAttached; /* True once backup has been registered with pager */
sqlite3_backup *pNext; /* Next backup associated with source pager */
};
@@ -157,6 +158,7 @@ sqlite3_backup *sqlite3_backup_init(
p->pDestDb = pDestDb;
p->pSrcDb = pSrcDb;
p->iNext = 1;
+ p->isAttached = 0;
if( 0==p->pSrc || 0==p->pDest ){
/* One (or both) of the named databases did not exist. An error has
@@ -167,18 +169,7 @@ sqlite3_backup *sqlite3_backup_init(
p = 0;
}
}
-
- /* If everything has gone as planned, attach the backup object to the
- ** source pager. The source pager calls BackupUpdate() and BackupRestart()
- ** to notify this module if the source file is modified mid-backup.
- */
if( p ){
- sqlite3_backup **pp; /* Pointer to head of pagers backup list */
- sqlite3BtreeEnter(p->pSrc);
- pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
- p->pNext = *pp;
- *pp = p;
- sqlite3BtreeLeave(p->pSrc);
p->pSrc->nBackup++;
}
@@ -272,6 +263,19 @@ static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
}
/*
+** Register this backup object with the associated source pager for
+** callbacks when pages are changed or the cache invalidated.
+*/
+static void attachBackupObject(sqlite3_backup *p){
+ sqlite3_backup **pp;
+ assert( sqlite3BtreeHoldsMutex(p->pSrc) );
+ pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
+ p->pNext = *pp;
+ *pp = p;
+ p->isAttached = 1;
+}
+
+/*
** Copy nPage pages from the source b-tree to the destination.
*/
int sqlite3_backup_step(sqlite3_backup *p, int nPage){
@@ -340,6 +344,8 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
p->nRemaining = nSrcPage+1-p->iNext;
if( p->iNext>(Pgno)nSrcPage ){
rc = SQLITE_DONE;
+ }else if( !p->isAttached ){
+ attachBackupObject(p);
}
}
@@ -472,12 +478,14 @@ int sqlite3_backup_finish(sqlite3_backup *p){
/* Detach this backup from the source pager. */
if( p->pDestDb ){
+ p->pSrc->nBackup--;
+ }
+ if( p->isAttached ){
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
while( *pp!=p ){
pp = &(*pp)->pNext;
}
*pp = p->pNext;
- p->pSrc->nBackup--;
}
/* If a transaction is still open on the Btree, roll it back. */
diff --git a/src/pager.c b/src/pager.c
index 0edabb3d0..9949c11f4 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.586 2009/05/06 18:57:10 shane Exp $
+** @(#) $Id: pager.c,v 1.587 2009/05/13 07:52:06 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -3622,7 +3622,7 @@ static int pagerSharedLock(Pager *pPager){
);
}
- if( sqlite3PcachePagecount(pPager->pPCache)>0 ){
+ if( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 ){
/* The shared-lock has just been acquired on the database file
** and there are already pages in the cache (from a previous
** read or write transaction). Check to see if the database