1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Fix a problem causing the write-lock to be held when it should not be in some circumstances following a SEH exception.

FossilOrigin-Name: 7eb5accb7cf937fc967dcd86da0af813fb18a2697348bd231fbefd3c09b930ab
This commit is contained in:
dan
2025-01-30 17:04:28 +00:00
parent 462888819e
commit df54ecb1bf
4 changed files with 26 additions and 10 deletions

View File

@@ -502,6 +502,11 @@ struct WalCkptInfo {
/*
** An open write-ahead log file is represented by an instance of the
** following object.
**
** writeLock:
** This is usually set to 1 whenever the WRITER lock is held. However,
** if it is set to 2, then the WRITER lock is held but must be released
** by walHandleException() if a SEH exception is thrown.
*/
struct Wal {
sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */
@@ -2413,7 +2418,9 @@ static int walHandleException(Wal *pWal){
static const int S = 1;
static const int E = (1<<SQLITE_SHM_NLOCK);
int ii;
u32 mUnlock = pWal->lockMask & ~(
u32 mUnlock;
if( pWal->writeLock==2 ) pWal->writeLock = 0;
mUnlock = pWal->lockMask & ~(
(pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock)))
| (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0)
| (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0)
@@ -2685,7 +2692,12 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
if( bWriteLock
|| SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1))
){
pWal->writeLock = 1;
/* If the write-lock was just obtained, set writeLock to 2 instead of
** the usual 1. This causes walIndexPage() to behave as if the
** write-lock were held (so that it allocates new pages as required),
** and walHandleException() to unlock the write-lock if a SEH exception
** is thrown. */
if( !bWriteLock ) pWal->writeLock = 2;
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
badHdr = walIndexTryHdr(pWal, pChanged);
if( badHdr ){