-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
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
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
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
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
-54f87899033ddd892bfd3a16310f64fb42d807ae
\ No newline at end of file
+c758cc1d885b4528c0b0ef6382119f20956d4816
\ No newline at end of file
** 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"
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,
}
+/*
+** 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].
*/
{"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;
#***********************************************************************
# 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
speed2.test
sqllimits1.test
+ thread001.test
+ thread002.test
+
incrvacuum_ioerr.test
autovacuum_crash.test
btree8.test
--- /dev/null
+# 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
+
#
#***********************************************************************
#
-# $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
return
}
-set ::NTHREAD 10
-
# The following script is sourced by every thread spawned using
# [sqlthread spawn]:
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
}
}