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