]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Revise and vastly simplify the Win32 SHM file locking semantics, allowing all new...
authormistachkin <mistachkin@noemail.net>
Thu, 9 Nov 2017 22:23:50 +0000 (22:23 +0000)
committermistachkin <mistachkin@noemail.net>
Thu, 9 Nov 2017 22:23:50 +0000 (22:23 +0000)
FossilOrigin-Name: d0997b0f5bc9a9869684e39a17a01c430d6383c8b31d6c00ea17a5eac15bc6f0

manifest
manifest.uuid
src/os_win.c

index 68233db6691bb101a52e1cfe91dcbbb4c4b0b5ed..bf3dc40e6bb349b6b3bb06ab5ee7312fad6a4334 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\san\sassert()\sin\sthe\sWin32\sVFS.
-D 2017-11-09T20:37:37.876
+C Revise\sand\svastly\ssimplify\sthe\sWin32\sSHM\sfile\slocking\ssemantics,\sallowing\sall\snew\stests\sto\spass.
+D 2017-11-09T22:23:50.758
 F Makefile.in 5bae3f2f3d42f2ad52b141562d74872c97ac0fca6c54953c91bb150a0e6427a8
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 3a5cb477ec3ce5274663b693164e349db63348667cd45bad78cc13d580b691e2
@@ -448,7 +448,7 @@ F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
 F src/os_unix.c e87cef0bb894b94d96ee3af210be669549d111c580817d14818101b992640767
-F src/os_win.c 64bc61821f75b37ca213da93aef84557c8730be6e0ca93943223b5e57fe6e5a3
+F src/os_win.c b40d4f98562048b1d084b71bb08367903b937424427ee7b866902dca7b79cb88
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c 07cf850241667874fcce9d7d924c814305e499b26c804322e2261247b5921903
 F src/pager.h 581698f2177e8bd4008fe4760898ce20b6133d1df22139b9101b5155f900df7a
@@ -1669,7 +1669,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ff630b66714b20c09888ead0a45f344d63e0d9a5208867d6266e74f79187076c
-R 9f94324b020c3efbc23aa89a0c6b1ac2
+P 22e58330461736ca22d6f4d7eab897a3597de2e7434a6f4a474f0f0d7f964281
+R 0c5d22f8af57ea73c927075712f52c29
 U mistachkin
-Z b9496fb62e9a99521b89e7f9003a99d8
+Z e19a1ec884226a6dec0cb1fab52ceb52
index da346528d8d7cd9561a035db30ad00d3d92863b4..2503e60869fa1da8214862b2433a22065dccd239 100644 (file)
@@ -1 +1 @@
-22e58330461736ca22d6f4d7eab897a3597de2e7434a6f4a474f0f0d7f964281
\ No newline at end of file
+d0997b0f5bc9a9869684e39a17a01c430d6383c8b31d6c00ea17a5eac15bc6f0
\ No newline at end of file
index aff48e25e942f4d6f0ee2766063436369c1be762..975df6154bc6b9a8d597a5b3ebe76815cb8fb5bb 100644 (file)
@@ -2098,27 +2098,6 @@ static int winLogErrorAtLine(
 static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
 static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
 
-/*
-** The "winIsLockConflict" macro is used to determine if a particular I/O
-** error code is due to a file locking conflict.  It must accept the error
-** code DWORD as its only argument.
-*/
-#if !defined(winIsLockConflict)
-#define winIsLockConflict(a) (((a)==NO_ERROR)                   || \
-                              ((a)==ERROR_LOCK_VIOLATION)       || \
-                              ((a)==ERROR_IO_PENDING))
-#endif
-
-/*
-** The "winIsLockMissing" macro is used to determine if a particular I/O
-** error code is due to being unable to obtain a file lock because all or
-** part of the range requested within the file is missing.  It must accept
-** the error code DWORD as its only argument.
-*/
-#if !defined(winIsLockMissing)
-#define winIsLockMissing(a) (((a)==ERROR_HANDLE_EOF))
-#endif
-
 /*
 ** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
 ** error code obtained via GetLastError() is eligible to be retried.  It
@@ -3844,65 +3823,6 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
   }
 }
 
-/*
-** Query the status of the DMS lock for the specified file.  Returns
-** SQLITE_OK upon success.  Upon success, the integer pointed to by
-** the pLockType argument will be set to the lock type held by the
-** other process, as follows:
-**
-**       WINSHM_UNLCK -- No locks are held on the DMS.
-**       WINSHM_RDLCK -- A SHARED lock is held on the DMS.
-**       WINSHM_WRLCK -- An EXCLUSIVE lock is held on the DMS.
-*/
-static int winGetShmDmsLockType(
-  winFile *pFile, /* File handle object */
-  int bReadOnly,  /* Non-zero if the SHM was opened read-only */
-  int *pLockType  /* WINSHM_UNLCK, WINSHM_RDLCK, or WINSHM_WRLCK */
-){
-#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
-  OVERLAPPED overlapped; /* The offset for ReadFile/WriteFile. */
-#endif
-  LPVOID pOverlapped = 0;
-  sqlite3_int64 offset = WIN_SHM_DMS;
-  BYTE notUsed1 = 0;
-  DWORD notUsed2 = 0;
-
-#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
-  if( winSeekFile(pFile, offset) ){
-    return SQLITE_IOERR_SEEK;
-  }
-#else
-  memset(&overlapped, 0, sizeof(OVERLAPPED));
-  overlapped.Offset = (LONG)(offset & 0xffffffff);
-  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
-  pOverlapped = &overlapped;
-#endif
-  if( bReadOnly ||
-      !osWriteFile(pFile->h, &notUsed1, 1, &notUsed2, pOverlapped) ){
-    DWORD lastErrno = bReadOnly ? NO_ERROR : osGetLastError();
-    if( !osReadFile(pFile->h, &notUsed1, 1, &notUsed2, pOverlapped) ){
-      lastErrno = osGetLastError();
-      if( winIsLockConflict(lastErrno) ){
-        if( pLockType ) *pLockType = WINSHM_WRLCK;
-      }else if( winIsLockMissing(lastErrno) ){
-        assert( bReadOnly );
-        if( pLockType ) *pLockType = WINSHM_UNLCK;
-      }else{
-        return SQLITE_IOERR_READ;
-      }
-    }else{
-      if( winIsLockConflict(lastErrno) ){
-        if( pLockType ) *pLockType = WINSHM_RDLCK;
-      }else{
-        return SQLITE_IOERR_WRITE;
-      }
-    }
-  }else{
-    if( pLockType ) *pLockType = WINSHM_UNLCK;
-  }
-  return SQLITE_OK;
-}
-
 /*
 ** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
 ** take it now. Return SQLITE_OK if successful, or an SQLite error
@@ -3913,53 +3833,21 @@ static int winGetShmDmsLockType(
 ** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
 */
 static int winLockSharedMemory(winShmNode *pShmNode){
-  int lockType;
-  int rc = SQLITE_OK;
-
-  /* Use ReadFile/WriteFile to determine the locks other processes are
-  ** holding on the DMS byte. If it indicates that another process is
-  ** holding a SHARED lock, then this process may also take a SHARED
-  ** lock and proceed with opening the *-shm file.
-  **
-  ** Or, if no other process is holding any lock, then this process
-  ** is the first to open it. In this case take an EXCLUSIVE lock on the
-  ** DMS byte and truncate the *-shm file to zero bytes in size. Then
-  ** downgrade to a SHARED lock on the DMS byte.
-  **
-  ** If another process is holding an EXCLUSIVE lock on the DMS byte,
-  ** return SQLITE_BUSY to the caller (it will try again). An earlier
-  ** version of this code attempted the SHARED lock at this point. But
-  ** this introduced a subtle race condition: if the process holding
-  ** EXCLUSIVE failed just before truncating the *-shm file, then this
-  ** process might open and use the *-shm file without truncating it.
-  ** And if the *-shm file has been corrupted by a power failure or
-  ** system crash, the database itself may also become corrupt.  */
-  if( winGetShmDmsLockType(&pShmNode->hFile, pShmNode->isReadonly,
-                           &lockType)!=SQLITE_OK ){
-    rc = SQLITE_IOERR_LOCK;
-  }else if( lockType==WINSHM_UNLCK ){
+  int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1);
+  if( rc==SQLITE_OK ){
     if( pShmNode->isReadonly ){
       pShmNode->isUnlocked = 1;
-      rc = SQLITE_READONLY_CANTINIT;
-    }else{
       winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
-      rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1);
-      if( rc==SQLITE_OK && winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){
-        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
+      return SQLITE_READONLY_CANTINIT;
+    }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){
+      winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+      return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
                          "winLockSharedMemory", pShmNode->zFilename);
-      }
     }
-  }else if( lockType==WINSHM_WRLCK ){
-    rc = SQLITE_BUSY;
-  }
-
-  if( rc==SQLITE_OK ){
-    assert( lockType==WINSHM_UNLCK || lockType==WINSHM_RDLCK );
-    winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
-    rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
   }
 
-  return rc;
+  winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+  return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
 }
 
 /*