xref: /sqlite-3.40.0/test/shmlock.test (revision 94e02d9c)
194e95ea4Sdan# 2018 December 6
294e95ea4Sdan#
394e95ea4Sdan# The author disclaims copyright to this source code.  In place of
494e95ea4Sdan# a legal notice, here is a blessing:
594e95ea4Sdan#
694e95ea4Sdan#    May you do good and not evil.
794e95ea4Sdan#    May you find forgiveness for yourself and forgive others.
894e95ea4Sdan#    May you share freely, never taking more than you give.
994e95ea4Sdan#
1094e95ea4Sdan#***********************************************************************
1194e95ea4Sdan#
1294e95ea4Sdan
1394e95ea4Sdanset testdir [file dirname $argv0]
1494e95ea4Sdansource $testdir/tester.tcl
1594e95ea4Sdan
1694e95ea4Sdanset testprefix shmlock
1794e95ea4Sdan
1894e95ea4Sdanifcapable !wal {finish_test ; return }
1994e95ea4Sdan
2094e95ea4Sdansqlite3 db2 test.db
2194e95ea4Sdansqlite3 db3 test.db
2294e95ea4Sdan
2394e95ea4Sdando_execsql_test 1.0 {
2494e95ea4Sdan  PRAGMA journal_mode = wal;
2594e95ea4Sdan  CREATE TABLE t1(a, b);
2694e95ea4Sdan  INSERT INTO t1 VALUES(1, 2);
2794e95ea4Sdan} {wal}
2894e95ea4Sdando_test 1.1 { execsql { SELECT * FROM t1 } db2 } {1 2}
2994e95ea4Sdando_test 1.2 { execsql { SELECT * FROM t1 } db3 } {1 2}
3094e95ea4Sdan
3194e95ea4Sdanforeach {tn dbhandle cmd res} {
3294e95ea4Sdan  1    db  {shared    lock   7 1}    OK
3394e95ea4Sdan  2    db2 {exclusive lock   7 1}    BUSY
3494e95ea4Sdan  3    db  {shared    unlock 7 1}    OK
3594e95ea4Sdan  4    db2 {exclusive lock   7 1}    OK
3694e95ea4Sdan  5    db  {shared    lock   7 1}    BUSY
3794e95ea4Sdan  6    db  {exclusive lock   7 1}    BUSY
3894e95ea4Sdan  7    db2 {exclusive unlock 7 1}    OK
3994e95ea4Sdan
4094e95ea4Sdan  8    db  {exclusive lock   0 8}    OK
4194e95ea4Sdan  9    db  {exclusive unlock 0 8}    OK
4294e95ea4Sdan  10   db2 {exclusive lock   0 8}    OK
4394e95ea4Sdan  11   db2 {exclusive unlock 0 8}    OK
4494e95ea4Sdan
4594e95ea4Sdan  12   db  {shared    lock   0 1}    OK
4694e95ea4Sdan  13   db2 {shared    lock   0 1}    OK
4794e95ea4Sdan  14   db3 {shared    lock   0 1}    OK
4894e95ea4Sdan  15   db3 {shared    unlock 0 1}    OK
4994e95ea4Sdan  16   db3 {exclusive lock   0 1}    BUSY
5094e95ea4Sdan  17   db2 {shared    unlock 0 1}    OK
5194e95ea4Sdan  18   db3 {exclusive lock   0 1}    BUSY
5294e95ea4Sdan  19   db  {shared    unlock 0 1}    OK
5394e95ea4Sdan  20   db3 {exclusive lock   0 1}    OK
5494e95ea4Sdan  21   db3 {exclusive unlock 0 1}    OK
5594e95ea4Sdan
5694e95ea4Sdan  22   db  {shared    lock   3 1}    OK
5794e95ea4Sdan  23   db2 {exclusive lock   2 2}    BUSY
5894e95ea4Sdan  24   db  {shared    lock   2 1}    OK
5994e95ea4Sdan  25   db2 {exclusive lock   0 5}    BUSY
6094e95ea4Sdan  26   db2 {exclusive lock   0 4}    BUSY
6194e95ea4Sdan  27   db2 {exclusive lock   0 3}    BUSY
6294e95ea4Sdan  28   db  {shared    unlock 3 1}    OK
6394e95ea4Sdan  29   db2 {exclusive lock   2 2}    BUSY
6494e95ea4Sdan  28   db  {shared    unlock 2 1}    OK
6594e95ea4Sdan  29   db2 {exclusive lock   2 2}    OK
6694e95ea4Sdan  29   db2 {exclusive unlock 2 2}    OK
6794e95ea4Sdan} {
6894e95ea4Sdan  do_test 1.3.$tn [list vfs_shmlock $dbhandle main {*}$cmd] "SQLITE_$res"
6994e95ea4Sdan}
7094e95ea4Sdan
7194e95ea4Sdandb  close
7294e95ea4Sdandb2 close
7394e95ea4Sdandb3 close
7494e95ea4Sdan
7594e95ea4Sdanif {[permutation]=="unix-excl"} {
7694e95ea4Sdan  do_test 2.0 {
7794e95ea4Sdan    for {set i 0} {$i < 256} {incr i} {
7894e95ea4Sdan      sqlite3 db$i test.db
7994e95ea4Sdan      execsql { SELECT * FROM t1 } db$i
8094e95ea4Sdan    }
8194e95ea4Sdan    for {set i 0} {$i < 255} {incr i} {
8294e95ea4Sdan      set rc [vfs_shmlock db$i main shared lock 4 1]
8394e95ea4Sdan      if {$rc != "SQLITE_OK"} { error $rc }
8494e95ea4Sdan    }
8594e95ea4Sdan
8694e95ea4Sdan    vfs_shmlock db255 main shared lock 4 1
8794e95ea4Sdan  } {SQLITE_BUSY}
8894e95ea4Sdan
8994e95ea4Sdan  do_test 2.1 { vfs_shmlock db255 main exclusive lock   4 1 } SQLITE_BUSY
9094e95ea4Sdan  do_test 2.2 { vfs_shmlock db0   main shared    unlock 4 1 } SQLITE_OK
9194e95ea4Sdan  do_test 2.3 { vfs_shmlock db255 main shared    lock   4 1 } SQLITE_OK
9294e95ea4Sdan  do_test 2.4 { vfs_shmlock db255 main shared    unlock 4 1 } SQLITE_OK
9394e95ea4Sdan  do_test 2.5 { vfs_shmlock db255 main exclusive lock   4 1 } SQLITE_BUSY
9494e95ea4Sdan
9594e95ea4Sdan  do_test 2.6 {
9694e95ea4Sdan    for {set i 1} {$i < 255} {incr i} {
9794e95ea4Sdan      set rc [vfs_shmlock db255 main exclusive lock 4 1]
9894e95ea4Sdan      if {$rc != "SQLITE_BUSY"} { error $rc }
9994e95ea4Sdan      set rc [vfs_shmlock db$i main shared unlock 4 1]
10094e95ea4Sdan      if {$rc != "SQLITE_OK"} { error $rc }
10194e95ea4Sdan    }
10294e95ea4Sdan
10394e95ea4Sdan    vfs_shmlock db255 main exclusive lock 4 1
10494e95ea4Sdan  } {SQLITE_OK}
10594e95ea4Sdan
10694e95ea4Sdan  vfs_shmlock db255 main exclusive unlock 4 1
10794e95ea4Sdan
10894e95ea4Sdan  for {set i 0} {$i < 256} {incr i} {
10994e95ea4Sdan    db$i close
11094e95ea4Sdan  }
11194e95ea4Sdan}
11294e95ea4Sdan
11394e95ea4Sdansqlite3 db0 test.db
11494e95ea4Sdansqlite3 db1 test.db
11594e95ea4Sdando_test 3.1 { execsql { SELECT * FROM t1 } db0 } {1 2}
11694e95ea4Sdando_test 3.2 { execsql { SELECT * FROM t1 } db1 } {1 2}
117*94e02d9cSdrhif {$tcl_platform(platform)=="windows"} {
118*94e02d9cSdrh  set isWindows 1
119*94e02d9cSdrh} else {
120*94e02d9cSdrh  set isWindows 0
121*94e02d9cSdrh}
12294e95ea4Sdan
12394e95ea4Sdanset L(0) {n n n n n n n n}
12494e95ea4Sdanset L(1) {n n n n n n n n}
12594e95ea4Sdanproc random_lock_test {idx} {
12694e95ea4Sdan  global L
12794e95ea4Sdan  set iSlot [expr int(rand()*8)]
12894e95ea4Sdan  if {[expr int(rand()*2)]} {
12994e95ea4Sdan    # Unlock operation
13094e95ea4Sdan    if {[lindex $L($idx) $iSlot]!="n"} {
13194e95ea4Sdan      vfs_shmlock db$idx main [lindex $L($idx) $iSlot] unlock $iSlot 1
13294e95ea4Sdan      lset L($idx) $iSlot n
13394e95ea4Sdan    }
13494e95ea4Sdan  } else {
13594e95ea4Sdan    # Lock operation
13694e95ea4Sdan    if {[lindex $L($idx) $iSlot]=="n"} {
13794e95ea4Sdan      set locktype [lindex {e s} [expr int(rand()*2)]]
13894e95ea4Sdan      set n 1
13994e95ea4Sdan      if {$locktype=="e"} {
14094e95ea4Sdan        for {set l $iSlot} {$l<8 && [lindex $L($idx) $l]=="n"} {incr l} {}
14194e95ea4Sdan        set n [expr int(rand()*($l-$iSlot))+1]
142*94e02d9cSdrh        # The LockFile() and UnlockFile() apis on windows require that
143*94e02d9cSdrh        # every unlock correspond exactly to a prior lock.  Hence, we cannot
144*94e02d9cSdrh        # lock arbitrary ranges in this test on windows.
145*94e02d9cSdrh        if {$::isWindows} {set n 1}
14694e95ea4Sdan        # puts "iSlot=$iSlot l=$l L=$L($idx)"
14794e95ea4Sdan        # puts "$iSlot $n"
14894e95ea4Sdan      }
14994e95ea4Sdan      set res [vfs_shmlock db$idx main $locktype lock $iSlot $n]
15094e95ea4Sdan
15194e95ea4Sdan      set bBusy 0
15294e95ea4Sdan      for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
15394e95ea4Sdan        set other [lindex $L([expr ($idx+1)%2]) $i]
15494e95ea4Sdan        if {($other!="n" && $locktype=="e")||($other=="e" && $locktype=="s")} {
15594e95ea4Sdan          if {$res != "SQLITE_BUSY"} { error "BUSY not detected" }
15694e95ea4Sdan          set bBusy 1
15794e95ea4Sdan          break
15894e95ea4Sdan        }
15994e95ea4Sdan      }
16094e95ea4Sdan
16194e95ea4Sdan      if {$bBusy==0} {
16294e95ea4Sdan        if {$res != "SQLITE_OK"} { error "BUSY false-positive" }
16394e95ea4Sdan        for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
16494e95ea4Sdan          lset L($idx) $i $locktype
16594e95ea4Sdan        }
16694e95ea4Sdan      }
16794e95ea4Sdan    }
16894e95ea4Sdan  }
16994e95ea4Sdan}
17094e95ea4Sdan
17194e95ea4Sdanset nStep 100000
17294e95ea4Sdanfor {set i 0} {$i < $nStep} {incr i} {
17394e95ea4Sdan  random_lock_test 0
17494e95ea4Sdan  random_lock_test 1
17594e95ea4Sdan}
17694e95ea4Sdan
17794e95ea4Sdandb0 close
17894e95ea4Sdandb1 close
17994e95ea4Sdan
18094e95ea4Sdanfinish_test
181