]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a race condition causing SQLite to use a busy-handler for an operation that shoul...
authordan <Dan Kennedy>
Fri, 24 Jan 2025 15:49:47 +0000 (15:49 +0000)
committerdan <Dan Kennedy>
Fri, 24 Jan 2025 15:49:47 +0000 (15:49 +0000)
FossilOrigin-Name: 6ab9ed8eef77781898375038ab05fc6e5f46b745e4906691393b8b1d90570eb6

manifest
manifest.uuid
src/wal.c
test/walsetlk2.test [new file with mode: 0644]

index 73dfd4e95988fb321f09841263c763614726df5c..12481824903c0b737af23efed087dd7ba1ed20aa 100644 (file)
--- 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.
index 16fe6006a79211eb228cd4f0dae22a5e44115e5c..1506819b57d7a08ecbdca89e574d6a443c32dab2 100644 (file)
@@ -1 +1 @@
-daefcafe799ad7613cbdff1fb1e9d40659892906875b28fbc112abd7679e48ea
+6ab9ed8eef77781898375038ab05fc6e5f46b745e4906691393b8b1d90570eb6
index 42ce3cb97bc55d945b24b4d9af8112fb2d830ef7..707acfca5a1f1a328a93549fda4c60e094eaa32d 100644 (file)
--- 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 (file)
index 0000000..9936657
--- /dev/null
@@ -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
+