|
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.3 2008/07/12 14:52:20 drh Exp $ |
|
16 |
|
17 set testdir [file dirname $argv0] |
|
18 |
|
19 source $testdir/tester.tcl |
|
20 source $testdir/thread_common.tcl |
|
21 if {[info commands sqlthread] eq ""} { |
|
22 finish_test |
|
23 return |
|
24 } |
|
25 ifcapable !attach { |
|
26 finish_test |
|
27 return |
|
28 } |
|
29 |
|
30 db close |
|
31 sqlite3_enable_shared_cache 1 |
|
32 |
|
33 set ::NTHREAD 10 |
|
34 |
|
35 do_test thread002.1 { |
|
36 # Create 3 databases with identical schemas: |
|
37 for {set ii 0} {$ii < 3} {incr ii} { |
|
38 file delete -force test${ii}.db |
|
39 sqlite3 db test${ii}.db |
|
40 execsql { |
|
41 CREATE TABLE t1(k, v); |
|
42 CREATE INDEX t1_i ON t1(v); |
|
43 INSERT INTO t1(v) VALUES(1.0); |
|
44 } |
|
45 db close |
|
46 } |
|
47 } {} |
|
48 |
|
49 set thread_program { |
|
50 set ::DB [sqlite3_open test.db] |
|
51 for {set ii 1} {$ii <= 3} {incr ii} { |
|
52 set T [lindex $order [expr $ii-1]] |
|
53 execsql "ATTACH 'test${T}.db' AS aux${ii}" |
|
54 } |
|
55 |
|
56 for {set ii 0} {$ii < 100} {incr ii} { |
|
57 execsql { SELECT * FROM aux1.t1 } |
|
58 execsql { INSERT INTO aux1.t1(v) SELECT sum(v) FROM aux2.t1 } |
|
59 |
|
60 execsql { SELECT * FROM aux2.t1 } |
|
61 execsql { INSERT INTO aux2.t1(v) SELECT sum(v) FROM aux3.t1 } |
|
62 |
|
63 execsql { SELECT * FROM aux3.t1 } |
|
64 execsql { INSERT INTO aux3.t1(v) SELECT sum(v) FROM aux1.t1 } |
|
65 |
|
66 execsql { CREATE TABLE aux1.t2(a,b) } |
|
67 execsql { DROP TABLE aux1.t2 } |
|
68 |
|
69 # if {($ii%10)==0} {puts -nonewline . ; flush stdout} |
|
70 puts -nonewline . ; flush stdout |
|
71 } |
|
72 |
|
73 sqlite3_close $::DB |
|
74 list OK |
|
75 } |
|
76 |
|
77 set order_list [list {0 1 2} {0 2 1} {1 0 2} {1 2 0} {2 0 1} {2 1 0}] |
|
78 |
|
79 array unset finished |
|
80 for {set ii 0} {$ii < $::NTHREAD} {incr ii} { |
|
81 set order [lindex $order_list [expr $ii%6]] |
|
82 thread_spawn finished($ii) $thread_procs "set order {$order}" $thread_program |
|
83 } |
|
84 |
|
85 # Wait for all threads to finish, then check they all returned "OK". |
|
86 # |
|
87 for {set i 0} {$i < $::NTHREAD} {incr i} { |
|
88 if {![info exists finished($i)]} { |
|
89 vwait finished($i) |
|
90 } |
|
91 do_test thread001.2.$i { |
|
92 set ::finished($i) |
|
93 } OK |
|
94 } |
|
95 |
|
96 # Check all three databases are Ok. |
|
97 for {set ii 0} {$ii < 3} {incr ii} { |
|
98 do_test thread002.3.$ii { |
|
99 sqlite3 db test${ii}.db |
|
100 set res [list \ |
|
101 [execsql {SELECT count(*) FROM t1}] \ |
|
102 [execsql {PRAGMA integrity_check}] \ |
|
103 ] |
|
104 db close |
|
105 set res |
|
106 } [list [expr 1 + $::NTHREAD*100] ok] |
|
107 } |
|
108 |
|
109 finish_test |