-C Change\sthe\swindows\sbackend\sto\sretry\sread\sand\swrite\srequests\sif\sthe\sencounter\nERROR_LOCK_VIOLATION\sand\sERROR_SHARING_VIOLATION\serrors\s-\swhich\swe\sthink\nsometimes\shappens\sdue\sto\sagressive\santi-virus\ssoftware.
-D 2011-07-11T18:17:56.144
+C Update\sthe\sTCL\scommands\sfor\ssetting\swindows\smanditory\slocks.\nAdd\stest\scases\sfor\smanditory\slock\sdelays\sunder\swindows.
+D 2011-07-11T23:45:44.051
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c c355b33803fb756dc09297ec84d19604301fa622
-F src/test1.c 8eef932f1024f1076a8adb8a6f5d9c5267c9e969
+F src/test1.c 6623e003ce840ed4a303918dbbc124f9e222974c
F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432
F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a
F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
+F test/win32lock.test 7fa3287dccc836fcaa8e0d1e77aa017de5889231
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262
-P 90b1aea17400bbda5ebc8ae4eb4e12127519e42e
-R 349c7f009f94630db798c4428c847d95
+P c20aca06610407c197ea50ea77c2591aacf2252a
+R 4c1b031b9c10734fc2cbb78ed1f104dd
U drh
-Z 6ec74c1e47a6a671533b542ae146a0f8
+Z 4f5517f8772eb0c19d9bc59edbaff4cc
-c20aca06610407c197ea50ea77c2591aacf2252a
\ No newline at end of file
+03af4c175c6ba303ec0a5be25fd42771e38f7347
\ No newline at end of file
return TCL_OK;
}
+#if SQLITE_OS_WIN
+/*
+** Information passed from the main thread into the windows file locker
+** background thread.
+*/
+struct win32FileLocker {
+ HANDLE h; /* Handle of the file to be locked */
+ int delay1; /* Delay before locking */
+ int delay2; /* Delay before unlocking */
+ int ok; /* Finished ok */
+ int err; /* True if an error occurs */
+};
+#endif
+
+
+#if SQLITE_OS_WIN
+/*
+** The background thread that does file locking.
+*/
+static void win32_file_locker(void *pAppData){
+ struct win32FileLocker *p = (struct win32FileLocker*)pAppData;
+ if( p->delay1 ) Sleep(p->delay1);
+ if( LockFile(p->h, 0, 0, 100000000, 0) ){
+ Sleep(p->delay2);
+ UnlockFile(p->h, 0, 0, 100000000, 0);
+ p->ok = 1;
+ }else{
+ p->err = 1;
+ }
+ CloseHandle(p->h);
+ p->h = 0;
+ p->delay1 = 0;
+ p->delay2 = 0;
+}
+#endif
+
+#if SQLITE_OS_WIN
+/*
+** lock_win32_file FILENAME DELAY1 DELAY2
+**
+** Get an exclusive manditory lock on file for DELAY2 milliseconds.
+** Wait DELAY1 milliseconds before acquiring the lock.
+*/
+static int win32_file_lock(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ static struct win32FileLocker x = { 0, 0, 0 };
+ const char *zFilename;
+ int retry = 0;
+
+ if( objc!=4 && objc!=1 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME DELAY1 DELAY2");
+ return TCL_ERROR;
+ }
+ if( objc==1 ){
+ char zBuf[200];
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d %d %d %d %d",
+ x.ok, x.err, x.delay1, x.delay2, x.h);
+ Tcl_AppendResult(interp, zBuf, (char*)0);
+ return TCL_OK;
+ }
+ while( x.h && retry<10 ){
+ retry++;
+ Sleep(100);
+ }
+ if( x.h ){
+ Tcl_AppendResult(interp, "busy", (char*)0);
+ return TCL_ERROR;
+ }
+ if( Tcl_GetIntFromObj(interp, objv[2], &x.delay1) ) return TCL_ERROR;
+ if( Tcl_GetIntFromObj(interp, objv[3], &x.delay2) ) return TCL_ERROR;
+ zFilename = Tcl_GetString(objv[1]);
+ x.h = CreateFile(zFilename, GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ if( !x.h ){
+ Tcl_AppendResult(interp, "cannot open file: ", zFilename, (char*)0);
+ return TCL_ERROR;
+ }
+ _beginthread(win32_file_locker, 0, (void*)&x);
+ Sleep(0);
+ return TCL_OK;
+}
+#endif
/*
** optimization_control DB OPT BOOLEAN
{ "restore_prng_state", restore_prng_state, 0 },
{ "reset_prng_state", reset_prng_state, 0 },
{ "optimization_control", optimization_control,0},
+#if SQLITE_OS_WIN
+ { "lock_win32_file", win32_file_lock, 0 },
+#endif
{ "tcl_objproc", runAsObjProc, 0 },
/* sqlite3_column_*() API */
--- /dev/null
+# 2011 July 11
+#
+# 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.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The
+# focus of this script is recovery from transient manditory locks
+# that sometimes appear on database files due to anti-virus software.
+#
+
+if {$tcl_platform(platform)!="windows"} return
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+set testprefix win32lock
+
+do_test win32lock-1.1 {
+ db eval {
+ PRAGMA cache_size=10;
+ CREATE TABLE t1(x,y);
+ INSERT INTO t1 VALUES(1,randomblob(100000));
+ INSERT INTO t1 VALUES(2,randomblob(50000));
+ INSERT INTO t1 VALUES(3,randomblob(25000));
+ INSERT INTO t1 VALUES(4,randomblob(12500));
+ SELECT x, length(y) FROM t1 ORDER BY rowid;
+ }
+} {1 100000 2 50000 3 25000 4 12500}
+
+unset -nocomplain delay1 rc msg
+set delay1 50
+set rc 0
+set old_pending_byte [sqlite3_test_control_pending_byte 0x40000000]
+while {1} {
+ sqlite3_sleep 10
+ lock_win32_file test.db 0 $::delay1
+ set rc [catch {db eval {SELECT x, length(y) FROM t1 ORDER BY rowid}} msg]
+ if {$rc} {
+ do_test win32lock-1.2-$delay1-fin {
+ set ::msg
+ } {disk I/O error}
+ break
+ } else {
+ do_test win32lock-1.2-$delay1 {
+ set ::msg
+ } {1 100000 2 50000 3 25000 4 12500}
+ incr delay1 50
+ }
+}
+sqlite3_test_control_pending_byte $old_pending_byte
+
+finish_test