mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-26 00:24:55 +01:00
Improve Drop guards
This commit is contained in:
parent
18d69063fd
commit
9a86bae45a
@ -24,6 +24,7 @@ pub(crate) struct RawProc<'a, F, R, S> {
|
|||||||
pub(crate) pdata: *const ProcData,
|
pub(crate) pdata: *const ProcData,
|
||||||
pub(crate) schedule: *const S,
|
pub(crate) schedule: *const S,
|
||||||
pub(crate) future: *mut F,
|
pub(crate) future: *mut F,
|
||||||
|
// TODO: Replace with `MaybeUninit`
|
||||||
pub(crate) output: *mut R,
|
pub(crate) output: *mut R,
|
||||||
|
|
||||||
// Make the lifetime 'a of the future invariant
|
// Make the lifetime 'a of the future invariant
|
||||||
@ -135,7 +136,6 @@ where
|
|||||||
/// Wakes a waker.
|
/// Wakes a waker.
|
||||||
unsafe fn wake(ptr: *const ()) {
|
unsafe fn wake(ptr: *const ()) {
|
||||||
let raw = Self::from_ptr(ptr);
|
let raw = Self::from_ptr(ptr);
|
||||||
let _guard = (&(*raw.pdata).span).enter();
|
|
||||||
let id = (&(*raw.pdata).span)
|
let id = (&(*raw.pdata).span)
|
||||||
.id()
|
.id()
|
||||||
.map(|id| id.into_u64())
|
.map(|id| id.into_u64())
|
||||||
@ -208,7 +208,6 @@ where
|
|||||||
/// Wakes a waker by reference.
|
/// Wakes a waker by reference.
|
||||||
unsafe fn wake_by_ref(ptr: *const ()) {
|
unsafe fn wake_by_ref(ptr: *const ()) {
|
||||||
let raw = Self::from_ptr(ptr);
|
let raw = Self::from_ptr(ptr);
|
||||||
let _guard = (&(*raw.pdata).span).enter();
|
|
||||||
let id = (&(*raw.pdata).span)
|
let id = (&(*raw.pdata).span)
|
||||||
.id()
|
.id()
|
||||||
.map(|id| id.into_u64())
|
.map(|id| id.into_u64())
|
||||||
@ -277,7 +276,6 @@ where
|
|||||||
/// Clones a waker.
|
/// Clones a waker.
|
||||||
unsafe fn clone_waker(ptr: *const ()) -> RawWaker {
|
unsafe fn clone_waker(ptr: *const ()) -> RawWaker {
|
||||||
let raw = Self::from_ptr(ptr);
|
let raw = Self::from_ptr(ptr);
|
||||||
let _guard = (&(*raw.pdata).span).enter();
|
|
||||||
let id = (&(*raw.pdata).span)
|
let id = (&(*raw.pdata).span)
|
||||||
.id()
|
.id()
|
||||||
.map(|id| id.into_u64())
|
.map(|id| id.into_u64())
|
||||||
@ -309,7 +307,6 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn decrement(ptr: *const ()) {
|
unsafe fn decrement(ptr: *const ()) {
|
||||||
let raw = Self::from_ptr(ptr);
|
let raw = Self::from_ptr(ptr);
|
||||||
let _guard = (&(*raw.pdata).span).enter();
|
|
||||||
let id = (&(*raw.pdata).span)
|
let id = (&(*raw.pdata).span)
|
||||||
.id()
|
.id()
|
||||||
.map(|id| id.into_u64())
|
.map(|id| id.into_u64())
|
||||||
@ -383,9 +380,11 @@ where
|
|||||||
/// Ticking will call `poll` once and re-schedule the task if it returns `Poll::Pending`. If
|
/// Ticking will call `poll` once and re-schedule the task if it returns `Poll::Pending`. If
|
||||||
/// polling its future panics, the proc will be closed and the panic propagated into the caller.
|
/// polling its future panics, the proc will be closed and the panic propagated into the caller.
|
||||||
unsafe fn tick(ptr: *const ()) {
|
unsafe fn tick(ptr: *const ()) {
|
||||||
let raw = Self::from_ptr(ptr);
|
let mut raw = Self::from_ptr(ptr);
|
||||||
|
// Enter the span associated with the process to track execution time if enabled.
|
||||||
|
let _guard = (&(*raw.pdata).span).enter();
|
||||||
|
|
||||||
// Create a context from the raw proc pointer and the vtable inside the its pdata.
|
// Create a context from the raw proc pointer and the vtable inside its pdata.
|
||||||
let waker = ManuallyDrop::new(Waker::from_raw(RawWaker::new(
|
let waker = ManuallyDrop::new(Waker::from_raw(RawWaker::new(
|
||||||
ptr,
|
ptr,
|
||||||
&(*raw.pdata).vtable.raw_waker,
|
&(*raw.pdata).vtable.raw_waker,
|
||||||
@ -431,9 +430,9 @@ where
|
|||||||
|
|
||||||
// Poll the inner future, but surround it with a guard that closes the proc in case polling
|
// Poll the inner future, but surround it with a guard that closes the proc in case polling
|
||||||
// panics.
|
// panics.
|
||||||
let guard = Guard(raw);
|
let drop_guard = Guard(&mut raw);
|
||||||
let poll = <F as Future>::poll(Pin::new_unchecked(&mut *raw.future), cx);
|
let poll = <F as Future>::poll(drop_guard.pin_future(), cx);
|
||||||
mem::forget(guard);
|
drop_guard.disable();
|
||||||
|
|
||||||
match poll {
|
match poll {
|
||||||
Poll::Ready(out) => {
|
Poll::Ready(out) => {
|
||||||
@ -548,21 +547,43 @@ impl<'a, F, R, S> Clone for RawProc<'a, F, R, S> {
|
|||||||
}
|
}
|
||||||
impl<'a, F, R, S> Copy for RawProc<'a, F, R, S> {}
|
impl<'a, F, R, S> Copy for RawProc<'a, F, R, S> {}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
/// A guard that closes the proc if polling its future panics.
|
/// A guard that closes the proc if polling its future panics.
|
||||||
struct Guard<'a, F, R, S>(RawProc<'a, F, R, S>)
|
struct Guard<'guard, 'a, F, R, S>(&'guard mut RawProc<'a, F, R, S>)
|
||||||
where
|
where
|
||||||
F: Future<Output = R> + 'a,
|
F: Future<Output = R> + 'a,
|
||||||
R: 'a,
|
R: 'a,
|
||||||
S: Fn(LightProc) + 'a;
|
S: Fn(LightProc) + 'a;
|
||||||
|
|
||||||
impl<'a, F, R, S> Drop for Guard<'a, F, R, S>
|
impl<'guard, 'a, F, R, S> Guard<'guard, 'a, F, R, S>
|
||||||
|
where
|
||||||
|
F: Future<Output = R> + 'a,
|
||||||
|
R: 'a,
|
||||||
|
S: Fn(LightProc) + 'a,
|
||||||
|
{
|
||||||
|
#[inline(always)]
|
||||||
|
/// Disable the guard again.
|
||||||
|
///
|
||||||
|
/// This does essentially nothing but prevents the Drop implementation from being called
|
||||||
|
fn disable(self) {
|
||||||
|
// Put `self` in a ManuallyDrop telling the compiler to explicitly not call Drop::drop
|
||||||
|
let _ = ManuallyDrop::new(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
unsafe fn pin_future(&self) -> Pin<&mut F> {
|
||||||
|
Pin::new_unchecked(&mut *self.0.future)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, F, R, S> Drop for Guard<'_, 'a, F, R, S>
|
||||||
where
|
where
|
||||||
F: Future<Output = R> + 'a,
|
F: Future<Output = R> + 'a,
|
||||||
R: 'a,
|
R: 'a,
|
||||||
S: Fn(LightProc) + 'a,
|
S: Fn(LightProc) + 'a,
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let raw = self.0;
|
let raw = &self.0;
|
||||||
let ptr = raw.pdata as *const ();
|
let ptr = raw.pdata as *const ();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
Loading…
Reference in New Issue
Block a user