1# 2015 Mar 17 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 13set testdir [file dirname $argv0] 14source $testdir/tester.tcl 15source $testdir/lock_common.tcl 16source $testdir/wal_common.tcl 17 18ifcapable !wal {finish_test ; return } 19if {$::tcl_platform(platform)!="unix"} { finish_test ; return } 20set testprefix walblock 21 22catch { db close } 23testvfs tvfs -fullshm 1 24foreach f [glob test.db*] { forcedelete $f } 25 26sqlite3 db test.db -vfs tvfs 27do_execsql_test 1.1.0 { 28 CREATE TABLE t1(x, y); 29 INSERT INTO t1 VALUES(1, 2); 30 INSERT INTO t1 VALUES(3, 4); 31 INSERT INTO t1 VALUES(5, 6); 32 PRAGMA journal_mode = wal; 33 INSERT INTO t1 VALUES(7, 8); 34} {wal} 35 36do_test 1.1.1 { 37 lsort [glob test.db*] 38} {test.db test.db-shm test.db-wal} 39 40do_test 1.1.2 { 41 set C [launch_testfixture] 42 testfixture $C { 43 sqlite3 db test.db 44 db eval { SELECT * FROM t1 } 45 } 46} {1 2 3 4 5 6 7 8} 47 48do_test 1.1.3 { 49 set ::out [list] 50 testfixture $C { 51 db eval { SELECT * FROM t1 } 52 } [list set ::out] 53 set ::out 54} {} 55 56do_test 1.1.4 { 57 vwait ::out 58 set ::out 59} {1 2 3 4 5 6 7 8} 60 61# 62# Test that if a read client cannot read the wal-index header because a 63# write client is in the middle of updating it, the reader blocks until 64# the writer finishes. 65# 66# 1. Open a write transaction using client [db] in this process. 67# 68# 2. Attempt to commit the write transaction. Intercept the xShmBarrier() 69# call made by the writer between updating the two copies of the 70# wal-index header. 71# 72# 3. Within the xShmBarrier() callback, make an asynchronous request to 73# the other process to read from the database. It should block, as it 74# cannot get read the wal-index header. 75# 76# 4. Still in xShmBarrier(), wait for 5 seconds. Check that the other 77# process has not answered the request. 78# 79# 5: Finish committing the transaction. Then wait for 0.5 seconds more. 80# Ensure that the second process has by this stage read the database 81# and that the snapshot it read included the transaction committed in 82# step (4). 83# 84do_execsql_test 1.2.1 { 85 BEGIN; 86 INSERT INTO t1 VALUES(9, 10); 87} {} 88 89tvfs script barrier_callback 90tvfs filter xShmBarrier 91proc barrier_callback {method args} { 92 set ::out "" 93 testfixture $::C { db eval { SELECT * FROM t1 } } {set ::out} 94 95 do_test "1.2.2.(blocking 10 seconds)" { 96 set ::continue 0 97 after 10000 {set ::continue 1} 98 vwait ::continue 99 set ::out 100 } {} 101} 102 103execsql COMMIT 104 105do_test "1.2.3.(blocking 0.5 seconds)" { 106 set ::continue 0 107 after 500 {set ::continue 1} 108 vwait ::continue 109 set ::out 110} {1 2 3 4 5 6 7 8 9 10} 111 112 113finish_test 114 115 116 117 118