Bug 1638927 - Replace `lazy_static` with `once_cell` in XULStore. r=froydnj
authorLina Cambridge <lina@yakshaving.ninja>
Fri, 22 May 2020 00:40:25 +0000
changeset 531566 1785974f69f21f44e54a644440d439925d1f8fe3
parent 531565 89d99941f3af28b7faf6570a20c584652d876c59
child 531567 7cdd5e64521e1f67aa626464142a80eaaa6a4f29
push id37440
push userabutkovits@mozilla.com
push dateFri, 22 May 2020 09:43:16 +0000
treeherdermozilla-central@fbf71e4d2e21 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1638927
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1638927 - Replace `lazy_static` with `once_cell` in XULStore. r=froydnj TSan returns false positives for `lazy_static`. While we could blocklist it, `once_cell` has equivalent functionality, but with a more modern API, so let's use it instead. Depends on D75864 Differential Revision: https://phabricator.services.mozilla.com/D76342
Cargo.lock
toolkit/components/xulstore/Cargo.toml
toolkit/components/xulstore/src/lib.rs
toolkit/components/xulstore/src/persist.rs
toolkit/components/xulstore/src/statics.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5785,23 +5785,23 @@ dependencies = [
 
 [[package]]
 name = "xulstore"
 version = "0.1.0"
 dependencies = [
  "crossbeam-utils 0.6.5",
  "cstr",
  "failure",
- "lazy_static",
  "libc",
  "lmdb-rkv",
  "log",
  "moz_task",
  "nserror",
  "nsstring",
+ "once_cell",
  "rkv 0.10.4",
  "serde_json",
  "tempfile",
  "xpcom",
 ]
 
 [[package]]
 name = "yaml-rust"
--- a/toolkit/components/xulstore/Cargo.toml
+++ b/toolkit/components/xulstore/Cargo.toml
@@ -2,23 +2,23 @@
 name = "xulstore"
 version = "0.1.0"
 authors = ["nobody@mozilla.org"]
 license = "MPL-2.0"
 
 [dependencies]
 crossbeam-utils = "0.6.3"
 cstr = "0.1"
-lazy_static = "1.0"
 libc = "0.2"
 lmdb-rkv = "0.14"
 log = "0.4"
 moz_task = { path = "../../../xpcom/rust/moz_task" }
 nsstring = { path = "../../../xpcom/rust/nsstring" }
 nserror = { path = "../../../xpcom/rust/nserror" }
+once_cell = "1"
 rkv = "0.10.2"
 serde_json = "1"
 tempfile = "3"
 xpcom = { path = "../../../xpcom/rust/xpcom" }
 
 # Get rid of failure's dependency on backtrace. Eventually
 # backtrace will move into Rust core, but we don't need it here.
 [dependencies.failure]
--- a/toolkit/components/xulstore/src/lib.rs
+++ b/toolkit/components/xulstore/src/lib.rs
@@ -2,25 +2,24 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 extern crate crossbeam_utils;
 #[macro_use]
 extern crate cstr;
 #[macro_use]
 extern crate failure;
-#[macro_use]
-extern crate lazy_static;
 extern crate libc;
 extern crate lmdb;
 #[macro_use]
 extern crate log;
 extern crate moz_task;
 extern crate nserror;
 extern crate nsstring;
+extern crate once_cell;
 extern crate rkv;
 extern crate serde_json;
 extern crate tempfile;
 #[macro_use]
 extern crate xpcom;
 
 mod error;
 mod ffi;
--- a/toolkit/components/xulstore/src/persist.rs
+++ b/toolkit/components/xulstore/src/persist.rs
@@ -17,39 +17,39 @@
 use crate::{
     error::{XULStoreError, XULStoreResult},
     statics::get_database,
 };
 use crossbeam_utils::atomic::AtomicCell;
 use lmdb::Error as LmdbError;
 use moz_task::{dispatch_background_task_with_options, DispatchOptions, Task, TaskRunnable};
 use nserror::nsresult;
+use once_cell::sync::Lazy;
 use rkv::{StoreError as RkvStoreError, Value};
 use std::{collections::HashMap, sync::Mutex, thread::sleep, time::Duration};
 use xpcom::RefPtr;
 
-lazy_static! {
-    /// A map of key/value pairs to persist.  Values are Options so we can
-    /// use the same structure for both puts and deletes, with a `None` value
-    /// identifying a key that should be deleted from the database.
-    ///
-    /// This is a map rather than a sequence in order to merge consecutive
-    /// changes to the same key, i.e. when a consumer sets *foo* to `bar`
-    /// and then sets it again to `baz` before we persist the first change.
-    ///
-    /// In that case, there's no point in setting *foo* to `bar` before we set
-    /// it to `baz`, and the map ensures we only ever persist the latest value
-    /// for any given key.
-    static ref CHANGES: Mutex<Option<HashMap<String, Option<String>>>> = { Mutex::new(None) };
+/// A map of key/value pairs to persist.  Values are Options so we can
+/// use the same structure for both puts and deletes, with a `None` value
+/// identifying a key that should be deleted from the database.
+///
+/// This is a map rather than a sequence in order to merge consecutive
+/// changes to the same key, i.e. when a consumer sets *foo* to `bar`
+/// and then sets it again to `baz` before we persist the first change.
+///
+/// In that case, there's no point in setting *foo* to `bar` before we set
+/// it to `baz`, and the map ensures we only ever persist the latest value
+/// for any given key.
+static CHANGES: Lazy<Mutex<Option<HashMap<String, Option<String>>>>> =
+    Lazy::new(|| Mutex::new(None));
 
-    /// A Mutex that prevents two PersistTasks from running at the same time,
-    /// since each task opens the database, and we need to ensure there is only
-    /// one open database handle for the database at any given time.
-    static ref PERSIST: Mutex<()> = { Mutex::new(()) };
-}
+/// A Mutex that prevents two PersistTasks from running at the same time,
+/// since each task opens the database, and we need to ensure there is only
+/// one open database handle for the database at any given time.
+static PERSIST: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
 
 /// Synchronously persists changes recorded in memory to disk. Typically
 /// called from a background thread, however this can be called from the main
 /// thread in Gecko during shutdown (via flush_writes).
 fn sync_persist() -> XULStoreResult<()> {
     let db = get_database()?;
     let mut writer = db.env.write()?;
 
--- a/toolkit/components/xulstore/src/statics.rs
+++ b/toolkit/components/xulstore/src/statics.rs
@@ -5,16 +5,17 @@
 use crate::{
     error::{XULStoreError, XULStoreResult},
     ffi::ProfileChangeObserver,
     make_key, SEPARATOR,
 };
 use lmdb::Error as LmdbError;
 use moz_task::is_main_thread;
 use nsstring::nsString;
+use once_cell::sync::Lazy;
 use rkv::{migrate::Migrator, Rkv, SingleStore, StoreError, StoreOptions, Value};
 use std::{
     collections::BTreeMap,
     fs::{copy, create_dir_all, remove_file, File},
     path::PathBuf,
     str,
     sync::Mutex,
 };
@@ -29,24 +30,23 @@ pub struct Database {
 }
 
 impl Database {
     fn new(env: Rkv, store: SingleStore) -> Database {
         Database { env, store }
     }
 }
 
-lazy_static! {
-    static ref PROFILE_DIR: Mutex<Option<PathBuf>> = {
-        observe_profile_change();
-        Mutex::new(get_profile_dir().ok())
-    };
-    pub(crate) static ref DATA_CACHE: Mutex<Option<XULStoreCache>> =
-        { Mutex::new(cache_data().ok()) };
-}
+static PROFILE_DIR: Lazy<Mutex<Option<PathBuf>>> = Lazy::new(|| {
+    observe_profile_change();
+    Mutex::new(get_profile_dir().ok())
+});
+
+pub(crate) static DATA_CACHE: Lazy<Mutex<Option<XULStoreCache>>> =
+    Lazy::new(|| Mutex::new(cache_data().ok()));
 
 pub(crate) fn get_database() -> XULStoreResult<Database> {
     let xulstore_dir = get_xulstore_dir()?;
     let xulstore_path = xulstore_dir.as_path();
 
     let env = match Rkv::new(xulstore_path) {
         Ok(env) => Ok(env),
         Err(StoreError::LmdbError(LmdbError::Invalid)) => {