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