From: drh Date: Mon, 11 Jul 2011 18:17:56 +0000 (+0000) Subject: Change the windows backend to retry read and write requests if the encounter X-Git-Tag: version-3.7.8~38^2~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d9ef0a612105c623790418d46967b420fc530ad;p=thirdparty%2Fsqlite.git Change the windows backend to retry read and write requests if the encounter ERROR_LOCK_VIOLATION and ERROR_SHARING_VIOLATION errors - which we think sometimes happens due to agressive anti-virus software. FossilOrigin-Name: c20aca06610407c197ea50ea77c2591aacf2252a --- diff --git a/manifest b/manifest index 4f1bbb1b0b..bf84f0f2ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\son\sunix. -D 2011-07-09T16:17:18.236 +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 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 eafcd6b91cf204a7ef29ac1ef2a1b7132e132e58 +F src/os_win.c 6ba8a531bdc739b23143e8f1d26222ead4d0bdb0 F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -951,7 +951,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 418a4da2a96cf33055f18c9a667754fad2111cf3 -R bd1403a9e638958833ef8e7e7178479a +P 90b1aea17400bbda5ebc8ae4eb4e12127519e42e +R 349c7f009f94630db798c4428c847d95 U drh -Z 18ede22d9ea411d29db6ab17e40995c3 +Z 6ec74c1e47a6a671533b542ae146a0f8 diff --git a/manifest.uuid b/manifest.uuid index 0650cd683d..2020e584ff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90b1aea17400bbda5ebc8ae4eb4e12127519e42e \ No newline at end of file +c20aca06610407c197ea50ea77c2591aacf2252a \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index bd0f2f216a..59baeebb5f 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -402,6 +402,33 @@ static int winLogErrorAtLine( return errcode; } +/* +** The number of times that a ReadFile() or WriteFile() will be retried +** following a locking error. +*/ +#ifndef SQLITE_WIN32_IOERR_RETRY +# define SQLITE_WIN32_IOERR_RETRY 5 +#endif + +/* +** If a ReadFile() or WriteFile() error occurs, invoke this routine +** to see if it should be retried. Return TRUE to retry. Return FALSE +** to give up with an error. +*/ +static int retryIoerr(int *pnRetry){ + DWORD e; + if( *pnRetry>=SQLITE_WIN32_IOERR_RETRY ){ + return 0; + } + e = GetLastError(); + if( e==ERROR_LOCK_VIOLATION || e==ERROR_SHARING_VIOLATION ){ + Sleep(50 + 50*(*pnRetry)); + ++*pnRetry; + return 1; + } + return 0; +} + #if SQLITE_OS_WINCE /************************************************************************* ** This section contains code for WinCE only. @@ -820,6 +847,7 @@ static int winRead( ){ winFile *pFile = (winFile*)id; /* file handle */ DWORD nRead; /* Number of bytes actually read from file */ + int nRetry = 0; /* Number of retrys */ assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_READ); @@ -828,7 +856,8 @@ static int winRead( if( seekWinFile(pFile, offset) ){ return SQLITE_FULL; } - if( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ + while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ + if( retryIoerr(&nRetry) ) continue; pFile->lastErrno = GetLastError(); return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath); } @@ -866,8 +895,14 @@ static int winWrite( u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ int nRem = amt; /* Number of bytes yet to be written */ DWORD nWrite; /* Bytes written by each WriteFile() call */ + int nRetry = 0; /* Number of retries */ - while( nRem>0 && WriteFile(pFile->h, aRem, nRem, &nWrite, 0) && nWrite>0 ){ + while( nRem>0 ){ + if( !WriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ + if( retryIoerr(&nRetry) ) continue; + break; + } + if( nWrite<=0 ) break; aRem += nWrite; nRem -= nWrite; }