diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/os_unix.c | 3 | ||||
-rw-r--r-- | src/os_win.c | 27 | ||||
-rw-r--r-- | src/sqlite.h.in | 7 | ||||
-rw-r--r-- | src/sqliteInt.h | 2 |
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 */ |