From: mistachkin Date: Fri, 2 Mar 2012 22:38:49 +0000 (+0000) Subject: When running on Windows with an NT-based kernel, always use the LockFileEx/UnlockFile... X-Git-Tag: version-3.7.13~11^2~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a5cfb31fdf2f94a3c3ef0ac63177b31a044f8a5;p=thirdparty%2Fsqlite.git When running on Windows with an NT-based kernel, always use the LockFileEx/UnlockFileEx functions (with the correct flags). FossilOrigin-Name: 3e7ba3ddb956056b8132ed383feed4f329c634e0 --- diff --git a/manifest b/manifest index 2f9e043fbf..3a094cf7f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sWin32\sAPIs\sused\sto\sthe\ssystem\scall\stable.\s\sAdd\serror\shandling\scode\sfor\sSetFilePointerEx.\s\sMake\ssure\sthe\slast\serror\snumber\sis\ssaved\sfrom\sthe\scall\sto\sGetFileInformationByHandleEx. -D 2012-03-02T13:47:16.837 +C When\srunning\son\sWindows\swith\san\sNT-based\skernel,\salways\suse\sthe\sLockFileEx/UnlockFileEx\sfunctions\s(with\sthe\scorrect\sflags). +D 2012-03-02T22:38:49.501 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/os.h c3a9db9e8e16f564e1a40cea1687dad69634262c F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 0e3d2942d228d0366fb80a3640f35caf413b66d1 -F src/os_win.c 7378d50e4f8c3dafc0c11ca99615801c84329a4d +F src/os_win.c f6b9fa7a93d16779b0504d8c5d438fdd0ef022bb F src/pager.c 3955b62cdb5bb64559607cb474dd12a6c8e1d4a5 F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5 F src/parse.y 1ddd71ae55f4b7cbb2672526ea4de023de0f519e @@ -991,7 +991,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P cbf23b461f599d0b025c0f42dd3189cfa4e84bac -R f72d2ca1c8333360bf3d39a3248646ef +P a782d2dc3cd4ef49ed46b361cdd331be846c3d50 +R 5657a63a45c0ba0c63e40023bb562ed0 U mistachkin -Z bc3c857da09d5ea46a27e32ed356379b +Z a7d3129db9e33b537945aea438ba067d diff --git a/manifest.uuid b/manifest.uuid index 30bb20d31a..7b9f86ea2e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a782d2dc3cd4ef49ed46b361cdd331be846c3d50 \ No newline at end of file +3e7ba3ddb956056b8132ed383feed4f329c634e0 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index bc8bf3e267..4c56392a6d 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1277,6 +1277,49 @@ static void logIoerr(int nRetry){ } } +/* +** Lock a file region. +*/ +static BOOL winLockFile( + HANDLE hFile, + DWORD flags, + DWORD offsetLow, + DWORD offsetHigh, + DWORD numBytesLow, + DWORD numBytesHigh +){ + if( isNT() ){ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osLockFileEx(hFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); + }else{ + return osLockFile(hFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh); + } +} + +/* +** Unlock a file region. + */ +static BOOL winUnlockFile( + HANDLE hFile, + DWORD offsetLow, + DWORD offsetHigh, + DWORD numBytesLow, + DWORD numBytesHigh +){ + if( isNT() ){ + OVERLAPPED ovlp; + memset(&ovlp, 0, sizeof(OVERLAPPED)); + ovlp.Offset = offsetLow; + ovlp.OffsetHigh = offsetHigh; + return osUnlockFileEx(hFile, 0, numBytesLow, numBytesHigh, &ovlp); + }else{ + return osUnlockFile(hFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh); + } +} + #if SQLITE_OS_WINCE /************************************************************************* ** This section contains code for WinCE only. @@ -1957,6 +2000,30 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ # define LOCKFILE_FAIL_IMMEDIATELY 1 #endif +#ifndef LOCKFILE_EXCLUSIVE_LOCK +# define LOCKFILE_EXCLUSIVE_LOCK 2 +#endif + +/* +** Historically, SQLite has used both the LockFile and LockFileEx functions. +** When the LockFile function was used, it was always expected to fail +** immediately if the lock could not be obtained. Also, it always expected to +** obtain an exclusive lock. These flags are used with the LockFileEx function +** and reflect those expectations; therefore, they should not be changed. +*/ +#ifndef SQLITE_LOCKFILE_FLAGS +# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \ + LOCKFILE_EXCLUSIVE_LOCK) +#endif + +/* +** Currently, SQLite never calls the LockFileEx function without wanting the +** call to fail immediately if the lock cannot be obtained. +*/ +#ifndef SQLITE_LOCKFILEEX_FLAGS +# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY) +#endif + /* ** Acquire a reader lock. ** Different API routines are called depending on whether or not this @@ -1965,19 +2032,16 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ static int getReadLock(winFile *pFile){ int res; if( isNT() ){ - OVERLAPPED ovlp; - ovlp.Offset = SHARED_FIRST; - ovlp.OffsetHigh = 0; - ovlp.hEvent = 0; - res = osLockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, - 0, SHARED_SIZE, 0, &ovlp); + res = winLockFile(pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0, + SHARED_SIZE, 0); } #ifdef SQLITE_WIN32_HAS_ANSI else{ int lk; sqlite3_randomness(sizeof(lk), &lk); pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); - res = osLockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); + res = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS, + SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); } #endif if( res == 0 ){ @@ -1994,11 +2058,11 @@ static int unlockReadLock(winFile *pFile){ int res; DWORD lastErrno; if( isNT() ){ - res = osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + res = winUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); } #ifdef SQLITE_WIN32_HAS_ANSI else{ - res = osUnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); + res = winUnlockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); } #endif if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ @@ -2071,7 +2135,8 @@ static int winLock(sqlite3_file *id, int locktype){ && (pFile->locktype==RESERVED_LOCK)) ){ int cnt = 3; - while( cnt-->0 && (res = osLockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ + while( cnt-->0 && (res = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS, + PENDING_BYTE, 0, 1, 0))==0 ){ /* Try 3 times to get the pending lock. This is needed to work ** around problems caused by indexing and/or anti-virus software on ** Windows systems. @@ -2103,7 +2168,7 @@ static int winLock(sqlite3_file *id, int locktype){ */ if( locktype==RESERVED_LOCK && res ){ assert( pFile->locktype==SHARED_LOCK ); - res = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + res = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); if( res ){ newLocktype = RESERVED_LOCK; }else{ @@ -2124,7 +2189,8 @@ static int winLock(sqlite3_file *id, int locktype){ assert( pFile->locktype>=SHARED_LOCK ); res = unlockReadLock(pFile); OSTRACE(("unreadlock = %d\n", res)); - res = osLockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + res = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, + SHARED_SIZE, 0); if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ @@ -2138,7 +2204,7 @@ static int winLock(sqlite3_file *id, int locktype){ ** release it now. */ if( gotPendingLock && locktype==SHARED_LOCK ){ - osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); + winUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } /* Update the state of the lock has held in the file descriptor then @@ -2172,9 +2238,9 @@ static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ rc = 1; OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); }else{ - rc = osLockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + rc = winLockFile(pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0); if( rc ){ - osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + winUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); } rc = !rc; OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); @@ -2204,7 +2270,7 @@ static int winUnlock(sqlite3_file *id, int locktype){ pFile->locktype, pFile->sharedLockByte)); type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ - osUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); + winUnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ @@ -2213,13 +2279,13 @@ static int winUnlock(sqlite3_file *id, int locktype){ } } if( type>=RESERVED_LOCK ){ - osUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); + winUnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); } if( locktype==NO_LOCK && type>=SHARED_LOCK ){ unlockReadLock(pFile); } if( type>=PENDING_LOCK ){ - osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); + winUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } pFile->locktype = (u8)locktype; return rc; @@ -2457,25 +2523,19 @@ static int winShmSystemLock( int ofst, /* Offset to first byte to be locked/unlocked */ int nByte /* Number of bytes to lock or unlock */ ){ - OVERLAPPED ovlp; - DWORD dwFlags; int rc = 0; /* Result code form Lock/UnlockFileEx() */ /* Access to the winShmNode object is serialized by the caller */ assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); - /* Initialize the locking parameters */ - dwFlags = LOCKFILE_FAIL_IMMEDIATELY; - if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; - - memset(&ovlp, 0, sizeof(OVERLAPPED)); - ovlp.Offset = ofst; - /* Release/Acquire the system-level lock */ if( lockType==_SHM_UNLCK ){ - rc = osUnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp); + rc = winUnlockFile(pFile->hFile.h, ofst, 0, nByte, 0); }else{ - rc = osLockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp); + /* Initialize the locking parameters */ + DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY; + if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; + rc = winLockFile(pFile->hFile.h, dwFlags, ofst, 0, nByte, 0); } if( rc!= 0 ){