Skip to content

Commit 77ba34a

Browse files
authored
Rollup merge of rust-lang#149976 - waker-fn, r=jhpratt
Add waker_fn and local_waker_fn to std::task This refers to rust-lang#149580.
2 parents 548e586 + 6346d14 commit 77ba34a

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

library/alloc/src/task.rs

Lines changed: 77 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,45 @@ 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 = "local_waker", issue = "118959")]
364+
#[unstable(feature = "waker_fn", issue = "149580")]
365+
pub fn local_waker_fn<F: Fn() + Send + Sync + 'static>(f: F) -> LocalWaker {
366+
struct LocalWakeFn<F> {
367+
f: F,
368+
}
369+
370+
impl<F> LocalWake for LocalWakeFn<F>
371+
where
372+
F: Fn(),
373+
{
374+
fn wake(self: Rc<Self>) {
375+
(self.f)()
376+
}
377+
378+
fn wake_by_ref(self: &Rc<Self>) {
379+
(self.f)()
380+
}
381+
}
382+
383+
LocalWaker::from(Rc::new(LocalWakeFn { f }))
384+
}
385+
309386
// NB: This private function for constructing a RawWaker is used, rather than
310387
// inlining this into the `From<Rc<W>> for RawWaker` impl, to ensure that
311388
// the safety of `From<Rc<W>> for Waker` does not depend on the correct

0 commit comments

Comments
 (0)