From 52564d7002c4f2f64735dfc2d93cdfa827145fb1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 12 Jul 2011 11:04:18 +0000 Subject: [PATCH] Update the anti-virus retry logic for DeleteFile(). Invoke sqlite3_log() for each anti-virus retry. Make the retry delay configurable at compile-time. FossilOrigin-Name: 89f1848d7f7d98b4f7da9218f99ed90d22dd43a8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 44 ++++++++++++++++++-------------------------- test/wal6.test | 13 ++----------- 4 files changed, 28 insertions(+), 45 deletions(-) diff --git a/manifest b/manifest index e631fa3a74..7953e79169 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 +C Update\sthe\santi-virus\sretry\slogic\sfor\sDeleteFile().\s\sInvoke\ssqlite3_log()\nfor\seach\santi-virus\sretry.\s\sMake\sthe\sretry\sdelay\sconfigurable\sat\ncompile-time. +D 2011-07-12T11:04:18.838 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 6ba8a531bdc739b23143e8f1d26222ead4d0bdb0 +F src/os_win.c 4cea89f0a6c98b6a7f4fb3895544af8a07d7807d F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -882,7 +882,7 @@ F test/wal2.test aa0fb2314b3235be4503c06873e41ebfc0757782 F test/wal3.test 5c396cc22497244d627306f4c1d360167353f8dd F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30 F test/wal5.test f06a0427e06db00347e32eb9fa99d6a5c0f2d088 -F test/wal6.test 07aa31ca8892d0527f2c5c5a9a2a87aa421dfaa8 +F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4 @@ -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 c20aca06610407c197ea50ea77c2591aacf2252a -R 4c1b031b9c10734fc2cbb78ed1f104dd +P 03af4c175c6ba303ec0a5be25fd42771e38f7347 +R b94301e8087eadceda58922babc3618f U drh -Z 4f5517f8772eb0c19d9bc59edbaff4cc +Z 71facc3c10c90f54a5e699820f127261 diff --git a/manifest.uuid b/manifest.uuid index 688cc99f9e..ccdb128bfa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03af4c175c6ba303ec0a5be25fd42771e38f7347 \ No newline at end of file +89f1848d7f7d98b4f7da9218f99ed90d22dd43a8 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 59baeebb5f..f0cef15359 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -403,11 +403,16 @@ static int winLogErrorAtLine( } /* -** The number of times that a ReadFile() or WriteFile() will be retried -** following a locking error. +** The number of times that a ReadFile(), WriteFile(), and DeleteFile() +** will be retried following a locking error - probably caused by +** antivirus software. Also the initial delay before the first retry. +** The delay increases linearly with each retry. */ #ifndef SQLITE_WIN32_IOERR_RETRY -# define SQLITE_WIN32_IOERR_RETRY 5 +# define SQLITE_WIN32_IOERR_RETRY 10 +#endif +#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY +# define SQLITE_WIN32_IOERR_RETRY_DELAY 25 #endif /* @@ -422,7 +427,10 @@ static int retryIoerr(int *pnRetry){ } e = GetLastError(); if( e==ERROR_LOCK_VIOLATION || e==ERROR_SHARING_VIOLATION ){ - Sleep(50 + 50*(*pnRetry)); + int delay = SQLITE_WIN32_IOERR_RETRY_DELAY*(1+*pnRetry); + sqlite3_log(SQLITE_IOERR, "delay %dms for lock/sharing violation - " + "probably due to antivirus software", delay); + Sleep(delay); ++*pnRetry; return 1; } @@ -2351,15 +2359,13 @@ static int winOpen( ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving ** up and returning an error. */ -#define MX_DELETION_ATTEMPTS 5 static int winDelete( sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ int cnt = 0; - DWORD rc; - DWORD error = 0; + int rc; void *zConverted; UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(syncDir); @@ -2370,34 +2376,20 @@ static int winDelete( return SQLITE_NOMEM; } if( isNT() ){ - do{ - DeleteFileW(zConverted); - }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES) - || ((error = GetLastError()) == ERROR_ACCESS_DENIED)) - && (++cnt < MX_DELETION_ATTEMPTS) - && (Sleep(100), 1) ); + while( (rc = DeleteFileW(zConverted))!=0 || retryIoerr(&cnt) ){} /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. ** Since the ASCII version of these Windows API do not exist for WINCE, ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ - do{ - DeleteFileA(zConverted); - }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES) - || ((error = GetLastError()) == ERROR_ACCESS_DENIED)) - && (++cnt < MX_DELETION_ATTEMPTS) - && (Sleep(100), 1) ); + while( (rc = DeleteFileW(zConverted))!=0 || retryIoerr(&cnt) ){} #endif } + if( rc ) rc = winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename); free(zConverted); - OSTRACE(("DELETE \"%s\" %s\n", zFilename, - ( (rc==INVALID_FILE_ATTRIBUTES) && (error==ERROR_FILE_NOT_FOUND)) ? - "ok" : "failed" )); - - return ( (rc == INVALID_FILE_ATTRIBUTES) - && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : - winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename); + OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" ))); + return rc; } /* diff --git a/test/wal6.test b/test/wal6.test index 6fae48e9ea..ec31bb8b0f 100644 --- a/test/wal6.test +++ b/test/wal6.test @@ -43,19 +43,11 @@ foreach jmode $all_journal_modes { } {1 2} # Under Windows, you'll get an error trying to delete -# a file this is already opened. For now, make sure -# we get that error, then close the first connection +# a file this is already opened. Close the first connection # so the other tests work. if {$tcl_platform(platform)=="windows"} { if {$jmode=="persist" || $jmode=="truncate"} { - do_test wal6-1.2.$jmode.win { - sqlite3 db2 test.db - catchsql { - PRAGMA journal_mode=WAL; - } db2 - } {1 {disk I/O error}} - db2 close - db close + db close } } @@ -87,4 +79,3 @@ if {$tcl_platform(platform)=="windows"} { } finish_test -