summaryrefslogtreecommitdiffstats
path: root/test/mutex1.test
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--test/mutex1.test224
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