aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--manifest14
-rw-r--r--manifest.uuid2
-rw-r--r--src/os_win.c97
-rw-r--r--src/test1.c2
4 files changed, 71 insertions, 44 deletions
diff --git a/manifest b/manifest
index baf0855e2..83b434611 100644
--- 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.
diff --git a/manifest.uuid b/manifest.uuid
index c5800500f..11921b9ac 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-39bebd50b80ceee321b1da837c72a20cdb26f06e4b726f23e3ddac877d9400a7
+35b3e73c5a9efa12f9bb0dad1721fce128cd1e3bcbc87027ee4ea685a12a70d5
diff --git a/src/os_win.c b/src/os_win.c
index 51171e07c..74be36658 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -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;
}
@@ -3070,6 +3083,15 @@ static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){
}
/*
+** 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
*/
static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
@@ -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));
diff --git a/src/test1.c b/src/test1.c
index 4dcba97cd..6a8711677 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -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;