github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/shmlock.test (about) 1 # 2018 December 6 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 13 set testdir [file dirname $argv0] 14 source $testdir/tester.tcl 15 16 set testprefix shmlock 17 18 ifcapable !wal {finish_test ; return } 19 20 sqlite3 db2 test.db 21 sqlite3 db3 test.db 22 23 do_execsql_test 1.0 { 24 PRAGMA journal_mode = wal; 25 CREATE TABLE t1(a, b); 26 INSERT INTO t1 VALUES(1, 2); 27 } {wal} 28 do_test 1.1 { execsql { SELECT * FROM t1 } db2 } {1 2} 29 do_test 1.2 { execsql { SELECT * FROM t1 } db3 } {1 2} 30 31 foreach {tn dbhandle cmd res} { 32 1 db {shared lock 7 1} OK 33 2 db2 {exclusive lock 7 1} BUSY 34 3 db {shared unlock 7 1} OK 35 4 db2 {exclusive lock 7 1} OK 36 5 db {shared lock 7 1} BUSY 37 6 db {exclusive lock 7 1} BUSY 38 7 db2 {exclusive unlock 7 1} OK 39 40 8 db {exclusive lock 0 8} OK 41 9 db {exclusive unlock 0 8} OK 42 10 db2 {exclusive lock 0 8} OK 43 11 db2 {exclusive unlock 0 8} OK 44 45 12 db {shared lock 0 1} OK 46 13 db2 {shared lock 0 1} OK 47 14 db3 {shared lock 0 1} OK 48 15 db3 {shared unlock 0 1} OK 49 16 db3 {exclusive lock 0 1} BUSY 50 17 db2 {shared unlock 0 1} OK 51 18 db3 {exclusive lock 0 1} BUSY 52 19 db {shared unlock 0 1} OK 53 20 db3 {exclusive lock 0 1} OK 54 21 db3 {exclusive unlock 0 1} OK 55 56 22 db {shared lock 3 1} OK 57 23 db2 {exclusive lock 2 2} BUSY 58 24 db {shared lock 2 1} OK 59 25 db2 {exclusive lock 0 5} BUSY 60 26 db2 {exclusive lock 0 4} BUSY 61 27 db2 {exclusive lock 0 3} BUSY 62 28 db {shared unlock 3 1} OK 63 29 db2 {exclusive lock 2 2} BUSY 64 28 db {shared unlock 2 1} OK 65 29 db2 {exclusive lock 2 2} OK 66 29 db2 {exclusive unlock 2 2} OK 67 } { 68 do_test 1.3.$tn [list vfs_shmlock $dbhandle main {*}$cmd] "SQLITE_$res" 69 } 70 71 db close 72 db2 close 73 db3 close 74 75 if {[permutation]=="unix-excl"} { 76 do_test 2.0 { 77 for {set i 0} {$i < 256} {incr i} { 78 sqlite3 db$i test.db 79 execsql { SELECT * FROM t1 } db$i 80 } 81 for {set i 0} {$i < 255} {incr i} { 82 set rc [vfs_shmlock db$i main shared lock 4 1] 83 if {$rc != "SQLITE_OK"} { error $rc } 84 } 85 86 vfs_shmlock db255 main shared lock 4 1 87 } {SQLITE_BUSY} 88 89 do_test 2.1 { vfs_shmlock db255 main exclusive lock 4 1 } SQLITE_BUSY 90 do_test 2.2 { vfs_shmlock db0 main shared unlock 4 1 } SQLITE_OK 91 do_test 2.3 { vfs_shmlock db255 main shared lock 4 1 } SQLITE_OK 92 do_test 2.4 { vfs_shmlock db255 main shared unlock 4 1 } SQLITE_OK 93 do_test 2.5 { vfs_shmlock db255 main exclusive lock 4 1 } SQLITE_BUSY 94 95 do_test 2.6 { 96 for {set i 1} {$i < 255} {incr i} { 97 set rc [vfs_shmlock db255 main exclusive lock 4 1] 98 if {$rc != "SQLITE_BUSY"} { error $rc } 99 set rc [vfs_shmlock db$i main shared unlock 4 1] 100 if {$rc != "SQLITE_OK"} { error $rc } 101 } 102 103 vfs_shmlock db255 main exclusive lock 4 1 104 } {SQLITE_OK} 105 106 vfs_shmlock db255 main exclusive unlock 4 1 107 108 for {set i 0} {$i < 256} {incr i} { 109 db$i close 110 } 111 } 112 113 sqlite3 db0 test.db 114 sqlite3 db1 test.db 115 do_test 3.1 { execsql { SELECT * FROM t1 } db0 } {1 2} 116 do_test 3.2 { execsql { SELECT * FROM t1 } db1 } {1 2} 117 if {$tcl_platform(platform)=="windows"} { 118 set isWindows 1 119 } else { 120 set isWindows 0 121 } 122 123 set L(0) {n n n n n n n n} 124 set L(1) {n n n n n n n n} 125 proc random_lock_test {idx} { 126 global L 127 set iSlot [expr int(rand()*8)] 128 if {[expr int(rand()*2)]} { 129 # Unlock operation 130 if {[lindex $L($idx) $iSlot]!="n"} { 131 vfs_shmlock db$idx main [lindex $L($idx) $iSlot] unlock $iSlot 1 132 lset L($idx) $iSlot n 133 } 134 } else { 135 # Lock operation 136 if {[lindex $L($idx) $iSlot]=="n"} { 137 set locktype [lindex {e s} [expr int(rand()*2)]] 138 set n 1 139 if {$locktype=="e"} { 140 for {set l $iSlot} {$l<8 && [lindex $L($idx) $l]=="n"} {incr l} {} 141 set n [expr int(rand()*($l-$iSlot))+1] 142 # The LockFile() and UnlockFile() apis on windows require that 143 # every unlock correspond exactly to a prior lock. Hence, we cannot 144 # lock arbitrary ranges in this test on windows. 145 if {$::isWindows} {set n 1} 146 # puts "iSlot=$iSlot l=$l L=$L($idx)" 147 # puts "$iSlot $n" 148 } 149 set res [vfs_shmlock db$idx main $locktype lock $iSlot $n] 150 151 set bBusy 0 152 for {set i $iSlot} {$i<($iSlot+$n)} {incr i} { 153 set other [lindex $L([expr ($idx+1)%2]) $i] 154 if {($other!="n" && $locktype=="e")||($other=="e" && $locktype=="s")} { 155 if {$res != "SQLITE_BUSY"} { error "BUSY not detected" } 156 set bBusy 1 157 break 158 } 159 } 160 161 if {$bBusy==0} { 162 if {$res != "SQLITE_OK"} { error "BUSY false-positive" } 163 for {set i $iSlot} {$i<($iSlot+$n)} {incr i} { 164 lset L($idx) $i $locktype 165 } 166 } 167 } 168 } 169 } 170 171 set nStep 100000 172 for {set i 0} {$i < $nStep} {incr i} { 173 random_lock_test 0 174 random_lock_test 1 175 } 176 177 db0 close 178 db1 close 179 180 finish_test