1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-01-06 08:01:16 +03:00

If an IO error occurs while locking the database and checking the cache validity, unlock the database before returning. Ticket #3030. (CVS 5083)

FossilOrigin-Name: 4ad1809192b616d1c12499825bcd0967dea76864
This commit is contained in:
danielk1977
2008-05-05 16:23:55 +00:00
parent 4abd5449e8
commit 52b472aebf
4 changed files with 56 additions and 27 deletions

View File

@@ -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

View File

@@ -1 +1 @@
198c395b01140ef48b6913c00188ba7168bfb081
4ad1809192b616d1c12499825bcd0967dea76864

View 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;
}

View 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}