]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Added the SQLITE_FCNTL_WIN32_AV_RETRY file control for configuring the
authordrh <drh@noemail.net>
Wed, 13 Jul 2011 16:03:46 +0000 (16:03 +0000)
committerdrh <drh@noemail.net>
Wed, 13 Jul 2011 16:03:46 +0000 (16:03 +0000)
retry counts and delays in the windows VFS.

FossilOrigin-Name: 7aaf0a6ae1238129e07eb191ca3f043df445e27a

manifest
manifest.uuid
src/os_win.c
src/sqlite.h.in
src/test1.c
test/win32lock.test

index 00a73b3bc962e8ff4162464039d83b9edff12a40..8568405a643d275c14caa0011325078311617a7c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\sthe\simproved\santi-virus\sdefenses\sinto\sthe\strunk.
-D 2011-07-12T14:38:25.733
+C Added\sthe\sSQLITE_FCNTL_WIN32_AV_RETRY\sfile\scontrol\sfor\sconfiguring\sthe\nretry\scounts\sand\sdelays\sin\sthe\swindows\sVFS.
+D 2011-07-13T16:03:46.096
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -166,7 +166,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
 F src/os_unix.c d3e7b17100704ee0fe2ef71a98c478b947480f4d
-F src/os_win.c 57778b70d209f30070dc70e0e9f8e4adba0de5bc
+F src/os_win.c c5eadb2c0fc11347296a660f77b9844090265c0c
 F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41
 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1
 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
@@ -181,14 +181,14 @@ F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
 F src/select.c d219c4b68d603cc734b6f9b1e2780fee12a1fa0d
 F src/shell.c bbe7818ff5bc8614105ceb81ad67b8bdc0b671dd
-F src/sqlite.h.in 4b7255c10d39c5faf089dbd29cde7c367ff39f1f
+F src/sqlite.h.in badc4f56b9b57a8731475c2ddbccd8198ce33b9b
 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93
 F src/sqliteInt.h ba4a6d6288efb25b84bc0d7d0aaf80f9b42523ba
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
 F src/tclsqlite.c c355b33803fb756dc09297ec84d19604301fa622
-F src/test1.c 6623e003ce840ed4a303918dbbc124f9e222974c
+F src/test1.c 693d9a63dfe2c68b167080c99cab82f267f5a38e
 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432
 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
@@ -911,7 +911,7 @@ F test/where9.test 24f19ad14bb1b831564ced5273e681e495662848
 F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a
 F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5
 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
-F test/win32lock.test 58d2505e035a8175c2db524e58e7c5c9bf1a926c
+F test/win32lock.test 0a16a7df4a51575bda27529ac992a5a94e4a38bd
 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
 F tool/build-shell.sh 12aa4391073a777fcb6dcc490b219a018ae98bac
 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
@@ -952,7 +952,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262
-P 03af4c175c6ba303ec0a5be25fd42771e38f7347 36f11acc531a524407e03c797a6a1bcf88bad809
-R 15ec97d6baeea0684b5deea8be1be88e
+P 0207fd9b0c0f6baa3c2cb8ba588ad585507848b3
+R c10af965bd436aa363363314cb7d7b89
 U drh
-Z 2176be5b1a19aaddd13f35903c55d94b
+Z 2357d1ef0784887fd664a2ba2dbc9797
index 21872bd98141a78a4461176f519f9f298715108a..b78982fe751e4a828c708edca9d5b681f603a126 100644 (file)
@@ -1 +1 @@
-0207fd9b0c0f6baa3c2cb8ba588ad585507848b3
\ No newline at end of file
+7aaf0a6ae1238129e07eb191ca3f043df445e27a
\ No newline at end of file
index 7a1713a610d2e8e7deea7ed3a64e334fcefc51fb..2d4f0adad2f46a50b55bccf3eccc217fa78e7e69 100644 (file)
@@ -414,6 +414,8 @@ static int winLogErrorAtLine(
 #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
 # define SQLITE_WIN32_IOERR_RETRY_DELAY 25
 #endif
+static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY;
+static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
 
 /*
 ** If a ReadFile() or WriteFile() error occurs, invoke this routine
@@ -422,14 +424,14 @@ static int winLogErrorAtLine(
 */
 static int retryIoerr(int *pnRetry){
   DWORD e;
-  if( *pnRetry>=SQLITE_WIN32_IOERR_RETRY ){
+  if( *pnRetry>=win32IoerrRetry ){
     return 0;
   }
   e = GetLastError();
   if( e==ERROR_ACCESS_DENIED ||
       e==ERROR_LOCK_VIOLATION ||
       e==ERROR_SHARING_VIOLATION ){
-    Sleep(SQLITE_WIN32_IOERR_RETRY_DELAY*(1+*pnRetry));
+    Sleep(win32IoerrRetryDelay*(1+*pnRetry));
     ++*pnRetry;
     return 1;
   }
@@ -443,7 +445,7 @@ static void logIoerr(int nRetry){
   if( nRetry ){
     sqlite3_log(SQLITE_IOERR, 
       "delayed %dms for lock/sharing conflict",
-      SQLITE_WIN32_IOERR_RETRY_DELAY*nRetry*(nRetry+1)/2
+      win32IoerrRetryDelay*nRetry*(nRetry+1)/2
     );
   }
 }
@@ -1356,6 +1358,20 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
     case SQLITE_FCNTL_SYNC_OMITTED: {
       return SQLITE_OK;
     }
+    case SQLITE_FCNTL_WIN32_AV_RETRY: {
+      int *a = (int*)pArg;
+      if( a[0]>0 ){
+        win32IoerrRetry = a[0];
+      }else{
+        a[0] = win32IoerrRetry;
+      }
+      if( a[1]>0 ){
+        win32IoerrRetryDelay = a[1];
+      }else{
+        a[1] = win32IoerrRetryDelay;
+      }
+      return SQLITE_OK;
+    }
   }
   return SQLITE_NOTFOUND;
 }
index 2e6ca2b74a5307c126a514c38aca09e4baa6ab30..b8e8bfbc463357220a243459024bd89466ddf4ad 100644 (file)
@@ -736,6 +736,23 @@ struct sqlite3_io_methods {
 ** Applications should not call [sqlite3_file_control()] with this
 ** opcode as doing so may disrupt the operation of the specialized VFSes
 ** that do require it.  
+**
+** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
+** retry counts and intervals for certain disk I/O operations for the
+** windows [VFS] in order to work to provide robustness against
+** anti-virus programs.  By default, the windows VFS will retry file read,
+** file write, and file delete opertions up to 10 times, with a delay
+** of 25 milliseconds before the first retry and with the delay increasing
+** by an additional 25 milliseconds with each subsequent retry.  This
+** opcode allows those to values (10 retries and 25 milliseconds of delay)
+** to be adjusted.  The values are changed for all database connections
+** within the same process.  The argument is a pointer to an array of two
+** integers where the first integer i the new retry count and the second
+** integer is the delay.  If either integer is negative, then the setting
+** is not changed but instead the prior value of that setting is written
+** into the array entry, allowing the current retry settings to be
+** interrogated.  The zDbName parameter is ignored.
+** 
 */
 #define SQLITE_FCNTL_LOCKSTATE        1
 #define SQLITE_GET_LOCKPROXYFILE      2
@@ -745,7 +762,7 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_CHUNK_SIZE       6
 #define SQLITE_FCNTL_FILE_POINTER     7
 #define SQLITE_FCNTL_SYNC_OMITTED     8
-
+#define SQLITE_FCNTL_WIN32_AV_RETRY   9
 
 /*
 ** CAPI3REF: Mutex Handle
index 91bb1b4998e8456702090d2a180fb69683590fb3..3301ab7403ba2c61e46cc64b5efea753842792ad 100644 (file)
@@ -5096,6 +5096,39 @@ static int file_control_lockproxy_test(
   return TCL_OK;  
 }
 
+/*
+** tclcmd:   file_control_win32_av_retry DB  NRETRY  DELAY
+**
+** This TCL command runs the sqlite3_file_control interface with
+** the SQLITE_FCNTL_WIN32_AV_RETRY opcode.
+*/
+static int file_control_win32_av_retry(
+  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int objc,              /* Number of arguments */
+  Tcl_Obj *CONST objv[]  /* Command arguments */
+){
+  sqlite3 *db;
+  int rc;
+  int a[2];
+  char z[100];
+
+  if( objc!=4 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"",
+        Tcl_GetStringFromObj(objv[0], 0), " DB NRETRY DELAY", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
+    return TCL_ERROR;
+  }
+  if( Tcl_GetIntFromObj(interp, objv[2], &a[0]) ) return TCL_ERROR;
+  if( Tcl_GetIntFromObj(interp, objv[3], &a[1]) ) return TCL_ERROR;
+  rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_AV_RETRY, (void*)a);
+  sqlite3_snprintf(sizeof(z), z, "%d %d %d", rc, a[0], a[1]);
+  Tcl_AppendResult(interp, z, (char*)0);
+  return TCL_OK;  
+}
+
 
 /*
 ** tclcmd:   sqlite3_vfs_list
@@ -5638,7 +5671,7 @@ static int win32_file_lock(
     Tcl_AppendResult(interp, zBuf, (char*)0);
     return TCL_OK;
   }
-  while( x.h && retry<10 ){
+  while( x.h && retry<30 ){
     retry++;
     Sleep(100);
   }
@@ -5662,6 +5695,7 @@ static int win32_file_lock(
 }
 #endif
 
+
 /*
 **      optimization_control DB OPT BOOLEAN
 **
@@ -5892,7 +5926,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "file_control_lasterrno_test", file_control_lasterrno_test,  0   },
      { "file_control_lockproxy_test", file_control_lockproxy_test,  0   },
      { "file_control_chunksize_test", file_control_chunksize_test,  0   },
-     { "file_control_sizehint_test", file_control_sizehint_test,  0   },
+     { "file_control_sizehint_test",  file_control_sizehint_test,   0   },
+     { "file_control_win32_av_retry", file_control_win32_av_retry,  0   },
      { "sqlite3_vfs_list",           vfs_list,     0   },
      { "sqlite3_create_function_v2", test_create_function_v2, 0 },
 
index 0fc88eb3f74e7482c8a026a33037ad0106834e34..802ea27d16d21109c521f2c65347e8511d8f9108 100644 (file)
@@ -67,6 +67,40 @@ while {1} {
   }
   set ::log {}
 }
+
+do_test win32lock-2.0 {
+  file_control_win32_av_retry db -1 -1
+} {0 10 25}
+do_test win32lock-2.1 {
+  file_control_win32_av_retry db 1 1
+} {0 1 1}
+
+set delay1 50
+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-2.2-$delay1-fin {
+       set ::msg
+    } {disk I/O error}
+    break
+  } else {
+    do_test win32lock-2.2-$delay1 {
+       set ::msg
+    } {1 100000 2 50000 3 25000 4 12500}
+    if {$::log!=""} {
+      do_test win32lock-2.2-$delay1-log1 {
+        regsub {\d+} $::log # x
+        set x
+      } {{delayed #ms for lock/sharing conflict}}
+    }
+    incr delay1 50
+  }
+  set ::log {}
+}
+
+file_control_win32_av_retry db 10 25
 sqlite3_test_control_pending_byte $old_pending_byte
 sqlite3_shutdown
 test_sqlite3_log