From: drh Date: Wed, 13 Jul 2011 16:03:46 +0000 (+0000) Subject: Added the SQLITE_FCNTL_WIN32_AV_RETRY file control for configuring the X-Git-Tag: version-3.7.8~38^2~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d0cdf012a2cfb309a57c1d3bf26f7045c7ce853f;p=thirdparty%2Fsqlite.git Added the SQLITE_FCNTL_WIN32_AV_RETRY file control for configuring the retry counts and delays in the windows VFS. FossilOrigin-Name: 7aaf0a6ae1238129e07eb191ca3f043df445e27a --- diff --git a/manifest b/manifest index 00a73b3bc9..8568405a64 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 21872bd981..b78982fe75 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0207fd9b0c0f6baa3c2cb8ba588ad585507848b3 \ No newline at end of file +7aaf0a6ae1238129e07eb191ca3f043df445e27a \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 7a1713a610..2d4f0adad2 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -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; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 2e6ca2b74a..b8e8bfbc46 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -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 diff --git a/src/test1.c b/src/test1.c index 91bb1b4998..3301ab7403 100644 --- a/src/test1.c +++ b/src/test1.c @@ -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 }, diff --git a/test/win32lock.test b/test/win32lock.test index 0fc88eb3f7..802ea27d16 100644 --- a/test/win32lock.test +++ b/test/win32lock.test @@ -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