diff --git a/heed/src/cookbook.rs b/heed/src/cookbook.rs index c47d5f9c..ac0d3d9d 100644 --- a/heed/src/cookbook.rs +++ b/heed/src/cookbook.rs @@ -341,8 +341,9 @@ //! //! # Advanced Multithreaded Access of Entries //! -//! LMDB disallow sharing cursors amongs threads. It is only possible to send -//! them between threads when the heed `read-txn-no-tls` feature is enabled. +//! LMDB disallows sharing cursors among threads. It is only possible to send +//! them between threads when the environment has been opened with +//! [`EnvOpenOptions::read_txn_without_tls`] method. //! //! Please note that this should not be utilized with an encrypted heed3 database. These //! types of databases employ an internal cycling buffer for decrypting entries, which diff --git a/heed/src/databases/database.rs b/heed/src/databases/database.rs index e17a02b6..33d2d51d 100644 --- a/heed/src/databases/database.rs +++ b/heed/src/databases/database.rs @@ -378,8 +378,9 @@ impl Database { /// Returns an iterator over all of the values of a single key. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -986,8 +987,9 @@ impl Database { /// Return an ordered iterator of all key-value pairs in this database. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1087,8 +1089,9 @@ impl Database { /// Return a reverse ordered iterator of all key-value pairs in this database. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1192,8 +1195,9 @@ impl Database { /// /// Comparisons are made by using the comparator `C`. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1364,8 +1368,9 @@ impl Database { /// /// Comparisons are made by using the comparator `C`. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1537,8 +1542,9 @@ impl Database { /// /// Comparisons are made by using the bytes representation of the key. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1669,8 +1675,9 @@ impl Database { /// /// Comparisons are made by using the bytes representation of the key. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; diff --git a/heed/src/databases/encrypted_database.rs b/heed/src/databases/encrypted_database.rs index 4e06cbc1..9b506f70 100644 --- a/heed/src/databases/encrypted_database.rs +++ b/heed/src/databases/encrypted_database.rs @@ -319,8 +319,9 @@ impl EncryptedDatabase { /// Returns an iterator over all of the values of a single key. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -822,8 +823,9 @@ impl EncryptedDatabase { /// Return a lexicographically ordered iterator of all key-value pairs in this database. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -920,8 +922,9 @@ impl EncryptedDatabase { /// Return a reversed lexicographically ordered iterator of all key-value pairs in this database. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1021,8 +1024,9 @@ impl EncryptedDatabase { /// /// Comparisons are made by using the comparator `C`. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1143,8 +1147,9 @@ impl EncryptedDatabase { /// /// Comparisons are made by using the comparator `C`. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1265,8 +1270,9 @@ impl EncryptedDatabase { /// /// Comparisons are made by using the bytes representation of the key. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; @@ -1389,8 +1395,9 @@ impl EncryptedDatabase { /// /// Comparisons are made by using the bytes representation of the key. /// - /// You can make this iterator `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this iterator `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ``` /// # use std::fs; diff --git a/heed/src/envs/encrypted_env.rs b/heed/src/envs/encrypted_env.rs index d1347e74..742280c8 100644 --- a/heed/src/envs/encrypted_env.rs +++ b/heed/src/envs/encrypted_env.rs @@ -191,8 +191,10 @@ impl EncryptedEnv { /// Create a transaction with read-only access for use with the environment. /// - /// You can make this transaction `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this transaction `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. + /// /// See [`Self::static_read_txn`] if you want the txn to own the environment. /// /// ## LMDB Limitations @@ -221,8 +223,9 @@ impl EncryptedEnv { /// Contrary to [`Self::read_txn`], this version **owns** the environment, which /// means you won't be able to close the environment while this transaction is alive. /// - /// You can make this transaction `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this transaction `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ## LMDB Limitations /// diff --git a/heed/src/envs/env.rs b/heed/src/envs/env.rs index 8d2f0793..f7c00ccb 100644 --- a/heed/src/envs/env.rs +++ b/heed/src/envs/env.rs @@ -341,8 +341,10 @@ impl Env { /// Create a transaction with read-only access for use with the environment. /// - /// You can make this transaction `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this transaction `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. + /// /// See [`Self::static_read_txn`] if you want the txn to own the environment. /// /// ## LMDB Limitations @@ -371,8 +373,9 @@ impl Env { /// Contrary to [`Self::read_txn`], this version **owns** the environment, which /// means you won't be able to close the environment while this transaction is alive. /// - /// You can make this transaction `Send`able between threads by - /// using the `read-txn-no-tls` crate feature. + /// You can make this transaction `Send`able between threads by opening + /// the environment with the [`EnvOpenOptions::read_txn_without_tls`] + /// method. /// /// ## LMDB Limitations /// diff --git a/heed/src/envs/env_open_options.rs b/heed/src/envs/env_open_options.rs index 463a07a2..ee70d87d 100644 --- a/heed/src/envs/env_open_options.rs +++ b/heed/src/envs/env_open_options.rs @@ -161,7 +161,7 @@ impl EnvOpenOptions { /// /// # fn main() -> Result<(), Box> { /// let mut env_builder = EnvOpenOptions::new(); - /// unsafe { env_builder.flags(EnvFlags::NO_TLS | EnvFlags::NO_META_SYNC); } + /// unsafe { env_builder.flags(EnvFlags::NO_META_SYNC); } /// let dir = tempfile::tempdir().unwrap(); /// let env = unsafe { env_builder.open(dir.path())? }; /// @@ -457,16 +457,11 @@ impl EnvOpenOptions { mdb_result(ffi::mdb_env_set_maxdbs(env, dbs))?; } - // When the `read-txn-no-tls` feature is enabled, we must force LMDB - // to avoid using the thread local storage, this way we allow users - // to use references of RoTxn between threads safely. - #[allow(deprecated)] // NO_TLS is inside of the crate - let flags = if T::ENABLED { - // TODO make this a ZST flag on the Env and on RoTxn (make them Send when we can) - self.flags - } else { - self.flags | EnvFlags::NO_TLS - }; + // When the `::ENABLED` is true, we must tell + // LMDB to avoid using the thread local storage, this way we + // allow users to move RoTxn between threads safely. + #[allow(deprecated)] // ok because NO_TLS is inside of the crate + let flags = if T::ENABLED { self.flags } else { self.flags | EnvFlags::NO_TLS }; let result = ffi::mdb_env_open(env, path_str.as_ptr(), flags.bits(), 0o600); match mdb_result(result) { diff --git a/heed/src/mdb/lmdb_flags.rs b/heed/src/mdb/lmdb_flags.rs index d41881fc..091f91ed 100644 --- a/heed/src/mdb/lmdb_flags.rs +++ b/heed/src/mdb/lmdb_flags.rs @@ -28,6 +28,8 @@ bitflags! { /// Use asynchronous msync when MDB_WRITEMAP is used. const MAP_ASYNC = ffi::MDB_MAPASYNC; /// Tie reader locktable slots to MDB_txn objects instead of to threads. + // Note to self: When removing this flag from here, we must introduce an + // internal-only AllEnvFlags akin to the AllDatabaseFlags bitflags. #[deprecated(since="0.22.0", note="please use `EnvOpenOptions::read_txn_with_tls` or `EnvOpenOptions::read_txn_without_tls` instead")] const NO_TLS = ffi::MDB_NOTLS; /// Don't do any locking, caller must manage their own locks. diff --git a/heed3/Cargo.toml b/heed3/Cargo.toml index 5cf9cf66..abdf2316 100644 --- a/heed3/Cargo.toml +++ b/heed3/Cargo.toml @@ -45,21 +45,6 @@ url = "2.5.4" default = ["serde", "serde-bincode", "serde-json"] serde = ["bitflags/serde", "dep:serde"] -# The #MDB_NOTLS flag is automatically set on Env opening, -# RoTxn and RoCursors implements the Send trait. This allows the -# user to move RoTxns and RoCursors between threads as read transactions -# will no more use thread local storage and will tie reader locktable -# slots to #MDB_txn objects instead of to threads. -# -# According to the LMDB documentation, when this feature is not enabled: -# A thread can only use one transaction at a time, plus any child -# transactions. Each transaction belongs to one thread. [...] -# The #MDB_NOTLS flag changes this for read-only transactions. -# -# And a #MDB_BAD_RSLOT error will be thrown when multiple read -# transactions exists on the same thread -read-txn-no-tls = [] - # Enable the serde en/decoders for bincode, serde_json, or rmp_serde serde-bincode = ["heed-types/serde-bincode"] serde-json = ["heed-types/serde-json"]