]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Have os_unix.c reuse cached file-descriptors in the case when a read-write fd is...
authordan <Dan Kennedy>
Thu, 21 Mar 2024 11:37:36 +0000 (11:37 +0000)
committerdan <Dan Kennedy>
Thu, 21 Mar 2024 11:37:36 +0000 (11:37 +0000)
FossilOrigin-Name: a678e85402af08c1e387bf30ff2205f84dd7da749755da565d70f831c007a3d9

manifest
manifest.uuid
src/os_unix.c
test/readonly.test [new file with mode: 0644]

index 0e4698a26a34b06e708d203d9f8479ed26f858fd..d352d9cc2b3e373aada3013ae836572e8a775f84 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sall\stest\scases\sso\sthat\sthey\swork\swith\sSQLITE_ALLOW_ROWID_IN_VIEW.
-D 2024-03-21T10:35:33.254
+C Have\sos_unix.c\sreuse\scached\sfile-descriptors\sin\sthe\scase\swhen\sa\sread-write\sfd\sis\srequested\son\sa\sread-only\sfile\sand\sa\sread-only\sfd\sreturned.
+D 2024-03-21T11:37:36.346
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -734,7 +734,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
 F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
-F src/os_unix.c 8d7533b3b4d0d2d6ddd34d1ebc92f50a91f04e722a3a9295a000bc3c25128e2f
+F src/os_unix.c 6227cbc4ac93046f121436886cf3712da6f4e2082af6314f976eeae1d86b794a
 F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
 F src/pager.c ff60e98138d2499082ac6230f01ac508aba545315debccfca2fd6042f5f10fcd
@@ -1522,6 +1522,7 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
 F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
+F test/readonly.test bdf5a451f415bc3153764122d034f553797c27194ffbd1e9763ecd9500af41d2
 F test/recover.test 6463509a7404e0c35431dd9b4a1c3b4a29d7a6af8a08462b31670c8a5a616d3a
 F test/regexp1.test 8f2a8bc1569666e29a4cee6c1a666cd224eb6d50e2470d1dc1df995170f3e0f1
 F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5
@@ -2181,8 +2182,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 7e13a2c7583dbcb660adde6b0465da037365971c56726b8f18a541d8803ffeed
-R 2027b60f20ab6be3fc26d73a48e5361c
-U drh
-Z 4767141a590293471cedda2bdaf01e5d
+P 66c69e2f20f7692e0f34743ae97b09c4d8d11b874cdc5381795f2d1e0410f724
+R 41345a246cf3c264839b8ebe82b82196
+U dan
+Z d2317639297bfb820720d835feec7e58
 # Remove this line to create a well-formed Fossil manifest.
index 423f236b4500932757922a4e0eefb7fd846f5d36..ac95fcbf05e66064fd87921d316ee100b0c6455e 100644 (file)
@@ -1 +1 @@
-66c69e2f20f7692e0f34743ae97b09c4d8d11b874cdc5381795f2d1e0410f724
\ No newline at end of file
+a678e85402af08c1e387bf30ff2205f84dd7da749755da565d70f831c007a3d9
\ No newline at end of file
index 4663c22d94ea4803212904b67a99a1897c5c6ec1..9e7ba05d6882b1f3c310b99102e8ecbf7f830af2 100644 (file)
@@ -6398,12 +6398,19 @@ static int unixOpen(
         rc = SQLITE_READONLY_DIRECTORY;
       }else if( errno!=EISDIR && isReadWrite ){
         /* Failed to open the file for read/write access. Try read-only. */
+        UnixUnusedFd *pReadonly = 0;
         flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
         openFlags &= ~(O_RDWR|O_CREAT);
         flags |= SQLITE_OPEN_READONLY;
         openFlags |= O_RDONLY;
         isReadonly = 1;
-        fd = robust_open(zName, openFlags, openMode);
+        pReadonly = findReusableFd(zName, flags);
+        if( pReadonly ){
+          fd = pReadonly->fd;
+          sqlite3_free(pReadonly);
+        }else{
+          fd = robust_open(zName, openFlags, openMode);
+        }
       }
     }
     if( fd<0 ){
diff --git a/test/readonly.test b/test/readonly.test
new file mode 100644 (file)
index 0000000..811d54f
--- /dev/null
@@ -0,0 +1,54 @@
+# 2024 March 21
+#
+# 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.
+#
+#***********************************************************************
+#
+# This file contains tests for using databases in read-only mode on
+# unix.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+source $testdir/lock_common.tcl
+source $testdir/wal_common.tcl
+set ::testprefix readonly
+
+do_execsql_test 1.0 {
+  CREATE TABLE t1(a, b);
+  INSERT INTO t1 VALUES(1, 2), (3, 4), (5, 6);
+}
+
+db close
+file attributes test.db -permissions r--r--r--
+
+sqlite3 db test.db
+
+do_catchsql_test 1.1 {
+  INSERT INTO t1 VALUES(7, 8);
+} {1 {attempt to write a readonly database}}
+
+do_execsql_test 1.2 {
+  BEGIN;
+    SELECT * FROM t1;
+} {1 2 3 4 5 6}
+
+# The following attempts to open a read/write fd on the database 20,000 
+# times. And each time instead opens a read-only fd. At one point this
+# was failing to reuse cached fds, causing a "too many open file-descriptors"
+# error.
+do_test 1.3 {
+  for {set ii 0} {$ii < 20000} {incr ii} {
+    sqlite3 db2 test.db
+    db2 close
+  }
+  set {} {} 
+} {}
+
+
+finish_test