1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
# 2007 September 7
#
# 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.
#
#***********************************************************************
#
# $Id: thread001.test,v 1.10 2009/03/26 14:48:07 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
if {[run_thread_tests]==0} { finish_test ; return }
ifcapable !shared_cache { finish_test ; return }
set ::enable_shared_cache [sqlite3_enable_shared_cache]
set ::NTHREAD 10
# Run this test three times:
#
# 1) All threads use the same database handle.
# 2) All threads use their own database handles.
# 3) All threads use their own database handles, shared-cache is enabled.
#
#
#
foreach {tn same_db shared_cache} [list \
1 1 0 \
2 0 0 \
3 0 1 \
] {
# Empty the database.
#
catchsql { DROP TABLE ab; }
do_test thread001.$tn.0 {
db close
sqlite3_enable_shared_cache $shared_cache
sqlite3_enable_shared_cache $shared_cache
} $shared_cache
sqlite3 db test.db -fullmutex 1 -key xyzzy
set dbconfig ""
if {$same_db} {
set dbconfig [list set ::DB [sqlite3_connection_pointer db]]
}
# Set up a database and a schema. The database contains a single
# table with two columns. The first column ("a") is an INTEGER PRIMARY
# KEY. The second contains the md5sum of all rows in the table with
# a smaller value stored in column "a".
#
do_test thread001.$tn.1 {
execsql {
CREATE TABLE ab(a INTEGER PRIMARY KEY, b);
CREATE INDEX ab_i ON ab(b);
INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab;
SELECT count(*) FROM ab;
}
} {1}
do_test thread001.$tn.2 {
execsql {
SELECT
(SELECT md5sum(a, b) FROM ab WHERE a < (SELECT max(a) FROM ab)) ==
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
}
} {1}
do_test thread001.$tn.3 {
execsql { PRAGMA integrity_check }
} {ok}
set thread_program {
#sqlthread parent {puts STARTING..}
set needToClose 0
if {![info exists ::DB]} {
set ::DB [sqlthread open test.db xyzzy]
#sqlthread parent "puts \"OPEN $::DB\""
set needToClose 1
}
for {set i 0} {$i < 100} {incr i} {
# Test that the invariant is true.
do_test t1 {
execsql {
SELECT
(SELECT md5sum(a, b) FROM ab WHERE +a < (SELECT max(a) FROM ab)) ==
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
}
} {1}
# Add another row to the database.
execsql { INSERT INTO ab SELECT NULL, md5sum(a, b) FROM ab }
}
if {$needToClose} {
#sqlthread parent "puts \"CLOSE $::DB\""
sqlite3_close $::DB
}
#sqlthread parent "puts \"DONE\""
list OK
}
# Kick off $::NTHREAD threads:
#
array unset finished
for {set i 0} {$i < $::NTHREAD} {incr i} {
thread_spawn finished($i) $dbconfig $thread_procs $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.$tn.4.$i {
set ::finished($i)
} OK
}
# Check the database still looks Ok.
#
do_test thread001.$tn.5 {
execsql { SELECT count(*) FROM ab; }
} [expr {1 + $::NTHREAD*100}]
do_test thread001.$tn.6 {
execsql {
SELECT
(SELECT md5sum(a, b) FROM ab WHERE +a < (SELECT max(a) FROM ab)) ==
(SELECT b FROM ab WHERE a = (SELECT max(a) FROM ab))
}
} {1}
do_test thread001.$tn.7 {
execsql { PRAGMA integrity_check }
} {ok}
}
sqlite3_enable_shared_cache $::enable_shared_cache
catch { db close }
set sqlite_open_file_count 0
finish_test
|