/ Check-in [b0fcc99d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add a simple test case for inter-process locking. (CVS 1752)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b0fcc99d227c061203fb1e0f4583b66723033159
User & Date: danielk1977 2004-06-28 08:25:48
Context
2004-06-28
11:52
Get all tests working under win2k. (CVS 1753) check-in: 168112c8 user: drh tags: trunk
08:25
Add a simple test case for inter-process locking. (CVS 1752) check-in: b0fcc99d user: danielk1977 tags: trunk
04:52
Fix some problems with multi-file transaction rollback. (CVS 1751) check-in: 06e8e30b user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

   792    792     /* A PENDING lock is needed before acquiring a SHARED lock and before
   793    793     ** acquiring an EXCLUSIVE lock.  For the SHARED lock, the PENDING will
   794    794     ** be released.
   795    795     */
   796    796     if( locktype==SHARED_LOCK 
   797    797         || (locktype==EXCLUSIVE_LOCK && id->locktype<PENDING_LOCK)
   798    798     ){
   799         -    lock.l_type = F_RDLCK;
          799  +    lock.l_type = (locktype==SHARED_LOCK?F_RDLCK:F_WRLCK);
   800    800       lock.l_start = PENDING_BYTE;
   801    801       s = fcntl(id->h, F_SETLK, &lock);
   802    802       if( s ){
   803    803         rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
   804    804         goto end_lock;
   805    805       }
   806    806     }

Added test/lock2.test.

            1  +# 2001 September 15
            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  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this script is database locks between competing processes.
           13  +#
           14  +# $Id: lock2.test,v 1.1 2004/06/28 08:25:48 danielk1977 Exp $
           15  +
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +
           20  +# Launch another testfixture process to be controlled by this one. A
           21  +# channel name is returned that may be passed as the first argument to proc
           22  +# 'testfixture' to execute a command. The child testfixture process is shut
           23  +# down by closing the channel.
           24  +proc launch_testfixture {} {
           25  +  set chan [open "|[file join . testfixture] tf_main.tcl" r+]
           26  +  fconfigure $chan -buffering line
           27  +  return $chan
           28  +}
           29  +
           30  +# Execute a command in a child testfixture process, connected by two-way
           31  +# channel $chan. Return the result of the command, or an error message.
           32  +proc testfixture {chan cmd} {
           33  +  puts $chan $cmd
           34  +  puts $chan OVER
           35  +  set r ""
           36  +  while { 1 } {
           37  +    set line [gets $chan]
           38  +    if { $line == "OVER" } { 
           39  +      return $r
           40  +    }
           41  +    append r $line
           42  +  }
           43  +}
           44  +
           45  +# Write the main loop for the child testfixture processes into file
           46  +# tf_main.tcl. The parent (this script) interacts with the child processes
           47  +# via a two way pipe. The parent writes a script to the stdin of the child
           48  +# process, followed by the word "OVER" on a line of it's own. The child
           49  +# process evaluates the script and writes the results to stdout, followed
           50  +# by an "OVER" of its own.
           51  +set f [open tf_main.tcl w]
           52  +puts $f {
           53  +  set l [open log w]
           54  +  set script ""
           55  +  while {![eof stdin]} {
           56  +    flush stdout
           57  +    set line [gets stdin]
           58  +    puts $l "READ $line"
           59  +    if { $line == "OVER" } {
           60  +      catch {eval $script} result
           61  +      puts $result
           62  +      puts $l "WRITE $result"
           63  +      puts OVER
           64  +      puts $l "WRITE OVER"
           65  +      flush stdout
           66  +      set script ""
           67  +    } else {
           68  +      append script $line
           69  +      append script " ; "
           70  +    }
           71  +  }
           72  +  close $l
           73  +}
           74  +close $f
           75  +
           76  +# Simple locking test case:
           77  +#
           78  +# lock2-1.1: Connect a second process to the database.
           79  +# lock2-1.2: Establish a RESERVED lock with this process.
           80  +# lock2-1.3: Get a SHARED lock with the second process.
           81  +# lock2-1.4: Try for a RESERVED lock with process 2. This fails.
           82  +# lock2-1.5: Try to upgrade the first process to EXCLUSIVE, this fails so
           83  +#            it gets PENDING.
           84  +# lock2-1.6: Release the SHARED lock held by the second process. 
           85  +# lock2-1.7: Attempt to reaquire a SHARED lock with the second process.
           86  +#            this fails due to the PENDING lock.
           87  +# lock2-1.8: Ensure the first process can now upgrade to EXCLUSIVE.
           88  +#
           89  +do_test lock2-1.1 {
           90  +  set ::tf1 [launch_testfixture]
           91  +  testfixture $::tf1 {
           92  +    sqlite3 db test.db
           93  +    db eval {select * from sqlite_master}
           94  +  }
           95  +} {}
           96  +do_test lock2-1.2 {
           97  +  execsql {
           98  +    BEGIN;
           99  +    CREATE TABLE abc(a, b, c);
          100  +  }
          101  +} {}
          102  +do_test lock2-1.3 {
          103  +  testfixture $::tf1 {
          104  +    db eval {
          105  +      BEGIN;
          106  +      SELECT * FROM sqlite_master;
          107  +    }
          108  +  }
          109  +} {}
          110  +do_test lock2-1.4 {
          111  +  testfixture $::tf1 {
          112  +    db eval {
          113  +      CREATE TABLE def(d, e, f)
          114  +    }
          115  +  }
          116  +} {database is locked}
          117  +do_test lock2-1.5 {
          118  +  catchsql {
          119  +    COMMIT;
          120  +  }
          121  +} {1 {database is locked}}
          122  +do_test lock2-1.6 {
          123  +  testfixture $::tf1 {
          124  +    db eval {
          125  +      SELECT * FROM sqlite_master;
          126  +      COMMIT;
          127  +    }
          128  +  }
          129  +} {}
          130  +do_test lock2-1.7 {
          131  +  testfixture $::tf1 {
          132  +    db eval {
          133  +      BEGIN;
          134  +      SELECT * FROM sqlite_master;
          135  +    }
          136  +  }
          137  +} {database is locked}
          138  +do_test lock2-1.8 {
          139  +  catchsql {
          140  +    COMMIT;
          141  +  }
          142  +} {0 {}}
          143  +do_test lock2-1.9 {
          144  +  execsql {
          145  +    SELECT * FROM sqlite_master;
          146  +  }
          147  +} {table abc abc 2 {CREATE TABLE abc(a, b, c)}}
          148  +do_test lock2-1.10 {
          149  +  testfixture $::tf1 {
          150  +    db eval {
          151  +      SELECT * FROM sqlite_master;
          152  +    }
          153  +  }
          154  +} {table abc abc 2 {CREATE TABLE abc(a, b, c)}}
          155  +
          156  +finish_test
          157  +