Merge "Use a RwLock for DB_PATH"
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 7c0d4c7..0cc3aa9 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -851,9 +851,6 @@
 
         let conn = Self::make_connection(&persistent_path_str)?;
 
-        // On busy fail Immediately. It is unlikely to succeed given a bug in sqlite.
-        conn.busy_handler(None).context("In KeystoreDB::new: Failed to set busy handler.")?;
-
         let mut db = Self { conn, gc, perboot: perboot::PERBOOT_DB.clone() };
         db.with_transaction(TransactionBehavior::Immediate, |tx| {
             Self::init_tables(tx).context("Trying to initialize tables.").no_gc()
@@ -987,6 +984,12 @@
                     return Err(e);
                 }
             }
+            let result: String = conn
+                .pragma_update_and_check(None, "journal_mode", &"WAL", |row| row.get(0))
+                .expect("Attempting to set journal mode failed.");
+            if result != "wal" {
+                error!("Failed to put DB in WAL mode.  This will make keystore slow.");
+            }
             break;
         }
 
@@ -1413,18 +1416,6 @@
         .context("In get_or_create_key_with.")
     }
 
-    /// SQLite3 seems to hold a shared mutex while running the busy handler when
-    /// waiting for the database file to become available. This makes it
-    /// impossible to successfully recover from a locked database when the
-    /// transaction holding the device busy is in the same process on a
-    /// different connection. As a result the busy handler has to time out and
-    /// fail in order to make progress.
-    ///
-    /// Instead, we set the busy handler to None (return immediately). And catch
-    /// Busy and Locked errors (the latter occur on in memory databases with
-    /// shared cache, e.g., the per-boot database.) and restart the transaction
-    /// after a grace period of half a millisecond.
-    ///
     /// Creates a transaction with the given behavior and executes f with the new transaction.
     /// The transaction is committed only if f returns Ok and retried if DatabaseBusy
     /// or DatabaseLocked is encountered.
diff --git a/keystore2/vpnprofilestore/lib.rs b/keystore2/vpnprofilestore/lib.rs
index 8b3bc2b..3d986a2 100644
--- a/keystore2/vpnprofilestore/lib.rs
+++ b/keystore2/vpnprofilestore/lib.rs
@@ -24,6 +24,7 @@
 };
 use anyhow::{Context, Result};
 use keystore2::{async_task::AsyncTask, legacy_blob::LegacyBlobLoader, utils::watchdog as wd};
+use log::error;
 use rusqlite::{
     params, Connection, OptionalExtension, Transaction, TransactionBehavior, NO_PARAMS,
 };
@@ -42,10 +43,16 @@
             conn: Connection::open(db_file).context("Failed to initialize SQLite connection.")?,
         };
 
-        // On busy fail Immediately. It is unlikely to succeed given a bug in sqlite.
-        db.conn.busy_handler(None).context("Failed to set busy handler.")?;
-
         db.init_tables().context("Trying to initialize vpnstore db.")?;
+
+        let result: String = db
+            .conn
+            .pragma_update_and_check(None, "journal_mode", &"WAL", |row| row.get(0))
+            .expect("Attempting to set journal mode failed.");
+        if result != "wal" {
+            error!("Failed to put DB in WAL mode.  This will make keystore slow.");
+        }
+
         Ok(db)
     }