diff --git a/Cargo.lock b/Cargo.lock index 56bfa311..34f4f9f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -623,6 +623,7 @@ dependencies = [ "serde", "tempfile", "thiserror", + "thread_local", "tokio", "tokio-util", "tower", diff --git a/database/Cargo.toml b/database/Cargo.toml index 5d7bb8b7..e61cc555 100644 --- a/database/Cargo.toml +++ b/database/Cargo.toml @@ -35,15 +35,19 @@ page_size = { version = "0.6.0" } # Needed for database resizes, they mus thiserror = { workspace = true } # `service` feature. -crossbeam = { workspace = true, features = ["std"], optional = true } -futures = { workspace = true, optional = true } -tokio = { workspace = true, features = ["full"], optional = true } -tokio-util = { workspace = true, features = ["full"], optional = true } -tower = { workspace = true, features = ["full"], optional = true } -rayon = { workspace = true, optional = true } +crossbeam = { workspace = true, features = ["std"], optional = true } +futures = { workspace = true, optional = true } +tokio = { workspace = true, features = ["full"], optional = true } +tokio-util = { workspace = true, features = ["full"], optional = true } +tower = { workspace = true, features = ["full"], optional = true } +thread_local = { workspace = true } +rayon = { workspace = true, optional = true } # Optional features. -heed = { version = "0.20.0-alpha.9", optional = true } +# SAFETY: Do not remove the `read-txn-no-tls` feature. +# Required for `heed`'s read transaction to be `Send`. +# See for more info. +heed = { version = "0.20.0-alpha.9", features = ["read-txn-no-tls"], optional = true } redb = { version = "2.0.0", optional = true } serde = { workspace = true, optional = true } diff --git a/database/src/backend/heed/database.rs b/database/src/backend/heed/database.rs index 01d544de..7a62855d 100644 --- a/database/src/backend/heed/database.rs +++ b/database/src/backend/heed/database.rs @@ -49,6 +49,17 @@ pub(super) struct HeedTableRw<'env, 'tx, T: Table> { pub(super) tx_rw: &'tx RefCell>, } +/// SAFETY: `cuprate_database`'s Cargo.toml enables a feature +/// for `heed` that turns on the `MDB_NOTLS` flag for LMDB. +/// +/// This makes read transactions `Send`, but only if that flag is enabled. +/// +/// This is required as in `crate::service` we must put our transactions and +/// tables inside `ThreadLocal`'s to use across multiple threads. +/// +/// `ThreadLocal` requires that `T: Send`. +unsafe impl Send for HeedTableRo<'_, T> {} + //---------------------------------------------------------------------------------------------------- Shared functions // FIXME: we cannot just deref `HeedTableRw -> HeedTableRo` and // call the functions since the database is held by value, so