Implement Send and Sync for useful types (#318)

The Send and Sync traits aren't auto-implemented on the many types which
wrap a raw pointer to some RocksDB struct. Most of these types are
nevertheless safe to use in Send and Sync context, so they should be
marked as such
master
rnarubin 5 years ago committed by Ilya Bogdanov
parent 73d5e00b79
commit 9e75179e77
  1. 12
      src/db.rs
  2. 10
      src/db_options.rs
  3. 46
      src/lib.rs

@ -199,8 +199,6 @@ pub struct DBIterator<'a> {
just_seeked: bool,
}
unsafe impl<'a> Send for DBIterator<'a> {}
pub enum Direction {
Forward,
Reverse,
@ -1854,6 +1852,16 @@ impl Default for ReadOptions {
}
}
// Safety note: auto-implementing Send on most db-related types is prevented by the inner FFI
// pointer. In most cases, however, this pointer is Send-safe because it is never aliased and
// rocksdb internally does not rely on thread-local information for its user-exposed types.
unsafe impl<'a> Send for DBRawIterator<'a> {}
unsafe impl Send for ReadOptions {}
// Sync is similarly safe for many types because they do not expose interior mutability, and their
// use within the rocksdb library is generally behind a const reference
unsafe impl Sync for ReadOptions {}
/// Vector of bytes stored in the database.
///
/// This is a `C` allocated byte array and a length value.

@ -34,7 +34,17 @@ pub fn new_cache(capacity: size_t) -> *mut ffi::rocksdb_cache_t {
unsafe { ffi::rocksdb_cache_create_lru(capacity) }
}
// Safety note: auto-implementing Send on most db-related types is prevented by the inner FFI
// pointer. In most cases, however, this pointer is Send-safe because it is never aliased and
// rocksdb internally does not rely on thread-local information for its user-exposed types.
unsafe impl Send for Options {}
unsafe impl Send for WriteOptions {}
unsafe impl Send for BlockBasedOptions {}
// Sync is similarly safe for many types because they do not expose interior mutability, and their
// use within the rocksdb library is generally behind a const reference
unsafe impl Sync for Options {}
unsafe impl Sync for WriteOptions {}
unsafe impl Sync for BlockBasedOptions {}
impl Drop for Options {
fn drop(&mut self) {

@ -290,3 +290,49 @@ pub struct ColumnFamily<'a> {
}
unsafe impl<'a> Send for ColumnFamily<'a> {}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn is_send() {
// test (at compile time) that certain types implement the auto-trait Send, either directly for
// pointer-wrapping types or transitively for types with all Send fields
fn is_send<T: Send>() {
// dummy function just used for its parameterized type bound
}
is_send::<DB>();
is_send::<DBIterator<'_>>();
is_send::<DBRawIterator<'_>>();
is_send::<Snapshot>();
is_send::<Options>();
is_send::<ReadOptions>();
is_send::<WriteOptions>();
is_send::<BlockBasedOptions>();
is_send::<PlainTableFactoryOptions>();
is_send::<ColumnFamilyDescriptor>();
is_send::<ColumnFamily>();
}
#[test]
fn is_sync() {
// test (at compile time) that certain types implement the auto-trait Sync
fn is_sync<T: Sync>() {
// dummy function just used for its parameterized type bound
}
is_sync::<DB>();
is_sync::<Snapshot>();
is_sync::<Options>();
is_sync::<ReadOptions>();
is_sync::<WriteOptions>();
is_sync::<BlockBasedOptions>();
is_sync::<PlainTableFactoryOptions>();
is_sync::<ColumnFamilyDescriptor>();
}
}

Loading…
Cancel
Save