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:
14
manifest
14
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
|
||||
|
||||
@@ -1 +1 @@
|
||||
198c395b01140ef48b6913c00188ba7168bfb081
|
||||
4ad1809192b616d1c12499825bcd0967dea76864
|
||||
36
src/pager.c
36
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.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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user