Skip to content

Commit 96e1da3

Browse files
authored
ref: Switch back to UnsafeCell from ArcSwap (#529)
Turns out `ArcSwap` does have a slight cost. The previous implementation used `UnsafeCell`, so switch back to that.
1 parent b12f72d commit 96e1da3

File tree

3 files changed

+19
-20
lines changed

3 files changed

+19
-20
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
**Internal**:
1414

15-
- Simplify `Hub::run` and `SentryFuture` by using a scope-guard and `arc-swap` for `Hub` switching. ([#524](https://github.com/getsentry/sentry-rust/pull/524))
15+
- Simplify `Hub::run` and `SentryFuture` by using a scope-guard for `Hub` switching. ([#524](https://github.com/getsentry/sentry-rust/pull/524), [#529](https://github.com/getsentry/sentry-rust/pull/529))
1616

1717
**Thank you**:
1818

sentry-core/Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ harness = false
2121

2222
[features]
2323
default = []
24-
client = ["rand", "arc-swap"]
24+
client = ["rand"]
2525
# I would love to just have a `log` feature, but this is used inside a macro,
2626
# and macros actually expand features (and extern crate) where they are used!
2727
debug-logs = ["dep:log"]
@@ -42,7 +42,6 @@ build_id = { version = "0.2.1", optional = true }
4242
findshlibs = { version = "=0.10.2", optional = true }
4343
rustc_version_runtime = { version = "0.2.1", optional = true }
4444
indexmap = { version = "1.9.1", optional = true }
45-
arc-swap = { version = "1.5.1", optional = true }
4645

4746
[target.'cfg(target_family = "unix")'.dependencies]
4847
pprof = { version = "0.11.0", optional = true, default-features = false }

sentry-core/src/hub_impl.rs

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use std::cell::Cell;
1+
use std::cell::{Cell, UnsafeCell};
22
use std::sync::{Arc, PoisonError, RwLock};
33
use std::thread;
44

55
use crate::Scope;
66
use crate::{scope::Stack, Client, Hub};
77

8-
use arc_swap::ArcSwap;
98
use once_cell::sync::Lazy;
109

1110
static PROCESS_HUB: Lazy<(Arc<Hub>, thread::ThreadId)> = Lazy::new(|| {
@@ -16,8 +15,8 @@ static PROCESS_HUB: Lazy<(Arc<Hub>, thread::ThreadId)> = Lazy::new(|| {
1615
});
1716

1817
thread_local! {
19-
static THREAD_HUB: (ArcSwap<Hub>, Cell<bool>) = (
20-
ArcSwap::from_pointee(Hub::new_from_top(&PROCESS_HUB.0)),
18+
static THREAD_HUB: (UnsafeCell<Arc<Hub>>, Cell<bool>) = (
19+
UnsafeCell::new(Arc::new(Hub::new_from_top(&PROCESS_HUB.0))),
2120
Cell::new(PROCESS_HUB.1 == thread::current().id())
2221
);
2322
}
@@ -27,25 +26,26 @@ pub(crate) struct SwitchGuard {
2726
}
2827

2928
impl SwitchGuard {
30-
pub(crate) fn new(hub: Arc<Hub>) -> Self {
31-
let inner = THREAD_HUB.with(|(old_hub, is_process_hub)| {
32-
{
33-
let old_hub = old_hub.load();
34-
if std::ptr::eq(old_hub.as_ref(), hub.as_ref()) {
35-
return None;
36-
}
29+
pub(crate) fn new(mut hub: Arc<Hub>) -> Self {
30+
let inner = THREAD_HUB.with(|(thread_hub, is_process_hub)| {
31+
// SAFETY: `thread_hub` will always be a valid thread local hub,
32+
// by definition not shared between threads.
33+
let thread_hub = unsafe { &mut *thread_hub.get() };
34+
if std::ptr::eq(thread_hub.as_ref(), hub.as_ref()) {
35+
return None;
3736
}
38-
let old_hub = old_hub.swap(hub);
37+
std::mem::swap(thread_hub, &mut hub);
3938
let was_process_hub = is_process_hub.replace(false);
40-
Some((old_hub, was_process_hub))
39+
Some((hub, was_process_hub))
4140
});
4241
SwitchGuard { inner }
4342
}
4443

4544
fn swap(&mut self) -> Option<Arc<Hub>> {
46-
if let Some((old_hub, was_process_hub)) = self.inner.take() {
47-
Some(THREAD_HUB.with(|(hub, is_process_hub)| {
48-
let hub = hub.swap(old_hub);
45+
if let Some((mut hub, was_process_hub)) = self.inner.take() {
46+
Some(THREAD_HUB.with(|(thread_hub, is_process_hub)| {
47+
let thread_hub = unsafe { &mut *thread_hub.get() };
48+
std::mem::swap(thread_hub, &mut hub);
4949
if was_process_hub {
5050
is_process_hub.set(true);
5151
}
@@ -150,7 +150,7 @@ impl Hub {
150150
if is_process_hub.get() {
151151
f(&PROCESS_HUB.0)
152152
} else {
153-
f(&hub.load())
153+
f(unsafe { &*hub.get() })
154154
}
155155
})
156156
}

0 commit comments

Comments
 (0)