@@ -225,21 +225,32 @@ impl<'a> Context<'a> {
225
225
/// # Panics
226
226
/// This function will panic if no `Waker` was set on the context. This happens if
227
227
/// the executor does not support working with thread safe wakers. An alternative
228
- /// may be to call [`.local_waker()`](Context::local_waker) instead.
228
+ /// may be to call [`.local_waker()`](Context::local_waker) instead. For a fallible
229
+ /// version of this function see [`.try_waker()`](Context::try_waker).
230
+ #[ inline]
231
+ #[ must_use]
229
232
#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
230
233
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
231
- #[ must_use]
232
- #[ inline]
233
234
pub const fn waker ( & self ) -> & ' a Waker {
234
235
& self
235
236
. waker
236
237
. expect ( "no waker was set on this context, consider calling `local_waker` instead." )
237
238
}
238
239
/// Returns a reference to the [`LocalWaker`] for the current task.
240
+ #[ inline]
239
241
#[ unstable( feature = "local_waker" , issue = "none" ) ]
240
- pub fn local_waker ( & self ) -> & ' a LocalWaker {
242
+ #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
243
+ pub const fn local_waker ( & self ) -> & ' a LocalWaker {
241
244
& self . local_waker
242
245
}
246
+ /// Returns a `Some(&Waker)` if a waker was defined on the `Context`,
247
+ /// otherwise it returns `None`.
248
+ #[ inline]
249
+ #[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
250
+ #[ unstable( feature = "local_waker" , issue = "none" ) ]
251
+ pub const fn try_waker ( & self ) -> Option < & ' a Waker > {
252
+ self . waker
253
+ }
243
254
}
244
255
245
256
#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
@@ -256,18 +267,19 @@ impl fmt::Debug for Context<'_> {
256
267
/// ```
257
268
/// #![feature(local_waker)]
258
269
/// #![feature(noop_waker)]
259
- /// use std::task::{ContextBuilder, LocalWaker, Waker};
260
- ///
270
+ /// use std::task::{ContextBuilder, LocalWaker, Waker, Poll};
271
+ /// use std::future::Future;
272
+ ///
261
273
/// let local_waker = LocalWaker::noop();
262
274
/// let waker = Waker::noop();
263
275
///
264
- /// let context = ContextBuilder::from_local_waker(&local_waker)
276
+ /// let mut cx = ContextBuilder::from_local_waker(&local_waker)
265
277
/// .waker(&waker)
266
278
/// .build();
267
279
///
268
- /// let future = pin::pin!(async { 20 });
269
- /// let poll = future.poll(&mut context );
270
- /// assert_eq!(poll, task:: Poll::Ready(20));
280
+ /// let mut future = std:: pin::pin!(async { 20 });
281
+ /// let poll = future.as_mut(). poll(&mut cx );
282
+ /// assert_eq!(poll, Poll::Ready(20));
271
283
///
272
284
/// ```
273
285
#[ unstable( feature = "local_waker" , issue = "none" ) ]
@@ -323,6 +335,50 @@ impl<'a> ContextBuilder<'a> {
323
335
}
324
336
}
325
337
338
+ /// Construct a `ContextBuilder`` from a `Context`. This is useful for
339
+ /// overriding values from a context.
340
+ ///
341
+ /// # Examples
342
+ /// An example of a future that allows to set a Waker on Context if none was defined.
343
+ /// This can be used to await futures that require a `Waker` even if the runtime does not
344
+ /// support `Waker`.
345
+ /// ```rust
346
+ /// #![feature(noop_waker, local_waker)]
347
+ /// use std::task::{Waker, ContextBuilder};
348
+ /// use std::future::{poll_fn, Future};
349
+ /// use std::pin::pin;
350
+ ///
351
+ /// async fn with_waker<F>(f: F, waker: &Waker) -> F::Output
352
+ /// where
353
+ /// F: Future
354
+ /// {
355
+ /// let mut f = pin!(f);
356
+ /// poll_fn(move |cx| {
357
+ /// let has_waker = cx.try_waker().is_some();
358
+ /// if has_waker {
359
+ /// return f.as_mut().poll(cx);
360
+ /// }
361
+ ///
362
+ /// let mut cx = ContextBuilder::from(cx)
363
+ /// .waker(&waker)
364
+ /// .build();
365
+ /// f.as_mut().poll(&mut cx)
366
+ /// }).await
367
+ /// }
368
+ ///
369
+ /// # async fn __() {
370
+ /// with_waker(async { /* ... */ }, &Waker::noop()).await;
371
+ /// # }
372
+ /// ```
373
+ #[ unstable( feature = "local_waker" , issue = "none" ) ]
374
+ impl < ' a > From < & mut Context < ' a > > for ContextBuilder < ' a > {
375
+ #[ inline]
376
+ fn from ( value : & mut Context < ' a > ) -> Self {
377
+ let Context { waker, local_waker, .. } = * value;
378
+ ContextBuilder { waker, local_waker }
379
+ }
380
+ }
381
+
326
382
/// A `Waker` is a handle for waking up a task by notifying its executor that it
327
383
/// is ready to be run.
328
384
///
@@ -559,12 +615,11 @@ impl fmt::Debug for Waker {
559
615
/// })
560
616
/// }
561
617
///
562
- /// # #[allow(unused_must_use)]
563
618
/// # async fn __() {
564
619
/// yield_now().await;
565
620
/// # }
566
621
/// ```
567
- ///
622
+ ///
568
623
/// [`Future::poll()`]: core::future::Future::poll
569
624
/// [`Poll::Pending`]: core::task::Poll::Pending
570
625
/// [`local_waker`]: core::task::Context::local_waker
0 commit comments