xref: /sqlite-3.40.0/test/thread_common.tcl (revision 3ded8d6f)
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# $Id: thread_common.tcl,v 1.4 2009/03/17 15:39:31 drh Exp $
13
14set testdir [file dirname $argv0]
15source $testdir/tester.tcl
16
17if {[info commands sqlthread] eq ""} {
18  puts -nonewline "Skipping thread-safety tests - "
19  puts            " not running a threadsafe sqlite/tcl build"
20  puts -nonewline "Both SQLITE_THREADSAFE and TCL_THREADS must be defined when"
21  puts            " building testfixture"
22  finish_test
23  return
24}
25
26# The following script is sourced by every thread spawned using
27# [sqlthread spawn]:
28set thread_procs {
29
30  # Execute the supplied SQL using database handle $::DB.
31  #
32  proc execsql {sql} {
33
34    set rc SQLITE_LOCKED
35    while {$rc eq "SQLITE_LOCKED"
36        || $rc eq "SQLITE_BUSY"
37        || $rc eq "SQLITE_SCHEMA"} {
38      set res [list]
39
40      enter_db_mutex $::DB
41      set err [catch {
42        set ::STMT [sqlite3_prepare_v2 $::DB $sql -1 dummy_tail]
43      } msg]
44
45      if {$err == 0} {
46        while {[set rc [sqlite3_step $::STMT]] eq "SQLITE_ROW"} {
47          for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} {
48            lappend res [sqlite3_column_text $::STMT 0]
49          }
50        }
51        set rc [sqlite3_finalize $::STMT]
52      } else {
53        if {[lindex $msg 0]=="(6)"} {
54          set rc SQLITE_LOCKED
55        } else {
56          set rc SQLITE_ERROR
57        }
58      }
59
60      if {[string first locked [sqlite3_errmsg $::DB]]>=0} {
61        set rc SQLITE_LOCKED
62      }
63      if {$rc ne "SQLITE_OK"} {
64        set errtxt "$rc - [sqlite3_errmsg $::DB] (debug1)"
65      }
66      leave_db_mutex $::DB
67
68      if {$rc eq "SQLITE_LOCKED" || $rc eq "SQLITE_BUSY"} {
69        #sqlthread parent "puts \"thread [sqlthread id] is busy.  rc=$rc\""
70        after 200
71      } else {
72        #sqlthread parent "puts \"thread [sqlthread id] ran $sql\""
73      }
74    }
75
76    if {$rc ne "SQLITE_OK"} {
77      error $errtxt
78    }
79    set res
80  }
81
82  proc do_test {name script result} {
83    set res [eval $script]
84    if {$res ne $result} {
85      error "$name failed: expected \"$result\" got \"$res\""
86    }
87  }
88}
89
90proc thread_spawn {varname args} {
91  sqlthread spawn $varname [join $args ;]
92}
93
94return 0
95