From d4bc8db614068a0aee9ceaf4dadd41667d843fff Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Wed, 14 Oct 2020 21:59:34 -0500 Subject: [PATCH 1/2] Get rid of the hack for epoch::unprotected --- crossbeam-epoch/src/guard.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/crossbeam-epoch/src/guard.rs b/crossbeam-epoch/src/guard.rs index c6a0ba377..64eaed4c9 100644 --- a/crossbeam-epoch/src/guard.rs +++ b/crossbeam-epoch/src/guard.rs @@ -502,12 +502,10 @@ impl fmt::Debug for Guard { /// [`defer`]: Guard::defer #[inline] pub unsafe fn unprotected() -> &'static Guard { - // HACK(stjepang): An unprotected guard is just a `Guard` with its field `local` set to null. - // Since this function returns a `'static` reference to a `Guard`, we must return a reference - // to a global guard. However, it's not possible to create a `static` `Guard` because it does - // not implement `Sync`. To get around the problem, we create a static `usize` initialized to - // zero and then transmute it into a `Guard`. This is safe because `usize` and `Guard` - // (consisting of a single pointer) have the same representation in memory. - static UNPROTECTED: usize = 0; - &*(&UNPROTECTED as *const _ as *const Guard) + // An unprotected guard is just a `Guard` with its field `local` set to null. + // The static needs to be a `static mut` because `Guard` isn't `Sync` + static mut UNPROTECTED: Guard = Guard { + local: std::ptr::null(), + }; + &UNPROTECTED } From a248d3175308d48e901259779ae848d83e064a1c Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Thu, 15 Oct 2020 12:40:08 -0500 Subject: [PATCH 2/2] Use a newtype to store the unprotected guard --- crossbeam-epoch/src/guard.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/crossbeam-epoch/src/guard.rs b/crossbeam-epoch/src/guard.rs index 64eaed4c9..6db3750b0 100644 --- a/crossbeam-epoch/src/guard.rs +++ b/crossbeam-epoch/src/guard.rs @@ -503,9 +503,12 @@ impl fmt::Debug for Guard { #[inline] pub unsafe fn unprotected() -> &'static Guard { // An unprotected guard is just a `Guard` with its field `local` set to null. - // The static needs to be a `static mut` because `Guard` isn't `Sync` - static mut UNPROTECTED: Guard = Guard { - local: std::ptr::null(), - }; - &UNPROTECTED + // We make a newtype over `Guard` because `Guard` isn't `Sync`, so can't be directly stored in + // a `static` + struct GuardWrapper(Guard); + unsafe impl Sync for GuardWrapper {} + static UNPROTECTED: GuardWrapper = GuardWrapper(Guard { + local: core::ptr::null(), + }); + &UNPROTECTED.0 }