From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/futures-task/src/waker.rs | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 vendor/futures-task/src/waker.rs (limited to 'vendor/futures-task/src/waker.rs') diff --git a/vendor/futures-task/src/waker.rs b/vendor/futures-task/src/waker.rs new file mode 100644 index 000000000..a7310a07a --- /dev/null +++ b/vendor/futures-task/src/waker.rs @@ -0,0 +1,59 @@ +use super::arc_wake::ArcWake; +use alloc::sync::Arc; +use core::mem; +use core::task::{RawWaker, RawWakerVTable, Waker}; + +pub(super) fn waker_vtable() -> &'static RawWakerVTable { + &RawWakerVTable::new( + clone_arc_raw::, + wake_arc_raw::, + wake_by_ref_arc_raw::, + drop_arc_raw::, + ) +} + +/// Creates a [`Waker`] from an `Arc`. +/// +/// The returned [`Waker`] will call +/// [`ArcWake.wake()`](ArcWake::wake) if awoken. +pub fn waker(wake: Arc) -> Waker +where + W: ArcWake + 'static, +{ + let ptr = Arc::into_raw(wake) as *const (); + + unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::())) } +} + +// FIXME: panics on Arc::clone / refcount changes could wreak havoc on the +// code here. We should guard against this by aborting. + +#[allow(clippy::redundant_clone)] // The clone here isn't actually redundant. +unsafe fn increase_refcount(data: *const ()) { + // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop + let arc = mem::ManuallyDrop::new(Arc::::from_raw(data as *const T)); + // Now increase refcount, but don't drop new refcount either + let _arc_clone: mem::ManuallyDrop<_> = arc.clone(); +} + +// used by `waker_ref` +unsafe fn clone_arc_raw(data: *const ()) -> RawWaker { + increase_refcount::(data); + RawWaker::new(data, waker_vtable::()) +} + +unsafe fn wake_arc_raw(data: *const ()) { + let arc: Arc = Arc::from_raw(data as *const T); + ArcWake::wake(arc); +} + +// used by `waker_ref` +unsafe fn wake_by_ref_arc_raw(data: *const ()) { + // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop + let arc = mem::ManuallyDrop::new(Arc::::from_raw(data as *const T)); + ArcWake::wake_by_ref(&arc); +} + +unsafe fn drop_arc_raw(data: *const ()) { + drop(Arc::::from_raw(data as *const T)) +} -- cgit v1.2.3