xref: /sqlite-3.40.0/test/thread_common.tcl (revision 7329ed9b)
149e439d9Sdanielk1977# 2007 September 10
249e439d9Sdanielk1977#
349e439d9Sdanielk1977# The author disclaims copyright to this source code.  In place of
449e439d9Sdanielk1977# a legal notice, here is a blessing:
549e439d9Sdanielk1977#
649e439d9Sdanielk1977#    May you do good and not evil.
749e439d9Sdanielk1977#    May you find forgiveness for yourself and forgive others.
849e439d9Sdanielk1977#    May you share freely, never taking more than you give.
949e439d9Sdanielk1977#
1049e439d9Sdanielk1977#***********************************************************************
1149e439d9Sdanielk1977#
126d961009Sdanielk1977# $Id: thread_common.tcl,v 1.5 2009/03/26 14:48:07 danielk1977 Exp $
1349e439d9Sdanielk1977
146d961009Sdanielk1977if {[info exists ::thread_procs]} {
156d961009Sdanielk1977  return 0
1649e439d9Sdanielk1977}
1749e439d9Sdanielk1977
1849e439d9Sdanielk1977# The following script is sourced by every thread spawned using
1949e439d9Sdanielk1977# [sqlthread spawn]:
2049e439d9Sdanielk1977set thread_procs {
2149e439d9Sdanielk1977
2249e439d9Sdanielk1977  # Execute the supplied SQL using database handle $::DB.
2349e439d9Sdanielk1977  #
2449e439d9Sdanielk1977  proc execsql {sql} {
2549e439d9Sdanielk1977
2649e439d9Sdanielk1977    set rc SQLITE_LOCKED
27e9dcd5e6Sdanielk1977    while {$rc eq "SQLITE_LOCKED"
28e9dcd5e6Sdanielk1977        || $rc eq "SQLITE_BUSY"
29e9dcd5e6Sdanielk1977        || $rc eq "SQLITE_SCHEMA"} {
3049e439d9Sdanielk1977      set res [list]
31e9dcd5e6Sdanielk1977
32b8613ab1Sdrh      enter_db_mutex $::DB
33e9dcd5e6Sdanielk1977      set err [catch {
34e9dcd5e6Sdanielk1977        set ::STMT [sqlite3_prepare_v2 $::DB $sql -1 dummy_tail]
35e9dcd5e6Sdanielk1977      } msg]
36e9dcd5e6Sdanielk1977
37e9dcd5e6Sdanielk1977      if {$err == 0} {
3849e439d9Sdanielk1977        while {[set rc [sqlite3_step $::STMT]] eq "SQLITE_ROW"} {
3949e439d9Sdanielk1977          for {set i 0} {$i < [sqlite3_column_count $::STMT]} {incr i} {
4049e439d9Sdanielk1977            lappend res [sqlite3_column_text $::STMT 0]
4149e439d9Sdanielk1977          }
4249e439d9Sdanielk1977        }
4349e439d9Sdanielk1977        set rc [sqlite3_finalize $::STMT]
44e9dcd5e6Sdanielk1977      } else {
453ded8d6fSdrh        if {[lindex $msg 0]=="(6)"} {
46e9dcd5e6Sdanielk1977          set rc SQLITE_LOCKED
47e9dcd5e6Sdanielk1977        } else {
48e9dcd5e6Sdanielk1977          set rc SQLITE_ERROR
49e9dcd5e6Sdanielk1977        }
50e9dcd5e6Sdanielk1977      }
51e9dcd5e6Sdanielk1977
52e9dcd5e6Sdanielk1977      if {[string first locked [sqlite3_errmsg $::DB]]>=0} {
53e9dcd5e6Sdanielk1977        set rc SQLITE_LOCKED
54e9dcd5e6Sdanielk1977      }
55b8613ab1Sdrh      if {$rc ne "SQLITE_OK"} {
56b8613ab1Sdrh        set errtxt "$rc - [sqlite3_errmsg $::DB] (debug1)"
57b8613ab1Sdrh      }
58b8613ab1Sdrh      leave_db_mutex $::DB
59e9dcd5e6Sdanielk1977
60e9dcd5e6Sdanielk1977      if {$rc eq "SQLITE_LOCKED" || $rc eq "SQLITE_BUSY"} {
61b8613ab1Sdrh        #sqlthread parent "puts \"thread [sqlthread id] is busy.  rc=$rc\""
62b8613ab1Sdrh        after 200
63b8613ab1Sdrh      } else {
64b8613ab1Sdrh        #sqlthread parent "puts \"thread [sqlthread id] ran $sql\""
6549e439d9Sdanielk1977      }
6649e439d9Sdanielk1977    }
6749e439d9Sdanielk1977
6849e439d9Sdanielk1977    if {$rc ne "SQLITE_OK"} {
69b8613ab1Sdrh      error $errtxt
7049e439d9Sdanielk1977    }
7149e439d9Sdanielk1977    set res
7249e439d9Sdanielk1977  }
7349e439d9Sdanielk1977
7449e439d9Sdanielk1977  proc do_test {name script result} {
7549e439d9Sdanielk1977    set res [eval $script]
7649e439d9Sdanielk1977    if {$res ne $result} {
7749e439d9Sdanielk1977      error "$name failed: expected \"$result\" got \"$res\""
7849e439d9Sdanielk1977    }
7949e439d9Sdanielk1977  }
8049e439d9Sdanielk1977}
8149e439d9Sdanielk1977
8249e439d9Sdanielk1977proc thread_spawn {varname args} {
83d3f8f946Sdan  sqlthread spawn $varname [join $args {;}]
8449e439d9Sdanielk1977}
8549e439d9Sdanielk1977
866d961009Sdanielk1977# Return true if this build can run the multi-threaded tests.
876d961009Sdanielk1977#
886d961009Sdanielk1977proc run_thread_tests {{print_warning 0}} {
896d961009Sdanielk1977  ifcapable !mutex {
906d961009Sdanielk1977    set zProblem "SQLite build is not threadsafe"
916d961009Sdanielk1977  }
92*7329ed9bSdan  ifcapable mutex_noop {
93*7329ed9bSdan    set zProblem "SQLite build uses SQLITE_MUTEX_NOOP"
94*7329ed9bSdan  }
956d961009Sdanielk1977  if {[info commands sqlthread] eq ""} {
966d961009Sdanielk1977    set zProblem "SQLite build is not threadsafe"
976d961009Sdanielk1977  }
986d961009Sdanielk1977  if {![info exists ::tcl_platform(threaded)]} {
996d961009Sdanielk1977    set zProblem "Linked against a non-threadsafe Tcl build"
1006d961009Sdanielk1977  }
1016d961009Sdanielk1977  if {[info exists zProblem]} {
1026d961009Sdanielk1977    puts "WARNING: Multi-threaded tests skipped: $zProblem"
10349e439d9Sdanielk1977    return 0
1046d961009Sdanielk1977  }
105ea5542d1Sdan  set ::run_thread_tests_called 1
1066d961009Sdanielk1977  return 1;
1076d961009Sdanielk1977}
1086d961009Sdanielk1977
1096d961009Sdanielk1977return 0
1106d961009Sdanielk1977
111