aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordan <Dan Kennedy>2025-01-24 15:49:47 +0000
committerdan <Dan Kennedy>2025-01-24 15:49:47 +0000
commit2539fb2bc57adebef779a13c18f788e14461f7c8 (patch)
treed41f540bd0391f0c407784cf5cca2407821dbe4c
parentff6bff4059235a583bd7b1c1928a956c4ed9b4f6 (diff)
downloadsqlite-2539fb2bc57adebef779a13c18f788e14461f7c8.tar.gz
sqlite-2539fb2bc57adebef779a13c18f788e14461f7c8.zip
Fix a race condition causing SQLite to use a busy-handler for an operation that should not.
FossilOrigin-Name: 6ab9ed8eef77781898375038ab05fc6e5f46b745e4906691393b8b1d90570eb6
-rw-r--r--manifest13
-rw-r--r--manifest.uuid2
-rw-r--r--src/wal.c7
-rw-r--r--test/walsetlk2.test89
4 files changed, 102 insertions, 9 deletions
diff --git a/manifest b/manifest
index 73dfd4e95..124818249 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Have\swindows\sSQLITE_ENABLE_SETLK_TIMEOUT\sbuilds\sblock\sindefinitely\sif\sthe\sbusy-timeout\sis\sset\sto\s0x7FFFFFFF.
-D 2025-01-15T12:45:38.037
+C Fix\sa\srace\scondition\scausing\sSQLite\sto\suse\sa\sbusy-handler\sfor\san\soperation\sthat\sshould\snot.
+D 2025-01-24T15:49:47.933
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@@ -858,7 +858,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8
F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3
F src/vtab.c 316cd48e9320660db3047cd306cd056e4361180cebb4d0f10a39244e10c11422
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c 4e6181d8780ab0af2e1388d0754cbe6f2f04593d2b1ab6c41699a89942fd8997
+F src/wal.c 97c96c4eab27a409d2c710d8977a6b4917aebced14db2d63a451e9ca7b1f69bd
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c 9ad3dea8003a8913da6a4ca8322e2fe30773f46e88a0d4fbf9db13bdb999efa2
@@ -2022,6 +2022,7 @@ F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766
F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68
F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533442b
F test/walsetlk.test 9c5b92f9a20252540fedf9ffa6ee3d1b8af08ea4b80d0144d9b88e6c0c1de80d
+F test/walsetlk2.test f32134c673e207e5af3c888448f925d1f92c250bb367f0e5a76e4bce9d56f0af
F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3
F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23
F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
@@ -2202,8 +2203,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P b400ab4ba99d3ed7e90c93257d729563c630ef451017a702d42f322a4e57b663
-R 5c0bed857a50c43f376c97a6b2ec23d6
+P daefcafe799ad7613cbdff1fb1e9d40659892906875b28fbc112abd7679e48ea
+R a5b314ee32b527d33bb7a6211f7b128a
U dan
-Z 3a0a46e6f7f4d366b981494ea8c1d6b1
+Z 09f6f131877fb88e3c0a6b91e64a67d2
# Remove this line to create a well-formed Fossil manifest.
diff --git a/manifest.uuid b/manifest.uuid
index 16fe6006a..1506819b5 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-daefcafe799ad7613cbdff1fb1e9d40659892906875b28fbc112abd7679e48ea
+6ab9ed8eef77781898375038ab05fc6e5f46b745e4906691393b8b1d90570eb6
diff --git a/src/wal.c b/src/wal.c
index 42ce3cb97..707acfca5 100644
--- a/src/wal.c
+++ b/src/wal.c
@@ -3470,8 +3470,11 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
** read-lock.
*/
void sqlite3WalEndReadTransaction(Wal *pWal){
- sqlite3WalEndWriteTransaction(pWal);
+#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
+ assert( pWal->writeLock==0 || pWal->readLock<0 );
+#endif
if( pWal->readLock>=0 ){
+ sqlite3WalEndWriteTransaction(pWal);
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
pWal->readLock = -1;
}
@@ -3664,7 +3667,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
** read-transaction was even opened, making this call a no-op.
** Return early. */
if( pWal->writeLock ){
- assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
+ assert( !memcmp(&pWal->hdr,(void*)pWal->apWiData[0],sizeof(WalIndexHdr)) );
return SQLITE_OK;
}
#endif
diff --git a/test/walsetlk2.test b/test/walsetlk2.test
new file mode 100644
index 000000000..99366571d
--- /dev/null
+++ b/test/walsetlk2.test
@@ -0,0 +1,89 @@
+# 2025 Jan 24
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# TESTRUNNER: slow
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+source $testdir/lock_common.tcl
+set testprefix walsetlk2
+
+ifcapable !wal {finish_test ; return }
+ifcapable !setlk_timeout {finish_test ; return }
+
+#-------------------------------------------------------------------------
+# Check that xShmLock calls are as expected for write transactions in
+# setlk mode.
+#
+reset_db
+
+do_execsql_test 1.0 {
+ PRAGMA journal_mode = wal;
+ CREATE TABLE t1(a, b, c);
+ INSERT INTO t1 VALUES(1, 2, 3);
+} {wal}
+db close
+
+testvfs tvfs
+tvfs script xShmLock_callback
+tvfs filter xShmLock
+
+set ::xshmlock [list]
+proc xShmLock_callback {method path name detail} {
+ lappend ::xshmlock $detail
+}
+
+sqlite3 db test.db -vfs tvfs
+db timeout 1000
+
+do_execsql_test 1.1 {
+ SELECT * FROM t1
+} {1 2 3}
+
+do_execsql_test 1.2 {
+ INSERT INTO t1 VALUES(4, 5, 6);
+}
+
+set ::xshmlock [list]
+do_execsql_test 1.3 {
+ INSERT INTO t1 VALUES(7, 8, 9);
+}
+
+do_test 1.4 {
+ set ::xshmlock
+} [list \
+ {0 1 lock exclusive} \
+ {4 1 lock exclusive} {4 1 unlock exclusive} \
+ {4 1 lock shared} \
+ {0 1 unlock exclusive} \
+ {4 1 unlock shared}
+]
+
+do_execsql_test 1.5.1 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8 9}
+set ::xshmlock [list]
+do_execsql_test 1.5.2 {
+ INSERT INTO t1 VALUES(10, 11, 12);
+}
+do_test 1.5.3 {
+ set ::xshmlock
+} [list \
+ {0 1 lock exclusive} \
+ {4 1 lock shared} \
+ {0 1 unlock exclusive} \
+ {4 1 unlock shared}
+]
+
+db close
+tvfs delete
+
+finish_test
+