-C Check\sthat\sread-only\spages\sare\snot\sbeing\smodified\s(disabled\sby\sdefault).\s(CVS\s2331)
-D 2005-02-15T02:54:15
+C Ensure\sa\sdatabase\sfile\sis\snot\struncated\swithout\san\sexclusive\slock.\r\nFix\sfor\sticket\s#1114.\s(CVS\s2332)
+D 2005-02-15T03:38:06
F Makefile.in d928187101fa3d78426cf48ca30e39d0fb714e57
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
F src/os_win.c bddeae1c3299be0fbe47077dd4e98b786a067f71
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c 69efe972d6034d8d5603f5b2a768e43e25dad0c0
+F src/pager.c 835028769569971c7dbd63d11d3517392f1cdae0
F src/pager.h 70d496f372163abb6340f474288c4bb9ea962cf7
F src/parse.y 450fc9c4d5a737be6fdba6e4b2e3de5800d4d750
F src/pragma.c 7e65c5545d83909238adf231e2a6eee6eb43e0d5
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl 3e522a06ad41992023c80ca29a048ae2331ca5bd
-P cbed92f397ec13b57771ab8b5be74c0cacf35dfd
-R f5e0bf334bc8ca4771ae6f5140466932
+P 8514a4feb2a86e93c4251c491d394e861bb65edb
+R 68447a9e1a1587fdc5cb563c6b34ab1f
U danielk1977
-Z 79138fc5bf3ab18977a8db63dd8b495b
+Z 2caaa7f8c9b8fb759f5bcfb478549a3f
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.189 2005/02/15 02:54:15 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.190 2005/02/15 03:38:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
** indicated.
*/
static int pager_truncate(Pager *pPager, int nPage){
+ assert( pPager->state>=PAGER_EXCLUSIVE );
return sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(i64)nPage);
}
/* If this is the first header read from the journal, truncate the
** database file back to it's original size.
*/
- if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
+ if( pPager->state>=PAGER_EXCLUSIVE &&
+ pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
rc = pager_truncate(pPager, mxPg);
if( rc!=SQLITE_OK ){
hdrOff = szJ;
}
-
/* Truncate the database back to its original size.
*/
- rc = pager_truncate(pPager, pPager->stmtSize);
+ if( pPager->state>=PAGER_EXCLUSIVE ){
+ rc = pager_truncate(pPager, pPager->stmtSize);
+ }
pPager->dbSize = pPager->stmtSize;
/* Figure out how many records are in the statement journal.
#define memoryTruncate(p)
#endif
+/*
+** Try to obtain a lock on a file. Invoke the busy callback if the lock
+** is currently not available. Repeate until the busy callback returns
+** false or until the lock succeeds.
+**
+** Return SQLITE_OK on success and an error code if we cannot obtain
+** the lock.
+*/
+static int pager_wait_on_lock(Pager *pPager, int locktype){
+ int rc;
+ assert( PAGER_SHARED==SHARED_LOCK );
+ assert( PAGER_RESERVED==RESERVED_LOCK );
+ assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
+ if( pPager->state>=locktype ){
+ rc = SQLITE_OK;
+ }else{
+ int busy = 1;
+ do {
+ rc = sqlite3OsLock(&pPager->fd, locktype);
+ }while( rc==SQLITE_BUSY &&
+ pPager->pBusyHandler &&
+ pPager->pBusyHandler->xFunc &&
+ pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++)
+ );
+ if( rc==SQLITE_OK ){
+ pPager->state = locktype;
+ }
+ }
+ return rc;
+}
+
/*
** Truncate the file to the number of pages specified.
*/
if( rc!=SQLITE_OK ){
return rc;
}
+
+ /* Get an exclusive lock on the database before truncating. */
+ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
rc = pager_truncate(pPager, nPage);
if( rc==SQLITE_OK ){
pPager->dbSize = nPage;
return rc;
}
-/*
-** Try to obtain a lock on a file. Invoke the busy callback if the lock
-** is currently not available. Repeate until the busy callback returns
-** false or until the lock succeeds.
-**
-** Return SQLITE_OK on success and an error code if we cannot obtain
-** the lock.
-*/
-static int pager_wait_on_lock(Pager *pPager, int locktype){
- int rc;
- assert( PAGER_SHARED==SHARED_LOCK );
- assert( PAGER_RESERVED==RESERVED_LOCK );
- assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
- if( pPager->state>=locktype ){
- rc = SQLITE_OK;
- }else{
- int busy = 1;
- do {
- rc = sqlite3OsLock(&pPager->fd, locktype);
- }while( rc==SQLITE_BUSY &&
- pPager->pBusyHandler &&
- pPager->pBusyHandler->xFunc &&
- pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++)
- );
- if( rc==SQLITE_OK ){
- pPager->state = locktype;
- }
- }
- return rc;
-}
-
/*
** Given a list of pages (connected by the PgHdr.pDirty pointer) write
** every one of those pages out to the database file and mark them all
return pager_errcode(pPager);
}
if( pPager->state==PAGER_RESERVED ){
- int rc2, rc3;
+ int rc2;
rc = pager_reload_cache(pPager);
- rc2 = pager_truncate(pPager, pPager->origDbSize);
- rc3 = pager_unwritelock(pPager);
+ rc2 = pager_unwritelock(pPager);
if( rc==SQLITE_OK ){
rc = rc2;
- if( rc3 ) rc = rc3;
}
}else{
rc = pager_playback(pPager);