]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If an IO error occurs while locking the database and checking the cache validity...
authordanielk1977 <danielk1977@noemail.net>
Mon, 5 May 2008 16:23:55 +0000 (16:23 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 5 May 2008 16:23:55 +0000 (16:23 +0000)
FossilOrigin-Name: 4ad1809192b616d1c12499825bcd0967dea76864

manifest
manifest.uuid
src/pager.c
test/tester.tcl

index de362930cc05493524991df4e761cfa16b388500..2c51680bcfa978d1a11cddcfa9129121bf917316 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\sleaking\spage\sreferences\safter\san\sIO\serror\sis\sencountered.\s(CVS\s5082)
-D 2008-05-05T15:26:51
+C If\san\sIO\serror\soccurs\swhile\slocking\sthe\sdatabase\sand\schecking\sthe\scache\svalidity,\sunlock\sthe\sdatabase\sbefore\sreturning.\sTicket\s#3030.\s(CVS\s5083)
+D 2008-05-05T16:23:55
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in 25b3282a4ac39388632c2fb0e044ff494d490952
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -122,7 +122,7 @@ F src/os_common.h e8b748b2f2ecc8a498e50bfe5d8721f189c19d2a
 F src/os_os2.c 41015b3fa91568761eb10cbf6ca27a0624ba0bda
 F src/os_unix.c 8cf512c4321c3114f053dc9eaae394db2dc03ebe
 F src/os_win.c 3a60bddd07ea6f8adb2314dd5996ac97b988f403
-F src/pager.c 2d495e9a439e7f5db12f02cd8efe6ae417bff26a
+F src/pager.c 5ac6728cf575afd87f8c5afe88bb768d3a641e34
 F src/pager.h 4f051fd856de6fd3c19aef5f82eace54122b9173
 F src/parse.y fc4bd35c6088901f7c8daead26c6fb11c87d22e7
 F src/pragma.c 2e4bb2e76e48a32750529fdc4bfe86ac5f54e01b
@@ -458,7 +458,7 @@ F test/tableapi.test 791f7e3891d9b70bdb43b311694bf5e9befcbc34
 F test/tclsqlite.test 3dfb48f46de4353376fad835390b493ba066b4dc
 F test/tempdb.test b88ac8a19823cf771d742bf61eef93ef337c06b1
 F test/temptable.test 19b851b9e3e64d91e9867619b2a3f5fffee6e125
-F test/tester.tcl 3f476ad2a7d8532b8de3ad7b0ed95995ee78f45b
+F test/tester.tcl 392890469221c2410759bb048bef99f5e20741a6
 F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7
 F test/thread002.test 2c4ad2c386f60f6fe268cd91c769ee35b3c1fd0b
 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
@@ -634,7 +634,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 2275fc6ee06b17da5808cecfa5570ac6439eaf74
-R 6d76420da4b019df82bc43b649a5cfb1
+P 198c395b01140ef48b6913c00188ba7168bfb081
+R 6e0e093a0f17c8e821e8c74c11e266a3
 U danielk1977
-Z 562dc8fb914e4c15e377eee1cc4d777b
+Z 67d910e4d419f070999a506a26c6b1be
index 19c861ab8d9d684c6a8c2ddef76b01561a990e6a..ce39a19acb12bdfb40ee8e64a63455ee3f408078 100644 (file)
@@ -1 +1 @@
-198c395b01140ef48b6913c00188ba7168bfb081
\ No newline at end of file
+4ad1809192b616d1c12499825bcd0967dea76864
\ No newline at end of file
index fadcf29dc94b5d1f409822bf9939704be9658e7a..fca3d3bc9e5666501056d34ae11f92cc7fbd45a7 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.438 2008/05/01 17:16:53 drh Exp $
+** @(#) $Id: pager.c,v 1.439 2008/05/05 16:23:55 danielk1977 Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -3401,6 +3401,7 @@ static int pagerSharedLock(Pager *pPager){
       if( !pPager->noReadlock ){
         rc = pager_wait_on_lock(pPager, SHARED_LOCK);
         if( rc!=SQLITE_OK ){
+          assert( pPager->state==PAGER_UNLOCK );
           return pager_error(pPager, rc);
         }
         assert( pPager->state>=SHARED_LOCK );
@@ -3411,7 +3412,8 @@ static int pagerSharedLock(Pager *pPager){
       */
       rc = hasHotJournal(pPager);
       if( rc<0 ){
-        return SQLITE_IOERR_NOMEM;
+        rc = SQLITE_IOERR_NOMEM;
+        goto failed;
       }
       if( rc==1 || isHot ){
         /* Get an EXCLUSIVE lock on the database file. At this point it is
@@ -3428,8 +3430,8 @@ static int pagerSharedLock(Pager *pPager){
         if( pPager->state<EXCLUSIVE_LOCK ){
           rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
           if( rc!=SQLITE_OK ){
-            pager_unlock(pPager);
-            return pager_error(pPager, rc);
+            rc = pager_error(pPager, rc);
+            goto failed;
           }
           pPager->state = PAGER_EXCLUSIVE;
         }
@@ -3463,15 +3465,12 @@ static int pagerSharedLock(Pager *pPager){
           }
         }
         if( rc!=SQLITE_OK ){
-          pager_unlock(pPager);
-          switch( rc ){
-            case SQLITE_NOMEM:
-            case SQLITE_IOERR_UNLOCK:
-            case SQLITE_IOERR_NOMEM:
-              return rc;
-            default:
-              return SQLITE_BUSY;
+          if( rc!=SQLITE_NOMEM && rc!=SQLITE_IOERR_UNLOCK 
+           && rc!=SQLITE_IOERR_NOMEM 
+          ){
+            rc = SQLITE_BUSY;
           }
+          goto failed;
         }
         pPager->journalOpen = 1;
         pPager->journalStarted = 0;
@@ -3484,7 +3483,8 @@ static int pagerSharedLock(Pager *pPager){
         */
         rc = pager_playback(pPager, 1);
         if( rc!=SQLITE_OK ){
-          return pager_error(pPager, rc);
+          rc = pager_error(pPager, rc);
+          goto failed;
         }
         assert(pPager->state==PAGER_SHARED || 
             (pPager->exclusiveMode && pPager->state>PAGER_SHARED)
@@ -3512,14 +3512,15 @@ static int pagerSharedLock(Pager *pPager){
         sqlite3PagerPagecount(pPager);
 
         if( pPager->errCode ){
-          return pPager->errCode;
+          rc = pPager->errCode;
+          goto failed;
         }
 
         if( pPager->dbSize>0 ){
           IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
           rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
           if( rc!=SQLITE_OK ){
-            return rc;
+            goto failed;
           }
         }else{
           memset(dbFileVers, 0, sizeof(dbFileVers));
@@ -3536,6 +3537,11 @@ static int pagerSharedLock(Pager *pPager){
     }
   }
 
+ failed:
+  if( rc!=SQLITE_OK ){
+    /* pager_unlock() is a no-op for exclusive mode and in-memory databases. */
+    pager_unlock(pPager);
+  }
   return rc;
 }
 
index b7039770e563ece8fc3163e48de7f8d1a83f8ae6..369ad996e3314b0a816a7f7038127e2ff3fcf6c6 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements some common TCL routines used for regression
 # testing the SQLite library
 #
-# $Id: tester.tcl,v 1.117 2008/05/05 15:26:51 danielk1977 Exp $
+# $Id: tester.tcl,v 1.118 2008/05/05 16:23:55 danielk1977 Exp $
 
 #
 # What for user input before continuing.  This gives an opportunity
@@ -684,10 +684,11 @@ proc do_ioerr_test {testname args} {
       expr { ($s && !$r && !$q) || (!$s && $r && $q) }
     } {1}
 
+    # Check that no page references were leaked. There should be 
+    # a single reference if there is still an active transaction, 
+    # or zero otherwise.
+    #
     if {$::go && $::sqlite_io_error_hardhit && $::ioerropts(-ckrefcount)} {
-      # Check that no page references were leaked. There should be 
-      # a single reference if there is still an active transaction, 
-      # or zero otherwise.
       do_test $testname.$n.4 {
         set bt [btree_from_db db]
         db_enter db
@@ -697,8 +698,30 @@ proc do_ioerr_test {testname args} {
       } [expr {[sqlite3_get_autocommit db]?0:1}]
     }
 
+    # If there is an open database handle and no open transaction, 
+    # and the pager is not running in exclusive-locking mode,
+    # check that the pager is in "unlocked" state. Theoretically,
+    # if a call to xUnlock() failed due to an IO error the underlying
+    # file may still be locked.
+    #
+    ifcapable pragma {
+      if { [info commands db] ne ""
+        && [db one {pragma locking_mode}] eq "normal"
+        && [sqlite3_get_autocommit db]
+      } {
+        do_test $testname.$n.5 {
+          set bt [btree_from_db db]
+          db_enter db
+          array set stats [btree_pager_stats $bt]
+          db_leave db
+          set stats(state)
+        } 0
+      }
+    }
+
     # If an IO error occured, then the checksum of the database should
     # be the same as before the script that caused the IO error was run.
+    #
     if {$::go && $::sqlite_io_error_hardhit && $::ioerropts(-cksum)} {
       do_test $testname.$n.5 {
         catch {db close}