1# 2007 September 10 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# 12# This test attempts to deadlock SQLite in shared-cache mode. 13# 14# 15# $Id: thread002.test,v 1.1 2007/09/10 10:53:02 danielk1977 Exp $ 16 17set testdir [file dirname $argv0] 18 19source $testdir/tester.tcl 20source $testdir/thread_common.tcl 21if {[info commands sqlthread] eq ""} { 22 return 23} 24 25db close 26sqlite3_enable_shared_cache 1 27 28set ::NTHREAD 10 29 30do_test thread002.1 { 31 # Create 3 databases with identical schemas: 32 for {set ii 0} {$ii < 3} {incr ii} { 33 file delete -force test${ii}.db 34 sqlite3 db test${ii}.db 35 execsql { 36 CREATE TABLE t1(k, v); 37 CREATE INDEX t1_i ON t1(v); 38 INSERT INTO t1(v) VALUES(1.0); 39 } 40 db close 41 } 42} {} 43 44set thread_program { 45 set ::DB [sqlite3_open test.db] 46 for {set ii 1} {$ii <= 3} {incr ii} { 47 set T [lindex $order [expr $ii-1]] 48 execsql "ATTACH 'test${T}.db' AS aux${ii}" 49 } 50 51 for {set ii 0} {$ii < 100} {incr ii} { 52 execsql { SELECT * FROM aux1.t1 } 53 execsql { INSERT INTO aux1.t1(v) SELECT sum(v) FROM aux2.t1 } 54 55 execsql { SELECT * FROM aux2.t1 } 56 execsql { INSERT INTO aux2.t1(v) SELECT sum(v) FROM aux3.t1 } 57 58 execsql { SELECT * FROM aux3.t1 } 59 execsql { INSERT INTO aux3.t1(v) SELECT sum(v) FROM aux1.t1 } 60 61 execsql { CREATE TABLE aux1.t2(a,b) } 62 execsql { DROP TABLE aux1.t2 } 63 64 # if {($ii%10)==0} {puts -nonewline . ; flush stdout} 65 puts -nonewline . ; flush stdout 66 } 67 68 sqlite3_close $::DB 69 list OK 70} 71 72set order_list [list {0 1 2} {0 2 1} {1 0 2} {1 2 0} {2 0 1} {2 1 0}] 73 74array unset finished 75for {set ii 0} {$ii < $::NTHREAD} {incr ii} { 76 set order [lindex $order_list [expr $ii%6]] 77 thread_spawn finished($ii) $thread_procs "set order {$order}" $thread_program 78} 79 80# Wait for all threads to finish, then check they all returned "OK". 81# 82for {set i 0} {$i < $::NTHREAD} {incr i} { 83 if {![info exists finished($i)]} { 84 vwait finished($i) 85 } 86 do_test thread001.2.$i { 87 set ::finished($i) 88 } OK 89} 90 91# Check all three databases are Ok. 92for {set ii 0} {$ii < 3} {incr ii} { 93 do_test thread002.3.$ii { 94 sqlite3 db test${ii}.db 95 set res [list \ 96 [execsql {SELECT count(*) FROM t1}] \ 97 [execsql {PRAGMA integrity_check}] \ 98 ] 99 db close 100 set res 101 } [list [expr 1 + $::NTHREAD*100] ok] 102} 103 104finish_test 105 106