Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add a test for the change on this branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | wal-blocking-lock |
Files: | files | file ages | folders |
SHA1: |
e22dde187eb0b389d6d93e2e39a26fd0 |
User & Date: | dan 2015-03-17 16:01:29.508 |
Context
2015-03-17
| ||
17:08 | Also merge the WAL blocking lock tests that were somehow missed on the previous check-in. (check-in: 7214dab744 user: drh tags: trunk) | |
16:01 | Add a test for the change on this branch. (Closed-Leaf check-in: e22dde187e user: dan tags: wal-blocking-lock) | |
2015-03-10
| ||
20:22 | Arrange for some of the transient locks in WAL mode to block, as a single to the OS to fix priority inversions. (check-in: c6e6d5f4e0 user: drh tags: wal-blocking-lock) | |
Changes
Changes to src/test_vfs.c.
︙ | ︙ | |||
962 963 964 965 966 967 968 969 970 971 972 973 | return rc; } static void tvfsShmBarrier(sqlite3_file *pFile){ TestvfsFd *pFd = tvfsGetFd(pFile); Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData); if( p->isFullshm ){ sqlite3OsShmBarrier(pFd->pReal); return; } | > > > > > < < < < < < | 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 | return rc; } static void tvfsShmBarrier(sqlite3_file *pFile){ TestvfsFd *pFd = tvfsGetFd(pFile); Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData); if( p->pScript && p->mask&TESTVFS_SHMBARRIER_MASK ){ const char *z = pFd->pShm ? pFd->pShm->zFile : ""; tvfsExecTcl(p, "xShmBarrier", Tcl_NewStringObj(z, -1), pFd->pShmId, 0, 0); } if( p->isFullshm ){ sqlite3OsShmBarrier(pFd->pReal); return; } } static int tvfsShmUnmap( sqlite3_file *pFile, int deleteFlag ){ int rc = SQLITE_OK; |
︙ | ︙ | |||
1528 1529 1530 1531 1532 1533 1534 | p->mask = TESTVFS_ALL_MASK; sqlite3_vfs_register(pVfs, isDefault); return TCL_OK; bad_args: | | | 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 | p->mask = TESTVFS_ALL_MASK; sqlite3_vfs_register(pVfs, isDefault); return TCL_OK; bad_args: Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-fullshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?"); return TCL_ERROR; } int Sqlitetestvfs_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp, "testvfs", testvfs_cmd, 0, 0); return TCL_OK; } #endif |
Changes to test/lock_common.tcl.
︙ | ︙ | |||
82 83 84 85 86 87 88 | } return $chan } # Execute a command in a child testfixture process, connected by two-way # channel $chan. Return the result of the command, or an error message. # | | > > > | | > | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | } return $chan } # Execute a command in a child testfixture process, connected by two-way # channel $chan. Return the result of the command, or an error message. # proc testfixture {chan cmd args} { if {[llength $args] == 0} { fconfigure $chan -blocking 1 puts $chan $cmd puts $chan OVER set r "" while { 1 } { set line [gets $chan] if { $line == "OVER" } { set res [lindex $r 1] if { [lindex $r 0] } { error $res } return $res } if {[eof $chan]} { return "ERROR: Child process hung up" } append r $line } return $r } else { set ::tfnb($chan) "" fconfigure $chan -blocking 0 -buffering none puts $chan $cmd puts $chan OVER fileevent $chan readable [list testfixture_script_cb $chan [lindex $args 0]] return "" } } proc testfixture_script_cb {chan script} { if {[eof $chan]} { append ::tfnb($chan) "ERROR: Child process hung up" set line "OVER" } else { set line [gets $chan] } if { $line == "OVER" } { uplevel #0 $script [list [lindex $::tfnb($chan) 1]] unset ::tfnb($chan) fileevent $chan readable "" } else { append ::tfnb($chan) $line } } proc testfixture_nb_cb {varname chan} { if {[eof $chan]} { append ::tfnb($chan) "ERROR: Child process hung up" set line "OVER" |
︙ | ︙ |
Added test/walblock.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | # 2015 Mar 17 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } if {$::tcl_platform(platform)!="unix"} { finish_test ; return } set testprefix walblock catch { db close } testvfs tvfs -fullshm 1 foreach f [glob test.db*] { forcedelete $f } sqlite3 db test.db -vfs tvfs do_execsql_test 1.1.0 { CREATE TABLE t1(x, y); INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); PRAGMA journal_mode = wal; INSERT INTO t1 VALUES(7, 8); } {wal} do_test 1.1.1 { lsort [glob test.db*] } {test.db test.db-shm test.db-wal} do_test 1.1.2 { set C [launch_testfixture] testfixture $C { sqlite3 db test.db db eval { SELECT * FROM t1 } } } {1 2 3 4 5 6 7 8} do_test 1.1.3 { set ::out [list] testfixture $C { db eval { SELECT * FROM t1 } } [list set ::out] set ::out } {} do_test 1.1.4 { vwait ::out set ::out } {1 2 3 4 5 6 7 8} # # Test that if a read client cannot read the wal-index header because a # write client is in the middle of updating it, the reader blocks until # the writer finishes. # # 1. Open a write transaction using client [db] in this process. # # 2. Attempt to commit the write transaction. Intercept the xShmBarrier() # call made by the writer between updating the two copies of the # wal-index header. # # 3. Within the xShmBarrier() callback, make an asynchronous request to # the other process to read from the database. It should block, as it # cannot get read the wal-index header. # # 4. Still in xShmBarrier(), wait for 5 seconds. Check that the other # process has not answered the request. # # 5: Finish committing the transaction. Then wait for 0.5 seconds more. # Ensure that the second process has by this stage read the database # and that the snapshot it read included the transaction committed in # step (4). # do_execsql_test 1.2.1 { BEGIN; INSERT INTO t1 VALUES(9, 10); } {} tvfs script barrier_callback tvfs filter xShmBarrier proc barrier_callback {method args} { set ::out "" testfixture $::C { db eval { SELECT * FROM t1 } } {set ::out} do_test "1.2.2.(blocking 5 seconds)" { set ::continue 0 after 5000 {set ::continue 1} vwait ::continue set ::out } {} } execsql COMMIT do_test "1.2.3.(blocking 0.5 seconds)" { set ::continue 0 after 500 {set ::continue 1} vwait ::continue set ::out } {1 2 3 4 5 6 7 8 9 10} finish_test |