/rust/registry/src/index.crates.io-1949cf8c6b5b557f/dashmap-6.1.0/src/util.rs
Line | Count | Source |
1 | | //! This module is full of hackery and dark magic. |
2 | | //! Either spend a day fixing it and quietly submit a PR or don't mention it to anybody. |
3 | | use core::cell::UnsafeCell; |
4 | | use core::{mem, ptr}; |
5 | | |
6 | 176 | pub const fn ptr_size_bits() -> usize { |
7 | 176 | mem::size_of::<usize>() * 8 |
8 | 176 | } |
9 | | |
10 | 0 | pub fn map_in_place_2<T, U, F: FnOnce(U, T) -> T>((k, v): (U, &mut T), f: F) { |
11 | 0 | unsafe { |
12 | 0 | // # Safety |
13 | 0 | // |
14 | 0 | // If the closure panics, we must abort otherwise we could double drop `T` |
15 | 0 | let promote_panic_to_abort = AbortOnPanic; |
16 | 0 |
|
17 | 0 | ptr::write(v, f(k, ptr::read(v))); |
18 | 0 |
|
19 | 0 | // If we made it here, the calling thread could have already have panicked, in which case |
20 | 0 | // We know that the closure did not panic, so don't bother checking. |
21 | 0 | std::mem::forget(promote_panic_to_abort); |
22 | 0 | } |
23 | 0 | } |
24 | | |
25 | | /// A simple wrapper around `T` |
26 | | /// |
27 | | /// This is to prevent UB when using `HashMap::get_key_value`, because |
28 | | /// `HashMap` doesn't expose an api to get the key and value, where |
29 | | /// the value is a `&mut T`. |
30 | | /// |
31 | | /// See [#10](https://github.com/xacrimon/dashmap/issues/10) for details |
32 | | /// |
33 | | /// This type is meant to be an implementation detail, but must be exposed due to the `Dashmap::shards` |
34 | | #[repr(transparent)] |
35 | | pub struct SharedValue<T> { |
36 | | value: UnsafeCell<T>, |
37 | | } |
38 | | |
39 | | impl<T: Clone> Clone for SharedValue<T> { |
40 | 0 | fn clone(&self) -> Self { |
41 | 0 | let inner = self.get().clone(); |
42 | | |
43 | 0 | Self { |
44 | 0 | value: UnsafeCell::new(inner), |
45 | 0 | } |
46 | 0 | } |
47 | | } |
48 | | |
49 | | unsafe impl<T: Send> Send for SharedValue<T> {} |
50 | | |
51 | | unsafe impl<T: Sync> Sync for SharedValue<T> {} |
52 | | |
53 | | impl<T> SharedValue<T> { |
54 | | /// Create a new `SharedValue<T>` |
55 | 0 | pub const fn new(value: T) -> Self { |
56 | 0 | Self { |
57 | 0 | value: UnsafeCell::new(value), |
58 | 0 | } |
59 | 0 | } Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::new Unexecuted instantiation: <dashmap::util::SharedValue<_>>::new Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::new |
60 | | |
61 | | /// Get a shared reference to `T` |
62 | 0 | pub fn get(&self) -> &T { |
63 | 0 | unsafe { &*self.value.get() } |
64 | 0 | } Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::get Unexecuted instantiation: <dashmap::util::SharedValue<_>>::get Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::get |
65 | | |
66 | | /// Get an unique reference to `T` |
67 | 0 | pub fn get_mut(&mut self) -> &mut T { |
68 | 0 | unsafe { &mut *self.value.get() } |
69 | 0 | } Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::get_mut Unexecuted instantiation: <dashmap::util::SharedValue<_>>::get_mut Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::get_mut |
70 | | |
71 | | /// Unwraps the value |
72 | 0 | pub fn into_inner(self) -> T { |
73 | 0 | self.value.into_inner() |
74 | 0 | } Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::into_inner Unexecuted instantiation: <dashmap::util::SharedValue<_>>::into_inner Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::into_inner |
75 | | |
76 | | /// Get a mutable raw pointer to the underlying value |
77 | 0 | pub(crate) fn as_ptr(&self) -> *mut T { |
78 | 0 | self.value.get() |
79 | 0 | } Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::as_ptr Unexecuted instantiation: <dashmap::util::SharedValue<_>>::as_ptr Unexecuted instantiation: <dashmap::util::SharedValue<alloc::sync::Arc<(lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, u32>, parking_lot::condvar::Condvar)>>>::as_ptr |
80 | | } |
81 | | |
82 | | struct AbortOnPanic; |
83 | | |
84 | | impl Drop for AbortOnPanic { |
85 | 0 | fn drop(&mut self) { |
86 | 0 | if std::thread::panicking() { |
87 | 0 | std::process::abort() |
88 | 0 | } |
89 | 0 | } |
90 | | } |