diff options
author | dan <Dan Kennedy> | 2024-10-09 15:40:07 +0000 |
---|---|---|
committer | dan <Dan Kennedy> | 2024-10-09 15:40:07 +0000 |
commit | 48dd75df73c53a28ef4e4a8dfd58787fa9893ac6 (patch) | |
tree | d46d0599aa8e8cd08df0455b617a2f1f3c85ac5b /src/os_unix.c | |
parent | 4b0a2e01068e14b6cd78a582c41d2b203c421d22 (diff) | |
download | sqlite-48dd75df73c53a28ef4e4a8dfd58787fa9893ac6.tar.gz sqlite-48dd75df73c53a28ef4e4a8dfd58787fa9893ac6.zip |
Fix the xCheckReservedLock() method of the flock VFS to avoid dropping the file-lock.
FossilOrigin-Name: 8ffaf85249ff38ceea037a6e96b3484c912f1c1aa55b8642297d592768661344
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 57 |
1 files changed, 16 insertions, 41 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 92ad9d860..2106dee8f 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2464,54 +2464,29 @@ static int robust_flock(int fd, int op){ ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ - int rc = SQLITE_OK; - int reserved = 0; unixFile *pFile = (unixFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); + assert( pFile->eFileLock<=SHARED_LOCK ); - /* Check if a thread in this process holds such a lock */ - if( pFile->eFileLock>SHARED_LOCK ){ - reserved = 1; - } - - /* Otherwise see if some other process holds it. */ - if( !reserved ){ - /* attempt to get the lock */ - int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); - if( !lrc ){ - /* got the lock, unlock it */ - lrc = robust_flock(pFile->h, LOCK_UN); - if ( lrc ) { - int tErrno = errno; - /* unlock failed with an error */ - lrc = SQLITE_IOERR_UNLOCK; - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } else { - int tErrno = errno; - reserved = 1; - /* someone else might have it reserved */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); - if( IS_LOCK_ERROR(lrc) ){ - storeLastErrno(pFile, tErrno); - rc = lrc; - } - } - } - OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); + /* The flock VFS only ever takes exclusive locks (see function flockLock). + ** Therefore, if this connection is holding any lock at all, no other + ** connection may be holding a RESERVED lock. So set *pResOut to 0 + ** in this case. + ** + ** Or, this connection may be holding no lock. In that case, set *pResOut to + ** 0 as well. The caller will then attempt to take an EXCLUSIVE lock on the + ** db in order to roll the hot journal back. If there is another connection + ** holding a lock, that attempt will fail and an SQLITE_BUSY returned to + ** the user. With other VFS, we try to avoid this, in order to allow a reader + ** to proceed while a writer is preparing its transaction. But that won't + ** work with the flock VFS - as it always takes EXCLUSIVE locks - so it is + ** not a problem in this case. */ + *pResOut = 0; -#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & 0xff) == SQLITE_IOERR ){ - rc = SQLITE_OK; - reserved=1; - } -#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ - *pResOut = reserved; - return rc; + return SQLITE_OK; } /* |