aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <Dan Kennedy>2025-01-30 17:04:28 +0000
committerdan <Dan Kennedy>2025-01-30 17:04:28 +0000
commitdf54ecb1bfaf1d6e514b534a9c647ffc72571684 (patch)
tree8bbaabcbdbc366e607a425bb314fc280a0cb3287 /src
parent462888819e3582e30c8a513285bd4d524a64f66e (diff)
downloadsqlite-df54ecb1bfaf1d6e514b534a9c647ffc72571684.tar.gz
sqlite-df54ecb1bfaf1d6e514b534a9c647ffc72571684.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/wal.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/wal.c b/src/wal.c
index 5d6c0c62c..759ad8e10 100644
--- a/src/wal.c
+++ b/src/wal.c
@@ -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 ){