Coverage Report

Created: 2026-05-16 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/futures-task-0.3.21/src/waker_ref.rs
Line
Count
Source
1
use super::arc_wake::ArcWake;
2
use super::waker::waker_vtable;
3
use alloc::sync::Arc;
4
use core::marker::PhantomData;
5
use core::mem::ManuallyDrop;
6
use core::ops::Deref;
7
use core::task::{RawWaker, Waker};
8
9
/// A [`Waker`] that is only valid for a given lifetime.
10
///
11
/// Note: this type implements [`Deref<Target = Waker>`](std::ops::Deref),
12
/// so it can be used to get a `&Waker`.
13
#[derive(Debug)]
14
pub struct WakerRef<'a> {
15
    waker: ManuallyDrop<Waker>,
16
    _marker: PhantomData<&'a ()>,
17
}
18
19
impl<'a> WakerRef<'a> {
20
    /// Create a new [`WakerRef`] from a [`Waker`] reference.
21
0
    pub fn new(waker: &'a Waker) -> Self {
22
        // copy the underlying (raw) waker without calling a clone,
23
        // as we won't call Waker::drop either.
24
0
        let waker = ManuallyDrop::new(unsafe { core::ptr::read(waker) });
25
0
        Self { waker, _marker: PhantomData }
26
0
    }
27
28
    /// Create a new [`WakerRef`] from a [`Waker`] that must not be dropped.
29
    ///
30
    /// Note: this if for rare cases where the caller created a [`Waker`] in
31
    /// an unsafe way (that will be valid only for a lifetime to be determined
32
    /// by the caller), and the [`Waker`] doesn't need to or must not be
33
    /// destroyed.
34
355k
    pub fn new_unowned(waker: ManuallyDrop<Waker>) -> Self {
35
355k
        Self { waker, _marker: PhantomData }
36
355k
    }
37
}
38
39
impl Deref for WakerRef<'_> {
40
    type Target = Waker;
41
42
355k
    fn deref(&self) -> &Waker {
43
355k
        &self.waker
44
355k
    }
45
}
46
47
/// Creates a reference to a [`Waker`] from a reference to `Arc<impl ArcWake>`.
48
///
49
/// The resulting [`Waker`] will call
50
/// [`ArcWake.wake()`](ArcWake::wake) if awoken.
51
#[inline]
52
355k
pub fn waker_ref<W>(wake: &Arc<W>) -> WakerRef<'_>
53
355k
where
54
355k
    W: ArcWake,
55
{
56
    // simply copy the pointer instead of using Arc::into_raw,
57
    // as we don't actually keep a refcount by using ManuallyDrop.<
58
355k
    let ptr = Arc::as_ptr(wake).cast::<()>();
59
60
355k
    let waker =
61
355k
        ManuallyDrop::new(unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>())) });
62
355k
    WakerRef::new_unowned(waker)
63
355k
}
futures_task::waker_ref::waker_ref::<futures_util::stream::futures_unordered::task::Task<futures_util::future::future::remote_handle::Remote<devices::virtio::block::asynchronous::handle_queue::{closure#0}>>>
Line
Count
Source
52
248
pub fn waker_ref<W>(wake: &Arc<W>) -> WakerRef<'_>
53
248
where
54
248
    W: ArcWake,
55
{
56
    // simply copy the pointer instead of using Arc::into_raw,
57
    // as we don't actually keep a refcount by using ManuallyDrop.<
58
248
    let ptr = Arc::as_ptr(wake).cast::<()>();
59
60
248
    let waker =
61
248
        ManuallyDrop::new(unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>())) });
62
248
    WakerRef::new_unowned(waker)
63
248
}
Unexecuted instantiation: futures_task::waker_ref::waker_ref::<futures_util::stream::futures_unordered::task::Task<devices::virtio::scsi::device::process_one_chain::{closure#0}>>
futures_task::waker_ref::waker_ref::<futures_util::stream::futures_unordered::task::Task<devices::virtio::block::asynchronous::process_one_chain::{closure#0}>>
Line
Count
Source
52
355k
pub fn waker_ref<W>(wake: &Arc<W>) -> WakerRef<'_>
53
355k
where
54
355k
    W: ArcWake,
55
{
56
    // simply copy the pointer instead of using Arc::into_raw,
57
    // as we don't actually keep a refcount by using ManuallyDrop.<
58
355k
    let ptr = Arc::as_ptr(wake).cast::<()>();
59
60
355k
    let waker =
61
355k
        ManuallyDrop::new(unsafe { Waker::from_raw(RawWaker::new(ptr, waker_vtable::<W>())) });
62
355k
    WakerRef::new_unowned(waker)
63
355k
}
Unexecuted instantiation: futures_task::waker_ref::waker_ref::<cros_async::blocking::sys::linux::block_on::Waker>
Unexecuted instantiation: futures_task::waker_ref::waker_ref::<futures_util::stream::futures_unordered::task::Task<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = ()> + core::marker::Send>>>>
Unexecuted instantiation: futures_task::waker_ref::waker_ref::<futures_util::stream::futures_unordered::task::Task<futures_task::future_obj::LocalFutureObj<()>>>
Unexecuted instantiation: futures_task::waker_ref::waker_ref::<futures_executor::local_pool::ThreadNotify>
Unexecuted instantiation: futures_task::waker_ref::waker_ref::<_>