]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Properly wait for asynchronous results for calls to LockFileEx() on FILE_FLAG_OVERLAP...
authordan <Dan Kennedy>
Tue, 24 Dec 2024 14:44:38 +0000 (14:44 +0000)
committerdan <Dan Kennedy>
Tue, 24 Dec 2024 14:44:38 +0000 (14:44 +0000)
FossilOrigin-Name: 35b3e73c5a9efa12f9bb0dad1721fce128cd1e3bcbc87027ee4ea685a12a70d5

manifest
manifest.uuid
src/os_win.c
src/test1.c

index baf0855e2a4658405e3d3c003089f73876433a12..83b434611e176b1ae8743d68b13c82e99b149779 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\srelease\stest\serrors\son\swinrt.
-D 2024-12-16T19:31:30.451
+C Properly\swait\sfor\sasynchronous\sresults\sfor\scalls\sto\sLockFileEx()\son\sFILE_FLAG_OVERLAPPED\sfiles\seven\sif\sLOCKFILE_FAIL_IMMEDIATELY,\swhich\susually\scauses\sLockFileEx()\sto\sreturn\ssynchronously,\sis\sspecified.
+D 2024-12-24T14:44:38.362
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -762,7 +762,7 @@ F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e
 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
 F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
 F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6
-F src/os_win.c 6f6bd231709a1bd46c815a2329da9555094b13508198b857db3464857b00b3f5
+F src/os_win.c 0f25f11cb81ce578a549f6df5240ea275118c536f8fff0d9f8d0e4d24e78f497
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9
 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
@@ -788,7 +788,7 @@ F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 F src/tclsqlite.c 90441d3cc16f966a23499d9096a3d2d971e5e8fddb4d1413b096b79c2b2cff07
 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395
-F src/test1.c 6c48aad3b093af9053d27ff0386c870806b2d170a445c1e569df781c4dc2e847
+F src/test1.c bed72f092f9aaebf50ee4919a02a26ab99a4f378ab334cb93d77e8adb82e4b77
 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b
 F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d
@@ -2202,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 5ca12dc964b2d8c3d11a2be5be7eac0dc994cec3a8b5fdfeac4ff8dde19a5a93
-R 68f20f3dcabf678da64d7efc79e9ed69
+P 39bebd50b80ceee321b1da837c72a20cdb26f06e4b726f23e3ddac877d9400a7
+R 12e3b22a0f00395166a9c60b15213ddc
 U dan
-Z 0a548518470ec9c7acb934179f861770
+Z b09d557521f0d4b60a9610b79c0fe3aa
 # Remove this line to create a well-formed Fossil manifest.
index c5800500ff06c45355ad65cbd311d28aa1305858..11921b9ac4f2260b01a987aaa6670fbca3048703 100644 (file)
@@ -1 +1 @@
-39bebd50b80ceee321b1da837c72a20cdb26f06e4b726f23e3ddac877d9400a7
+35b3e73c5a9efa12f9bb0dad1721fce128cd1e3bcbc87027ee4ea685a12a70d5
index 51171e07cb4fac8ff43e1e3e6a8826b86abf0ba3..74be366588bf08d7045ce0ae08195adcb496d2d7 100644 (file)
@@ -1190,6 +1190,22 @@ static struct win_syscall {
     aSyscall[80].pCurrent \
 )
 
+/*
+** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CancelIo()
+** for the case where a timeout expires and a lock request must be 
+** cancelled.
+**
+** Minimum supported client: Windows XP [desktop apps | UWP apps]
+** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps]
+*/
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+  { "CancelIo",                 (SYSCALL)CancelIo,               0 },
+#else
+  { "CancelIo",                 (SYSCALL)0,                      0 },
+#endif
+
+#define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[81].pCurrent)
+
 }; /* End of the overrideable system calls */
 
 /*
@@ -2598,9 +2614,6 @@ static int winHandleLockTimeout(
   int rc = SQLITE_OK;
   BOOL ret;
 
-#if !defined(SQLITE_ENABLE_SETLK_TIMEOUT)
-  ret = winLockFile(&hFile, flags, offset, 0, nByte, 0);
-#else
   if( !osIsNT() ){
     ret = winLockFile(&hFile, flags, offset, 0, nByte, 0);
   }else{
@@ -2608,39 +2621,40 @@ static int winHandleLockTimeout(
     memset(&ovlp, 0, sizeof(OVERLAPPED));
     ovlp.Offset = offset;
 
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
     if( nMs>0 ){
-      ovlp.hEvent = osCreateEvent(NULL, TRUE, FALSE, NULL);
-      if( ovlp.hEvent==NULL ){
-        return SQLITE_IOERR;
-      }
       flags &= ~LOCKFILE_FAIL_IMMEDIATELY;
     }
+    ovlp.hEvent = osCreateEvent(NULL, TRUE, FALSE, NULL);
+    if( ovlp.hEvent==NULL ){
+      return SQLITE_IOERR_LOCK;
+    }
+#endif
 
     ret = osLockFileEx(hFile, flags, 0, nByte, 0, &ovlp);
 
-    if( !ret && nMs>0 && GetLastError()==ERROR_IO_PENDING ){
-      DWORD res = osWaitForSingleObject(ovlp.hEvent, (DWORD)nMs);
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+    /* If SQLITE_ENABLE_SETLK_TIMEOUT is defined, then the file-handle was
+    ** opened with FILE_FLAG_OVERHEAD specified. In this case, the call to
+    ** LockFileEx() may fail because the request is still pending. This can
+    ** happen even if LOCKFILE_FAIL_IMMEDIATELY was specified.  */
+    if( !ret && GetLastError()==ERROR_IO_PENDING ){
+      DWORD nDelay = (nMs ? nMs : INFINITE);
+      DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay);
       if( res==WAIT_OBJECT_0 ){
-        /* Successfully obtained the lock. */
         ret = TRUE;
+      }else if( res==WAIT_TIMEOUT ){
+        rc = SQLITE_BUSY_TIMEOUT;
       }else{
-        if( res==WAIT_TIMEOUT ){
-          rc = SQLITE_BUSY_TIMEOUT;
-        }else{
-          /* Some other error has occurred */
-          rc = SQLITE_IOERR;
-        }
-        
-        /* Cancel the LockFileEx() if it is still pending. */
-        CancelIo(hFile);
+        /* Some other error has occurred */
+        rc = SQLITE_IOERR_LOCK;
       }
+      osCancelIo(hFile);
     }
 
-    if( nMs>0 ){
-      osCloseHandle(ovlp.hEvent);
-    }
+    osCloseHandle(ovlp.hEvent);
+#endif
   }
-#endif  /* defined(SQLITE_ENABLE_SETLK_TIMEOUT) */
 
   if( rc==SQLITE_OK && !ret ){
     rc = SQLITE_BUSY;
@@ -3056,11 +3070,10 @@ static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){
 #else
   DWORD upperBits = 0;
   DWORD lowerBits = 0;
-  DWORD lastErrno = 0;
 
+  assert( pnByte );
   lowerBits = osGetFileSize(h, &upperBits);
   *pnByte = (((sqlite3_int64)upperBits)<<32) + lowerBits;
-
   if( lowerBits==INVALID_FILE_SIZE && osGetLastError()!=NO_ERROR ){
     rc = SQLITE_IOERR_FSTAT;
   }
@@ -3069,6 +3082,15 @@ static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){
   return rc;
 }
 
+/*
+** Close the handle passed as the only argument.
+*/
+static void winHandleClose(HANDLE h){
+  if( h!=INVALID_HANDLE_VALUE ){
+    osCloseHandle(h);
+  }
+}
+
 /*
 ** Truncate an open file to a specified size
 */
@@ -3999,9 +4021,7 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
                  osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
         UNUSED_VARIABLE_VALUE(bRc);
       }
-      if( p->hSharedShm!=NULL && p->hSharedShm!=INVALID_HANDLE_VALUE ){
-        osCloseHandle(p->hSharedShm);
-      }
+      winHandleClose(p->hSharedShm);
       if( deleteFlag ){
         SimulateIOErrorBenign(1);
         sqlite3BeginBenignMalloc();
@@ -4079,6 +4099,9 @@ static void *winConvertFromUtf8Filename(const char *zFilename){
 
 /*
 ** This function is used to open a handle on a *-shm file.
+**
+** If SQLITE_ENABLE_SETLK_TIMEOUT is defined at build time, then the file
+** is opened with FILE_FLAG_OVERLAPPED specified. If not, it is not.
 */
 static int winHandleOpen(
   const char *zUtf8,              /* File to open */
@@ -4090,6 +4113,12 @@ static int winHandleOpen(
   int bReadonly = *pbReadonly;
   HANDLE h = INVALID_HANDLE_VALUE;
 
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+  const DWORD flag_overlapped = FILE_FLAG_OVERLAPPED;
+#else
+  const DWORD flag_overlapped = 0;
+#endif
+
   /* Convert the filename to the system encoding. */
   zConverted = winConvertFromUtf8Filename(zUtf8);
   if( zConverted==0 ){
@@ -4114,7 +4143,7 @@ static int winHandleOpen(
     memset(&extendedParameters, 0, sizeof(extendedParameters));
     extendedParameters.dwSize = sizeof(extendedParameters);
     extendedParameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
-    extendedParameters.dwFileFlags = FILE_FLAG_OVERLAPPED;
+    extendedParameters.dwFileFlags = flag_overlapped;
     extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
     h = osCreateFile2((LPCWSTR)zConverted,
         (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)),/* dwDesiredAccess */
@@ -4128,7 +4157,7 @@ static int winHandleOpen(
         FILE_SHARE_READ | FILE_SHARE_WRITE,        /* dwShareMode */
         NULL,                                      /* lpSecurityAttributes */
         OPEN_ALWAYS,                               /* dwCreationDisposition */
-        FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
+        FILE_ATTRIBUTE_NORMAL|flag_overlapped,
         NULL
     );
 #endif
@@ -4141,7 +4170,7 @@ static int winHandleOpen(
         FILE_SHARE_READ | FILE_SHARE_WRITE,        /* dwShareMode */
         NULL,                                      /* lpSecurityAttributes */
         OPEN_ALWAYS,                               /* dwCreationDisposition */
-        FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
+        FILE_ATTRIBUTE_NORMAL|flag_overlapped,
         NULL
     );
 #endif
@@ -4249,9 +4278,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
 #endif
     pDbFd->pShm = p;
   }else if( p ){
-    if( p->hShm!=INVALID_HANDLE_VALUE ){
-      osCloseHandle(p->hShm);
-    }
+    winHandleClose(p->hShm);
     sqlite3_free(p);
   }
 
@@ -6371,7 +6398,7 @@ int sqlite3_os_init(void){
 
   /* Double-check that the aSyscall[] array has been constructed
   ** correctly.  See ticket [bb3a86e890c8e96ab] */
-  assert( ArraySize(aSyscall)==81 );
+  assert( ArraySize(aSyscall)==82 );
 
   /* get memory map allocation granularity */
   memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
index 4dcba97cdd22e00468327dcf8e608ce65bc7216e..6a871167760ef9207a3b91d9342ab4a9aeab3f0f 100644 (file)
@@ -7985,7 +7985,7 @@ static int SQLITE_TCLAPI win32_file_lock(
 ){
   static struct win32FileLocker x = { "win32_file_lock", 0, 0, 0, 0, 0 };
   const char *zFilename = 0;
-  int nFilename = 0;
+  Tcl_Size nFilename = 0;
   char *zTerm = 0;
   char zBuf[200];
   int retry = 0;