Skip to content

Commit

Permalink
ref: Switch back to UnsafeCell from ArcSwap (getsentry#529)
Browse files Browse the repository at this point in the history
Turns out `ArcSwap` does have a slight cost. The previous implementation used `UnsafeCell`, so switch back to that.
  • Loading branch information
Swatinem authored Nov 30, 2022
1 parent b12f72d commit 96e1da3
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 20 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

**Internal**:

- 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))
- 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))

**Thank you**:

Expand Down
3 changes: 1 addition & 2 deletions sentry-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ harness = false

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

[target.'cfg(target_family = "unix")'.dependencies]
pprof = { version = "0.11.0", optional = true, default-features = false }
Expand Down
34 changes: 17 additions & 17 deletions sentry-core/src/hub_impl.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use std::cell::Cell;
use std::cell::{Cell, UnsafeCell};
use std::sync::{Arc, PoisonError, RwLock};
use std::thread;

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

use arc_swap::ArcSwap;
use once_cell::sync::Lazy;

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

thread_local! {
static THREAD_HUB: (ArcSwap<Hub>, Cell<bool>) = (
ArcSwap::from_pointee(Hub::new_from_top(&PROCESS_HUB.0)),
static THREAD_HUB: (UnsafeCell<Arc<Hub>>, Cell<bool>) = (
UnsafeCell::new(Arc::new(Hub::new_from_top(&PROCESS_HUB.0))),
Cell::new(PROCESS_HUB.1 == thread::current().id())
);
}
Expand All @@ -27,25 +26,26 @@ pub(crate) struct SwitchGuard {
}

impl SwitchGuard {
pub(crate) fn new(hub: Arc<Hub>) -> Self {
let inner = THREAD_HUB.with(|(old_hub, is_process_hub)| {
{
let old_hub = old_hub.load();
if std::ptr::eq(old_hub.as_ref(), hub.as_ref()) {
return None;
}
pub(crate) fn new(mut hub: Arc<Hub>) -> Self {
let inner = THREAD_HUB.with(|(thread_hub, is_process_hub)| {
// SAFETY: `thread_hub` will always be a valid thread local hub,
// by definition not shared between threads.
let thread_hub = unsafe { &mut *thread_hub.get() };
if std::ptr::eq(thread_hub.as_ref(), hub.as_ref()) {
return None;
}
let old_hub = old_hub.swap(hub);
std::mem::swap(thread_hub, &mut hub);
let was_process_hub = is_process_hub.replace(false);
Some((old_hub, was_process_hub))
Some((hub, was_process_hub))
});
SwitchGuard { inner }
}

fn swap(&mut self) -> Option<Arc<Hub>> {
if let Some((old_hub, was_process_hub)) = self.inner.take() {
Some(THREAD_HUB.with(|(hub, is_process_hub)| {
let hub = hub.swap(old_hub);
if let Some((mut hub, was_process_hub)) = self.inner.take() {
Some(THREAD_HUB.with(|(thread_hub, is_process_hub)| {
let thread_hub = unsafe { &mut *thread_hub.get() };
std::mem::swap(thread_hub, &mut hub);
if was_process_hub {
is_process_hub.set(true);
}
Expand Down Expand Up @@ -150,7 +150,7 @@ impl Hub {
if is_process_hub.get() {
f(&PROCESS_HUB.0)
} else {
f(&hub.load())
f(unsafe { &*hub.get() })
}
})
}
Expand Down

0 comments on commit 96e1da3

Please sign in to comment.