aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c6
-rw-r--r--src/os_unix.c3
-rw-r--r--src/os_win.c27
-rw-r--r--src/sqlite.h.in7
-rw-r--r--src/sqliteInt.h2
5 files changed, 30 insertions, 15 deletions
diff --git a/src/main.c b/src/main.c
index c8344b43c..c1799455f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1827,12 +1827,16 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
return SQLITE_OK;
}
+/*
+** Set the setlk timeout value.
+*/
int sqlite3_setlk_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
+ if( ms<-1 ) return SQLITE_RANGE;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- db->setlkTimeout = (ms>0 ? ms : 0);
+ db->setlkTimeout = ms;
#endif
return SQLITE_OK;
}
diff --git a/src/os_unix.c b/src/os_unix.c
index b1996278c..58e495210 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4038,8 +4038,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
case SQLITE_FCNTL_LOCK_TIMEOUT: {
int iOld = pFile->iBusyTimeout;
+ int iNew = *(int*)pArg;
#if SQLITE_ENABLE_SETLK_TIMEOUT==1
- pFile->iBusyTimeout = *(int*)pArg;
+ pFile->iBusyTimeout = iNew<0 ? 0x7FFFFFFF : (unsigned)iNew;
#elif SQLITE_ENABLE_SETLK_TIMEOUT==2
pFile->iBusyTimeout = !!(*(int*)pArg);
#else
diff --git a/src/os_win.c b/src/os_win.c
index 556b075f4..751ba2148 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -288,7 +288,7 @@ struct winFile {
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
#endif
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- unsigned iBusyTimeout; /* Wait this many millisec on locks */
+ DWORD iBusyTimeout; /* Wait this many millisec on locks */
#endif
};
@@ -2608,7 +2608,7 @@ static int winHandleLockTimeout(
DWORD offset,
DWORD nByte,
int bExcl,
- int nMs
+ DWORD nMs
){
DWORD flags = LOCKFILE_FAIL_IMMEDIATELY | (bExcl?LOCKFILE_EXCLUSIVE_LOCK:0);
int rc = SQLITE_OK;
@@ -2622,7 +2622,7 @@ static int winHandleLockTimeout(
ovlp.Offset = offset;
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- if( nMs>0 ){
+ if( nMs!=0 ){
flags &= ~LOCKFILE_FAIL_IMMEDIATELY;
}
ovlp.hEvent = osCreateEvent(NULL, TRUE, FALSE, NULL);
@@ -2637,9 +2637,17 @@ static int winHandleLockTimeout(
/* 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. */
+ ** happen even if LOCKFILE_FAIL_IMMEDIATELY was specified.
+ **
+ ** If nMs is 0, then LOCKFILE_FAIL_IMMEDIATELY was set in the flags
+ ** passed to LockFileEx(). In this case, if the operation is pending,
+ ** block indefinitely until it is finished.
+ **
+ ** Otherwise, wait for up to nMs ms for the operation to finish. nMs
+ ** may be set to INFINITE.
+ */
if( !ret && GetLastError()==ERROR_IO_PENDING ){
- DWORD nDelay = (nMs==0 || nMs==0x7FFFFFFF ? INFINITE : nMs);
+ DWORD nDelay = (nMs==0 ? INFINITE : nMs);
DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay);
if( res==WAIT_OBJECT_0 ){
ret = TRUE;
@@ -3834,10 +3842,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
case SQLITE_FCNTL_LOCK_TIMEOUT: {
int iOld = pFile->iBusyTimeout;
+ int iNew = *(int*)pArg;
#if SQLITE_ENABLE_SETLK_TIMEOUT==1
- pFile->iBusyTimeout = *(int*)pArg;
+ pFile->iBusyTimeout = (iNew < 0) ? INFINITE : (DWORD)iNew;
#elif SQLITE_ENABLE_SETLK_TIMEOUT==2
- pFile->iBusyTimeout = !!(*(int*)pArg);
+ pFile->iBusyTimeout = (DWORD)(!!iNew);
#else
# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2"
#endif
@@ -4043,7 +4052,7 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
** pShmNode. Take the lock. Truncate the *-shm file if required.
** Return SQLITE_OK if successful, or an SQLite error code otherwise.
*/
-static int winLockSharedMemory(winShmNode *pShmNode, int nMs){
+static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){
HANDLE h = pShmNode->hSharedShm;
int rc = SQLITE_OK;
@@ -4407,7 +4416,7 @@ static int winShmLock(
}
}else{
int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0);
- int nMs = winFileBusyTimeout(pDbFd);
+ DWORD nMs = winFileBusyTimeout(pDbFd);
rc = winHandleLockTimeout(p->hShm, ofst+WIN_SHM_BASE, n, bExcl, nMs);
if( rc==SQLITE_OK ){
if( bExcl ){
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index c2a69bd2f..68474ab71 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -2909,9 +2909,10 @@ int sqlite3_busy_timeout(sqlite3*, int ms);
** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does
** not support blocking locks, this function is a no-op.
**
-** Passing 0x7FFFFFFF to this function is interpreted by some VFS as "block
-** indefinitely". Passing zero or less than zero disables blocking locks
-** altogether.
+** Passing 0 to this function disables blocking locks altogether. Passing
+** -1 to this function requests that the VFS blocks for a long time -
+** indefinitely if possible. The results of passing any other negative value
+** are undefined.
**
** Internally, each SQLite database handle store two timeout values - the
** busy-timeout (used for rollback mode databases, or if the VFS does not
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index aa12b8976..631bb2a24 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1745,7 +1745,7 @@ struct sqlite3 {
int nAnalysisLimit; /* Number of index rows to ANALYZE */
int busyTimeout; /* Busy handler timeout, in msec */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
- int setlkTimeout; /* Blocking lock timeout, in msec */
+ int setlkTimeout; /* Blocking lock timeout, in msec. -1 -> inf. */
#endif
int nSavepoint; /* Number of non-transaction savepoints */
int nStatement; /* Number of nested statement-transactions */