diff options
author | danielk1977 <danielk1977@noemail.net> | 2009-03-23 17:11:26 +0000 |
---|---|---|
committer | danielk1977 <danielk1977@noemail.net> | 2009-03-23 17:11:26 +0000 |
commit | a8bbef84bf3214905ceb9ea32fc249010dbde41a (patch) | |
tree | 14594a477429fb069f01068b39d30e208ffde5f0 /test/notify2.test | |
parent | bc73971db6162bf60d775775b180cea06615b29c (diff) | |
download | sqlite-a8bbef84bf3214905ceb9ea32fc249010dbde41a.tar.gz sqlite-a8bbef84bf3214905ceb9ea32fc249010dbde41a.zip |
Fix an obscure race condition that can occur when multiple threads, shared cache and DDL statements are combined. Enhance notify2.test to test this scenario. (CVS 6373)
FossilOrigin-Name: 92ec5975123284aff3a69ee16c397d9e2a844c0b
Diffstat (limited to 'test/notify2.test')
-rw-r--r-- | test/notify2.test | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/test/notify2.test b/test/notify2.test index 8b508b2bc..a079c36f2 100644 --- a/test/notify2.test +++ b/test/notify2.test @@ -9,7 +9,7 @@ # #*********************************************************************** # -# $Id: notify2.test,v 1.2 2009/03/19 07:58:31 danielk1977 Exp $ +# $Id: notify2.test,v 1.3 2009/03/23 17:11:27 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -62,6 +62,8 @@ set ThreadProgram { set lRes [list] set rc SQLITE_OK +set sql $zSql + while {$rc=="SQLITE_OK" && $zSql ne ""} { set STMT [$::xPrepare $db $zSql -1 zSql] while {[set rc [$::xStep $STMT]] eq "SQLITE_ROW"} { @@ -72,22 +74,33 @@ set ThreadProgram { set rc [sqlite3_finalize $STMT] } - if {$rc != "SQLITE_OK"} { error "$rc [sqlite3_errmsg $db]" } + if {$rc != "SQLITE_OK"} { error "$rc $sql [sqlite3_errmsg $db]" } return $lRes } + proc execsql_retry {db sql} { + set msg "SQLITE_LOCKED blah..." + while { [string match SQLITE_LOCKED* $msg] } { + catch { execsql_blocking $db $sql } msg + } + } + proc select_one {args} { set n [llength $args] lindex $args [expr int($n*rand())] } - # Open a database connection. Attach the two auxillary databases. - set ::DB [sqlite3_open test.db] - execsql_blocking $::DB { - ATTACH 'test2.db' AS aux2; - ATTACH 'test3.db' AS aux3; + proc opendb {} { + # Open a database connection. Attach the two auxillary databases. + set ::DB [sqlite3_open test.db] + execsql_retry $::DB { ATTACH 'test2.db' AS aux2; } + execsql_retry $::DB { ATTACH 'test3.db' AS aux3; } } + opendb + + #after 2000 + # This loop runs for ~20 seconds. # set iStart [clock_seconds] @@ -108,12 +121,11 @@ set ThreadProgram { } { DELETE FROM xxx WHERE a<(SELECT max(a)-100 FROM xxx); INSERT INTO xxx SELECT NULL, total(a) FROM xxx; - } -# { -# CREATE INDEX IF NOT EXISTS yyy.xxx_i ON xxx(b); -# } { -# DROP INDEX IF EXISTS yyy.xxx_i; -# } + } { + CREATE INDEX IF NOT EXISTS yyy.xxx_i ON xxx(b); + } { + DROP INDEX IF EXISTS yyy.xxx_i; + } ]] } @@ -128,9 +140,15 @@ set ThreadProgram { " } msg] - if {$rc && [string match "SQLITE_LOCKED*" $msg]} { + if {$rc && [string match "SQLITE_LOCKED*" $msg] + || [string match "SQLITE_SCHEMA*" $msg] + } { # Hit an SQLITE_LOCKED error. Rollback the current transaction. - execsql_blocking $::DB ROLLBACK + set rc [catch { execsql_blocking $::DB ROLLBACK } msg] + if {$rc && [string match "SQLITE_LOCKED*" $msg]} { + sqlite3_close $::DB + opendb + } } elseif {$rc} { # Hit some other kind of error. This is a malfunction. error $msg @@ -150,7 +168,7 @@ set ThreadProgram { foreach {iTest xStep xPrepare} { 1 sqlite3_blocking_step sqlite3_blocking_prepare_v2 - 2 sqlite3_step sqlite3_prepare_v2 + 2 sqlite3_step sqlite3_nonblocking_prepare_v2 } { file delete -force test.db test2.db test3.db |