From: danielk1977 Date: Mon, 10 Sep 2007 10:53:01 +0000 (+0000) Subject: Add another test file to help verify thread-safety. (CVS 4419) X-Git-Tag: version-3.6.10~1758 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e9dcd5e6e3638eb3a3c04122440fa18c94a10fdf;p=thirdparty%2Fsqlite.git Add another test file to help verify thread-safety. (CVS 4419) FossilOrigin-Name: c758cc1d885b4528c0b0ef6382119f20956d4816 --- diff --git a/manifest b/manifest index 06cdbe521f..9031bcf2df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthread001.test\sagain,\sthis\stime\sto\salso\stest\sin\sshared-cache\smode.\s(CVS\s4418) -D 2007-09-10T07:35:47 +C Add\sanother\stest\sfile\sto\shelp\sverify\sthread-safety.\s(CVS\s4419) +D 2007-09-10T10:53:02 F Makefile.in cbfb898945536a8f9ea8b897e1586dd1fdbcc5db F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -156,7 +156,7 @@ F src/test_md5.c 34599caee5b1c73dcf86ca31f55846fab8c19ef7 F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f F src/test_server.c 1020673fc02ba5bbfa5dc96ded9f54f0f3744d38 F src/test_tclvar.c b2d1115e4d489179d3f029e765211b2ad527ba59 -F src/test_thread.c cbd7ba2cb295df9c9a8e848a8886c8d0f318de27 +F src/test_thread.c a98d69cae883e53d3686fc25889a5fa5f51439f8 F src/tokenize.c 67e42600ab34f976f2b1288c499ad6c98d652f0e F src/trigger.c 724a77d54609a33bde90618934fbeddfcc729a10 F src/update.c e89b980b443d44b68bfc0b1746cdb6308e049ac9 @@ -388,7 +388,7 @@ F test/pragma2.test bb5aa7be00dae2c381fcc782358048a33c955793 F test/printf.test 6bf1a86c6a1e45536f72d782bf44c8e3c76510f8 F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x F test/ptrchng.test 1c712dd6516e1377471744fa765e41c79a357da6 -F test/quick.test 88844a19f6d9dc5c990e01c7dd611d33d022a1c1 +F test/quick.test bedc5696abff22532b6df7da2b073254b15e53b7 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/rdonly.test b34db316525440d3b42c32e83942c02c37d28ef0 F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b @@ -426,9 +426,10 @@ F test/tclsqlite.test a868898e3350246be7ea132621dc25f9835b3030 F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821 F test/tester.tcl 913a808f05b0aed2fbb16481a423b1a5a118bdf0 F test/thread001.test 8fbd9559da0bbdc273e00318c7fd66c162020af7 +F test/thread002.test 1b886bc4cb396e2bba94be8996f159b2b5b605bc F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35 F test/thread2.test 6d7b30102d600f51b4055ee3a5a19228799049fb -F test/thread_common.tcl 95b11a3f42df7cba82e0c8feb8a70d339aaad4cb +F test/thread_common.tcl 8a9d7a4500dfdbbd36679c977831b62c130b76b1 F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9 F test/tkt1435.test f8c52c41de6e5ca02f1845f3a46e18e25cadac00 @@ -574,7 +575,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 6ee2b8ffc4310c8e329f634f3ade058b33c53a2a -R 59e1b6472478b1b0d4fb7b3646b47885 +P 54f87899033ddd892bfd3a16310f64fb42d807ae +R d80f0142f0a5e23af45dc05a2499fc1e U danielk1977 -Z f03978abade17ec790e2c8c978d82d62 +Z d1aeb7bb16c21c3bfd6864755301855d diff --git a/manifest.uuid b/manifest.uuid index 80f002b77c..544a86c955 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54f87899033ddd892bfd3a16310f64fb42d807ae \ No newline at end of file +c758cc1d885b4528c0b0ef6382119f20956d4816 \ No newline at end of file diff --git a/src/test_thread.c b/src/test_thread.c index a6bbbd80e4..4bfc6492d5 100644 --- a/src/test_thread.c +++ b/src/test_thread.c @@ -14,7 +14,7 @@ ** test that sqlite3 database handles may be concurrently accessed by ** multiple threads. Right now this only works on unix. ** -** $Id: test_thread.c,v 1.3 2007/09/10 06:23:54 danielk1977 Exp $ +** $Id: test_thread.c,v 1.4 2007/09/10 10:53:02 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -224,6 +224,12 @@ static int xBusy(void *pArg, int nBusy){ return 1; /* Try again... */ } +/* +** sqlthread open +** +** Open a database handle and return the string representation of +** the pointer value. +*/ static int sqlthread_open( ClientData clientData, Tcl_Interp *interp, @@ -250,6 +256,24 @@ static int sqlthread_open( } +/* +** sqlthread open +** +** Return the current thread-id (Tcl_GetCurrentThread()) cast to +** an integer. +*/ +static int sqlthread_id( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + Tcl_ThreadId id = Tcl_GetCurrentThread(); + Tcl_SetObjResult(interp, Tcl_NewIntObj((int)id)); + return TCL_OK; +} + + /* ** Dispatch routine for the sub-commands of [sqlthread]. */ @@ -268,6 +292,7 @@ static int sqlthread_proc( {"parent", sqlthread_parent, 1, "SCRIPT"}, {"spawn", sqlthread_spawn, 2, "VARNAME SCRIPT"}, {"open", sqlthread_open, 1, "DBNAME"}, + {"id", sqlthread_id, 0, ""}, {0, 0, 0} }; struct SubCommand *pSub; diff --git a/test/quick.test b/test/quick.test index 490a5283ab..6269f318e6 100644 --- a/test/quick.test +++ b/test/quick.test @@ -6,7 +6,7 @@ #*********************************************************************** # This file runs all tests. # -# $Id: quick.test,v 1.62 2007/08/23 16:27:21 danielk1977 Exp $ +# $Id: quick.test,v 1.63 2007/09/10 10:53:02 danielk1977 Exp $ proc lshift {lvar} { upvar $lvar l @@ -66,6 +66,9 @@ set EXCLUDE { speed2.test sqllimits1.test + thread001.test + thread002.test + incrvacuum_ioerr.test autovacuum_crash.test btree8.test diff --git a/test/thread002.test b/test/thread002.test new file mode 100644 index 0000000000..94141be040 --- /dev/null +++ b/test/thread002.test @@ -0,0 +1,105 @@ +# 2007 September 10 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This test attempts to deadlock SQLite in shared-cache mode. +# +# +# $Id: thread002.test,v 1.1 2007/09/10 10:53:02 danielk1977 Exp $ + +set testdir [file dirname $argv0] + +source $testdir/tester.tcl +source $testdir/thread_common.tcl +if {[info commands sqlthread] eq ""} { + return +} + +db close +sqlite3_enable_shared_cache 1 + +set ::NTHREAD 10 + +do_test thread002.1 { + # Create 3 databases with identical schemas: + for {set ii 0} {$ii < 3} {incr ii} { + file delete -force test${ii}.db + sqlite3 db test${ii}.db + execsql { + CREATE TABLE t1(k, v); + CREATE INDEX t1_i ON t1(v); + INSERT INTO t1(v) VALUES(1.0); + } + db close + } +} {} + +set thread_program { + set ::DB [sqlite3_open test.db] + for {set ii 1} {$ii <= 3} {incr ii} { + set T [lindex $order [expr $ii-1]] + execsql "ATTACH 'test${T}.db' AS aux${ii}" + } + + for {set ii 0} {$ii < 100} {incr ii} { + execsql { SELECT * FROM aux1.t1 } + execsql { INSERT INTO aux1.t1(v) SELECT sum(v) FROM aux2.t1 } + + execsql { SELECT * FROM aux2.t1 } + execsql { INSERT INTO aux2.t1(v) SELECT sum(v) FROM aux3.t1 } + + execsql { SELECT * FROM aux3.t1 } + execsql { INSERT INTO aux3.t1(v) SELECT sum(v) FROM aux1.t1 } + + execsql { CREATE TABLE aux1.t2(a,b) } + execsql { DROP TABLE aux1.t2 } + + # if {($ii%10)==0} {puts -nonewline . ; flush stdout} + puts -nonewline . ; flush stdout + } + + sqlite3_close $::DB + list OK +} + +set order_list [list {0 1 2} {0 2 1} {1 0 2} {1 2 0} {2 0 1} {2 1 0}] + +array unset finished +for {set ii 0} {$ii < $::NTHREAD} {incr ii} { + set order [lindex $order_list [expr $ii%6]] + thread_spawn finished($ii) $thread_procs "set order {$order}" $thread_program +} + +# Wait for all threads to finish, then check they all returned "OK". +# +for {set i 0} {$i < $::NTHREAD} {incr i} { + if {![info exists finished($i)]} { + vwait finished($i) + } + do_test thread001.2.$i { + set ::finished($i) + } OK +} + +# Check all three databases are Ok. +for {set ii 0} {$ii < 3} {incr ii} { + do_test thread002.3.$ii { + sqlite3 db test${ii}.db + set res [list \ + [execsql {SELECT count(*) FROM t1}] \ + [execsql {PRAGMA integrity_check}] \ + ] + db close + set res + } [list [expr 1 + $::NTHREAD*100] ok] +} + +finish_test + diff --git a/test/thread_common.tcl b/test/thread_common.tcl index 92611b1daa..5e34b179b1 100644 --- a/test/thread_common.tcl +++ b/test/thread_common.tcl @@ -9,7 +9,7 @@ # #*********************************************************************** # -# $Id: thread_common.tcl,v 1.1 2007/09/10 07:35:47 danielk1977 Exp $ +# $Id: thread_common.tcl,v 1.2 2007/09/10 10:53:02 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -23,8 +23,6 @@ if {[info commands sqlthread] eq ""} { return } -set ::NTHREAD 10 - # The following script is sourced by every thread spawned using # [sqlthread spawn]: set thread_procs { @@ -34,17 +32,37 @@ set thread_procs { proc execsql {sql} { set rc SQLITE_LOCKED - while {$rc eq "SQLITE_LOCKED"} { + while {$rc eq "SQLITE_LOCKED" + || $rc eq "SQLITE_BUSY" + || $rc eq "SQLITE_SCHEMA"} { set res [list] - set ::STMT [sqlite3_prepare $::DB $sql -1 dummy_tail] - while {[set rc [sqlite3_step $::STMT]] eq "SQLITE_ROW"} { - for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} { - lappend res [sqlite3_column_text $::STMT 0] + + set err [catch { + set ::STMT [sqlite3_prepare_v2 $::DB $sql -1 dummy_tail] + } msg] + + if {$err == 0} { + while {[set rc [sqlite3_step $::STMT]] eq "SQLITE_ROW"} { + for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} { + lappend res [sqlite3_column_text $::STMT 0] + } } + set rc [sqlite3_finalize $::STMT] + } else { + if {[string first (6) $msg]} { + set rc SQLITE_LOCKED + } else { + set rc SQLITE_ERROR + } + } + + if {[string first locked [sqlite3_errmsg $::DB]]>=0} { + set rc SQLITE_LOCKED } - set rc [sqlite3_finalize $::STMT] - if {$rc eq "SQLITE_LOCKED"} { + if {$rc eq "SQLITE_LOCKED" || $rc eq "SQLITE_BUSY"} { + #puts -nonewline "([sqlthread id] $rc)" + #flush stdout after 20 } }