blob: 673afdd8021fb63c70a665c04a6d8354e9e57745 [file] [log] [blame]
danielk197749e439d2007-09-10 07:35:47 +00001# 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#
danielk19776d961002009-03-26 14:48:07 +000012# $Id: thread_common.tcl,v 1.5 2009/03/26 14:48:07 danielk1977 Exp $
danielk197749e439d2007-09-10 07:35:47 +000013
danielk19776d961002009-03-26 14:48:07 +000014if {[info exists ::thread_procs]} {
15 return 0
danielk197749e439d2007-09-10 07:35:47 +000016}
17
danielk197749e439d2007-09-10 07:35:47 +000018# The following script is sourced by every thread spawned using
19# [sqlthread spawn]:
20set thread_procs {
21
22 # Execute the supplied SQL using database handle $::DB.
23 #
24 proc execsql {sql} {
25
26 set rc SQLITE_LOCKED
danielk1977e9dcd5e2007-09-10 10:53:01 +000027 while {$rc eq "SQLITE_LOCKED"
28 || $rc eq "SQLITE_BUSY"
29 || $rc eq "SQLITE_SCHEMA"} {
danielk197749e439d2007-09-10 07:35:47 +000030 set res [list]
danielk1977e9dcd5e2007-09-10 10:53:01 +000031
drhb8613ab2009-01-19 17:40:12 +000032 enter_db_mutex $::DB
danielk1977e9dcd5e2007-09-10 10:53:01 +000033 set err [catch {
34 set ::STMT [sqlite3_prepare_v2 $::DB $sql -1 dummy_tail]
35 } msg]
36
37 if {$err == 0} {
38 while {[set rc [sqlite3_step $::STMT]] eq "SQLITE_ROW"} {
39 for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} {
40 lappend res [sqlite3_column_text $::STMT 0]
41 }
42 }
43 set rc [sqlite3_finalize $::STMT]
44 } else {
drh3ded8d62009-03-17 15:39:31 +000045 if {[lindex $msg 0]=="(6)"} {
danielk1977e9dcd5e2007-09-10 10:53:01 +000046 set rc SQLITE_LOCKED
47 } else {
48 set rc SQLITE_ERROR
danielk197749e439d2007-09-10 07:35:47 +000049 }
50 }
51
danielk1977e9dcd5e2007-09-10 10:53:01 +000052 if {[string first locked [sqlite3_errmsg $::DB]]>=0} {
53 set rc SQLITE_LOCKED
54 }
drhb8613ab2009-01-19 17:40:12 +000055 if {$rc ne "SQLITE_OK"} {
56 set errtxt "$rc - [sqlite3_errmsg $::DB] (debug1)"
57 }
58 leave_db_mutex $::DB
danielk1977e9dcd5e2007-09-10 10:53:01 +000059
60 if {$rc eq "SQLITE_LOCKED" || $rc eq "SQLITE_BUSY"} {
drhb8613ab2009-01-19 17:40:12 +000061 #sqlthread parent "puts \"thread [sqlthread id] is busy. rc=$rc\""
62 after 200
63 } else {
64 #sqlthread parent "puts \"thread [sqlthread id] ran $sql\""
danielk197749e439d2007-09-10 07:35:47 +000065 }
66 }
67
68 if {$rc ne "SQLITE_OK"} {
drhb8613ab2009-01-19 17:40:12 +000069 error $errtxt
danielk197749e439d2007-09-10 07:35:47 +000070 }
71 set res
72 }
73
74 proc do_test {name script result} {
75 set res [eval $script]
76 if {$res ne $result} {
77 error "$name failed: expected \"$result\" got \"$res\""
78 }
79 }
80}
81
82proc thread_spawn {varname args} {
dand3f8f942010-04-13 11:35:01 +000083 sqlthread spawn $varname [join $args {;}]
danielk197749e439d2007-09-10 07:35:47 +000084}
85
danielk19776d961002009-03-26 14:48:07 +000086# Return true if this build can run the multi-threaded tests.
87#
88proc run_thread_tests {{print_warning 0}} {
89 ifcapable !mutex {
90 set zProblem "SQLite build is not threadsafe"
91 }
92 if {[info commands sqlthread] eq ""} {
93 set zProblem "SQLite build is not threadsafe"
94 }
95 if {![info exists ::tcl_platform(threaded)]} {
96 set zProblem "Linked against a non-threadsafe Tcl build"
97 }
98 if {[info exists zProblem]} {
99 if {$print_warning} {
100 if {[info exists ::run_thread_tests_failed]} {
101 puts "WARNING: Multi-threaded tests skipped: $zProblem"
102 }
103 } else {
104 puts "Skipping thread tests: $zProblem"
105 set ::run_thread_tests_failed 1
106 }
107 return 0
108 }
109 return 1;
110}
111
danielk197749e439d2007-09-10 07:35:47 +0000112return 0
danielk19776d961002009-03-26 14:48:07 +0000113