AryaWu/sqlite
0
1# 2018 December 62#3# The author disclaims copyright to this source code. In place of4# 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.tcl15 16set testprefix shmlock17 18ifcapable !wal {finish_test ; return }19 20sqlite3 db2 test.db21sqlite3 db3 test.db22 23do_execsql_test 1.0 {24 PRAGMA journal_mode = wal;25 CREATE TABLE t1(a, b);26 INSERT INTO t1 VALUES(1, 2);27} {wal}28do_test 1.1 { execsql { SELECT * FROM t1 } db2 } {1 2}29do_test 1.2 { execsql { SELECT * FROM t1 } db3 } {1 2}30 31foreach {tn dbhandle cmd res} {32 1 db {shared lock 7 1} OK33 2 db2 {exclusive lock 7 1} BUSY34 3 db {shared unlock 7 1} OK35 4 db2 {exclusive lock 7 1} OK36 5 db {shared lock 7 1} BUSY37 6 db {exclusive lock 7 1} BUSY38 7 db2 {exclusive unlock 7 1} OK39 40 8 db {exclusive lock 0 8} OK41 9 db {exclusive unlock 0 8} OK42 10 db2 {exclusive lock 0 8} OK43 11 db2 {exclusive unlock 0 8} OK44 45 12 db {shared lock 0 1} OK46 13 db2 {shared lock 0 1} OK47 14 db3 {shared lock 0 1} OK48 15 db3 {shared unlock 0 1} OK49 16 db3 {exclusive lock 0 1} BUSY50 17 db2 {shared unlock 0 1} OK51 18 db3 {exclusive lock 0 1} BUSY52 19 db {shared unlock 0 1} OK53 20 db3 {exclusive lock 0 1} OK54 21 db3 {exclusive unlock 0 1} OK55 56 22 db {shared lock 3 1} OK57 23 db2 {exclusive lock 2 2} BUSY58 24 db {shared lock 2 1} OK59 25 db2 {exclusive lock 0 5} BUSY60 26 db2 {exclusive lock 0 4} BUSY61 27 db2 {exclusive lock 0 3} BUSY62 28 db {shared unlock 3 1} OK63 29 db2 {exclusive lock 2 2} BUSY64 28 db {shared unlock 2 1} OK65 29 db2 {exclusive lock 2 2} OK66 29 db2 {exclusive unlock 2 2} OK67} {68 do_test 1.3.$tn [list vfs_shmlock $dbhandle main {*}$cmd] "SQLITE_$res"69}70 71db close72db2 close73db3 close74 75if {[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$i80 }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 187 } {SQLITE_BUSY}88 89 do_test 2.1 { vfs_shmlock db255 main exclusive lock 4 1 } SQLITE_BUSY90 do_test 2.2 { vfs_shmlock db0 main shared unlock 4 1 } SQLITE_OK91 do_test 2.3 { vfs_shmlock db255 main shared lock 4 1 } SQLITE_OK92 do_test 2.4 { vfs_shmlock db255 main shared unlock 4 1 } SQLITE_OK93 do_test 2.5 { vfs_shmlock db255 main exclusive lock 4 1 } SQLITE_BUSY94 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 1104 } {SQLITE_OK}105 106 vfs_shmlock db255 main exclusive unlock 4 1107 108 for {set i 0} {$i < 256} {incr i} {109 db$i close110 }111}112 113sqlite3 db0 test.db114sqlite3 db1 test.db115do_test 3.1 { execsql { SELECT * FROM t1 } db0 } {1 2}116do_test 3.2 { execsql { SELECT * FROM t1 } db1 } {1 2}117if {$tcl_platform(os) eq "Windows NT"} {118 set isWindows 1119} else {120 set isWindows 0121}122 123set L(0) {n n n n n n n n}124set L(1) {n n n n n n n n}125proc random_lock_test {idx} {126 global L127 set iSlot [expr int(rand()*8)]128 if {[expr int(rand()*2)]} {129 # Unlock operation130 if {[lindex $L($idx) $iSlot]!="n"} {131 vfs_shmlock db$idx main [lindex $L($idx) $iSlot] unlock $iSlot 1132 lset L($idx) $iSlot n133 }134 } else {135 # Lock operation136 if {[lindex $L($idx) $iSlot]=="n"} {137 set locktype [lindex {e s} [expr int(rand()*2)]]138 set n 1139 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 that143 # every unlock correspond exactly to a prior lock. Hence, we cannot144 # 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 0152 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 1157 break158 } 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 $locktype165 }166 }167 }168 }169}170 171set nStep 100000172for {set i 0} {$i < $nStep} {incr i} {173 random_lock_test 0174 random_lock_test 1175}176 177db0 close178db1 close179 180finish_test181 