From 30d0f08b6073e9c2e545a3567838a9e1e885fea2 Mon Sep 17 00:00:00 2001 From: Mica White Date: Mon, 23 Dec 2024 15:31:07 -0500 Subject: Remove scopeguard The scopeguard crate was being used for its `defer_on_unwind` macro. The problem was that it runs even if the runtime was already panicking. There aren't any changes to the macro which could have fixed this. I instead wrote my own function to check for a specific panicking closure. --- src/rwlock/rwlock.rs | 101 +++++++++++---------------------------------------- 1 file changed, 22 insertions(+), 79 deletions(-) (limited to 'src/rwlock') diff --git a/src/rwlock/rwlock.rs b/src/rwlock/rwlock.rs index 94c6062..03b2cfd 100644 --- a/src/rwlock/rwlock.rs +++ b/src/rwlock/rwlock.rs @@ -1,8 +1,11 @@ +use std::cell::UnsafeCell; use std::fmt::Debug; -use std::{cell::UnsafeCell, marker::PhantomData}; +use std::marker::PhantomData; +use std::panic::AssertUnwindSafe; use lock_api::RawRwLock; +use crate::handle_unwind::handle_unwind; use crate::key::Keyable; use crate::lockable::{ Lockable, LockableAsMut, LockableIntoInner, OwnedLockable, RawLock, Sharable, @@ -21,19 +24,9 @@ unsafe impl RawLock for RwLock { "The read-write lock has been killed" ); - scopeguard::defer_on_unwind! { - scopeguard::defer_on_unwind! { self.kill() }; - if self.raw_try_lock() { - self.raw_unlock(); - } else { - // We don't know whether this lock is locked by the current - // thread, or another thread. There's not much we can do other - // than kill it. - self.kill(); - } - } - - self.raw.lock_exclusive() + // if the closure unwraps, then the mutex will be killed + let this = AssertUnwindSafe(self); + handle_unwind(|| this.raw.lock_exclusive(), || self.kill()) } unsafe fn raw_try_lock(&self) -> bool { @@ -41,35 +34,15 @@ unsafe impl RawLock for RwLock { return false; } - scopeguard::defer_on_unwind! { - scopeguard::defer_on_unwind! { self.kill() }; - if self.raw_try_lock() { - self.raw_unlock(); - } else { - // We don't know whether this lock is locked by the current - // thread, or another thread. There's not much we can do other - // than kill it. - self.kill(); - } - } - - self.raw.try_lock_exclusive() + // if the closure unwraps, then the mutex will be killed + let this = AssertUnwindSafe(self); + handle_unwind(|| this.raw.try_lock_exclusive(), || self.kill()) } unsafe fn raw_unlock(&self) { - scopeguard::defer_on_unwind! { - scopeguard::defer_on_unwind! { self.kill() }; - if self.raw_try_lock() { - self.raw_unlock(); - } else { - // We don't know whether this lock is locked by the current - // thread, or another thread. There's not much we can do other - // than kill it. - self.kill(); - } - } - - self.raw.unlock_exclusive() + // if the closure unwraps, then the mutex will be killed + let this = AssertUnwindSafe(self); + handle_unwind(|| this.raw.unlock_exclusive(), || self.kill()) } unsafe fn raw_read(&self) { @@ -78,19 +51,9 @@ unsafe impl RawLock for RwLock { "The read-write lock has been killed" ); - scopeguard::defer_on_unwind! { - scopeguard::defer_on_unwind! { self.kill() }; - if self.raw_try_read() { - self.raw_unlock_read(); - } else { - // We don't know whether this lock is locked by the current - // thread, or another thread. There's not much we can do other - // than kill it. - self.kill(); - } - } - - self.raw.lock_shared() + // if the closure unwraps, then the mutex will be killed + let this = AssertUnwindSafe(self); + handle_unwind(|| this.raw.lock_shared(), || self.kill()) } unsafe fn raw_try_read(&self) -> bool { @@ -98,35 +61,15 @@ unsafe impl RawLock for RwLock { return false; } - scopeguard::defer_on_unwind! { - scopeguard::defer_on_unwind! { self.kill() }; - if self.raw_try_read() { - self.raw_unlock_read(); - } else { - // We don't know whether this lock is locked by the current - // thread, or another thread. There's not much we can do other - // than kill it. - self.kill(); - } - } - - self.raw.try_lock_shared() + // if the closure unwraps, then the mutex will be killed + let this = AssertUnwindSafe(self); + handle_unwind(|| this.raw.try_lock_shared(), || self.kill()) } unsafe fn raw_unlock_read(&self) { - scopeguard::defer_on_unwind! { - scopeguard::defer_on_unwind! { self.kill() }; - if self.raw_try_read() { - self.raw_unlock_read(); - } else { - // We don't know whether this lock is locked by the current - // thread, or another thread. There's not much we can do other - // than kill it. - self.kill(); - } - } - - self.raw.unlock_shared() + // if the closure unwraps, then the mutex will be killed + let this = AssertUnwindSafe(self); + handle_unwind(|| this.raw.unlock_shared(), || self.kill()) } } -- cgit v1.2.3