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