diff options
Diffstat (limited to 'test/mutex1.test')
-rw-r--r-- | test/mutex1.test | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/test/mutex1.test b/test/mutex1.test new file mode 100644 index 0000000..cb189a7 --- /dev/null +++ b/test/mutex1.test @@ -0,0 +1,224 @@ +# 2008 June 17 +# +# 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: mutex1.test,v 1.20 2009/04/23 14:58:40 danielk1977 Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !mutex { + finish_test + return +} +if {[info exists tester_do_binarylog]} { + finish_test + return +} + +sqlite3_reset_auto_extension +clear_mutex_counters + +proc mutex_counters {varname} { + upvar $varname var + set var(total) 0 + foreach {name value} [read_mutex_counters] { + set var($name) $value + incr var(total) $value + } +} + +#------------------------------------------------------------------------- +# Tests mutex1-1.* test that sqlite3_config() returns SQLITE_MISUSE if +# is called at the wrong time. And that the first time sqlite3_initialize +# is called it obtains the 'static_main' mutex 3 times and a recursive +# mutex (sqlite3Config.pInitMutex) twice. Subsequent calls are no-ops +# that do not require any mutexes. +# +do_test mutex1-1.0 { + install_mutex_counters 1 +} {SQLITE_MISUSE} + +do_test mutex1-1.1 { + db close + install_mutex_counters 1 +} {SQLITE_MISUSE} + +do_test mutex1-1.2 { + sqlite3_shutdown + install_mutex_counters 1 +} {SQLITE_OK} + +do_test mutex1-1.3 { + install_mutex_counters 0 +} {SQLITE_OK} + +do_test mutex1-1.4 { + install_mutex_counters 1 +} {SQLITE_OK} + +do_test mutex1-1.5 { + mutex_counters counters + set counters(total) +} {0} + +do_test mutex1-1.6 { + sqlite3_initialize +} {SQLITE_OK} + +do_test mutex1-1.7 { + mutex_counters counters + # list $counters(total) $counters(static_main) + expr {$counters(total)>0} +} {1} + +do_test mutex1-1.8 { + clear_mutex_counters + sqlite3_initialize +} {SQLITE_OK} + +do_test mutex1-1.9 { + mutex_counters counters + list $counters(total) $counters(static_main) +} {0 0} + +#------------------------------------------------------------------------- +# Tests mutex1-2.* test the three thread-safety related modes that +# can be selected using sqlite3_config: +# +# * Serialized mode, +# * Multi-threaded mode, +# * Single-threaded mode. +# +ifcapable threadsafe1&&shared_cache { + set enable_shared_cache [sqlite3_enable_shared_cache 1] + foreach {mode mutexes} { + singlethread {} + multithread { + fast static_app1 static_app2 static_app3 + static_lru static_main static_mem static_open + static_prng static_pmem static_vfs1 static_vfs2 + static_vfs3 + } + serialized { + fast recursive static_app1 static_app2 + static_app3 static_lru static_main static_mem + static_open static_prng static_pmem static_vfs1 + static_vfs2 static_vfs3 + } + } { + + # For journal_mode=memory, the static_prng mutex is not required. This + # is because the header of an in-memory journal does not contain + # any random bytes, and so no call to sqlite3_randomness() is made. + if {[permutation]=="inmemory_journal"} { + set idx [lsearch $mutexes static_prng] + if {$idx>=0} { set mutexes [lreplace $mutexes $idx $idx] } + } + + do_test mutex1.2.$mode.1 { + catch {db close} + sqlite3_shutdown + sqlite3_config_memstatus 1 + sqlite3_config $mode + } SQLITE_OK + + do_test mutex1.2.$mode.2 { + sqlite3_initialize + clear_mutex_counters + sqlite3 db test.db -nomutex 0 -fullmutex 0 + catchsql { CREATE TABLE abc(a, b, c) } + db eval { + INSERT INTO abc VALUES(1, 2, 3); + } + } {} + ifcapable !memorymanage { + regsub { static_lru} $mutexes {} mutexes + } + if {$mode ne "singlethread"} { + do_test mutex1.2.$mode.3 { + # + # NOTE: Make sure all the app and vfs mutexes get used. + # + enter_static_mutex static_app1 + leave_static_mutex static_app1 + enter_static_mutex static_app2 + leave_static_mutex static_app2 + enter_static_mutex static_app3 + leave_static_mutex static_app3 + enter_static_mutex static_vfs1 + leave_static_mutex static_vfs1 + enter_static_mutex static_vfs2 + leave_static_mutex static_vfs2 + enter_static_mutex static_vfs3 + leave_static_mutex static_vfs3 + } {} + } + do_test mutex1.2.$mode.4 { + mutex_counters counters + + set res [list] + foreach {key value} [array get counters] { + if {$key ne "total" && $value > 0} { + lappend res $key + } + } + lsort $res + } [lsort $mutexes] + } + sqlite3_enable_shared_cache $enable_shared_cache + + # Open and use a connection in "nomutex" mode. Test that no recursive + # mutexes are obtained. + do_test mutex1.3.1 { + catch {db close} + clear_mutex_counters + sqlite3 db test.db -nomutex 1 + execsql { SELECT * FROM abc } + } {1 2 3 1 2 3 1 2 3} + do_test mutex1.3.2 { + mutex_counters counters + set counters(recursive) + } {0} +} + +# Test the sqlite3_db_mutex() function. +# +do_test mutex1.4.1 { + catch {db close} + sqlite3 db test.db + enter_db_mutex db + db eval {SELECT 1, 2, 3} +} {1 2 3} +do_test mutex1.4.2 { + leave_db_mutex db + db eval {SELECT 1, 2, 3} +} {1 2 3} +do_test mutex1.4.3 { + catch {db close} + sqlite3 db test.db -nomutex 1 + enter_db_mutex db + db eval {SELECT 1, 2, 3} +} {1 2 3} +do_test mutex1.4.4 { + leave_db_mutex db + db eval {SELECT 1, 2, 3} +} {1 2 3} + +do_test mutex1-X { + catch {db close} + sqlite3_shutdown + clear_mutex_counters + install_mutex_counters 0 + sqlite3_initialize +} {SQLITE_OK} + +autoinstall_test_functions +finish_test |