Skip to content

Commit cd39f5a

Browse files
committed
Add waker_fn and local_waker_fn to std::task
Signed-off-by: tison <[email protected]>
1 parent 2cd4ee6 commit cd39f5a

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

library/alloc/src/task.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,44 @@ impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
127127
}
128128
}
129129

130+
/// Converts a closure into a [`Waker`].
131+
///
132+
/// The closure gets called every time the waker is woken.
133+
///
134+
/// # Examples
135+
///
136+
/// ```
137+
/// #![feature(waker_fn)]
138+
/// use std::task::waker_fn;
139+
///
140+
/// let waker = waker_fn(|| println!("woken"));
141+
///
142+
/// waker.wake_by_ref(); // Prints "woken".
143+
/// waker.wake(); // Prints "woken".
144+
/// ```
145+
#[cfg(target_has_atomic = "ptr")]
146+
#[unstable(feature = "waker_fn", issue = "149580")]
147+
pub fn waker_fn<F: Fn() + Send + Sync + 'static>(f: F) -> Waker {
148+
struct WakeFn<F> {
149+
f: F,
150+
}
151+
152+
impl<F> Wake for WakeFn<F>
153+
where
154+
F: Fn(),
155+
{
156+
fn wake(self: Arc<Self>) {
157+
(self.f)()
158+
}
159+
160+
fn wake_by_ref(self: &Arc<Self>) {
161+
(self.f)()
162+
}
163+
}
164+
165+
Waker::from(Arc::new(WakeFn { f }))
166+
}
167+
130168
// NB: This private function for constructing a RawWaker is used, rather than
131169
// inlining this into the `From<Arc<W>> for RawWaker` impl, to ensure that
132170
// the safety of `From<Arc<W>> for Waker` does not depend on the correct
@@ -306,6 +344,44 @@ impl<W: LocalWake + 'static> From<Rc<W>> for RawWaker {
306344
}
307345
}
308346

347+
/// Converts a closure into a [`LocalWaker`].
348+
///
349+
/// The closure gets called every time the local waker is woken.
350+
///
351+
/// # Examples
352+
///
353+
/// ```
354+
/// #![feature(local_waker)]
355+
/// #![feature(waker_fn)]
356+
/// use std::task::local_waker_fn;
357+
///
358+
/// let waker = local_waker_fn(|| println!("woken"));
359+
///
360+
/// waker.wake_by_ref(); // Prints "woken".
361+
/// waker.wake(); // Prints "woken".
362+
/// ```
363+
#[unstable(feature = "waker_fn", issue = "149580")]
364+
pub fn local_waker_fn<F: Fn() + Send + Sync + 'static>(f: F) -> LocalWaker {
365+
struct LocalWakeFn<F> {
366+
f: F,
367+
}
368+
369+
impl<F> LocalWake for LocalWakeFn<F>
370+
where
371+
F: Fn(),
372+
{
373+
fn wake(self: Rc<Self>) {
374+
(self.f)()
375+
}
376+
377+
fn wake_by_ref(self: &Rc<Self>) {
378+
(self.f)()
379+
}
380+
}
381+
382+
LocalWaker::from(Rc::new(LocalWakeFn { f }))
383+
}
384+
309385
// NB: This private function for constructing a RawWaker is used, rather than
310386
// inlining this into the `From<Rc<W>> for RawWaker` impl, to ensure that
311387
// the safety of `From<Rc<W>> for Waker` does not depend on the correct

0 commit comments

Comments
 (0)