Skip to content
/ rust Public
forked from rust-lang/rust

Commit c6ac3b0

Browse files
committed
Add Context::ext
1 parent 10a7aa1 commit c6ac3b0

File tree

1 file changed

+52
-3
lines changed

1 file changed

+52
-3
lines changed

library/core/src/task/wake.rs

+52-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use crate::mem::transmute;
44

5+
use crate::any::Any;
56
use crate::fmt;
67
use crate::marker::PhantomData;
78
use crate::ptr;
@@ -220,6 +221,12 @@ impl RawWakerVTable {
220221
}
221222
}
222223

224+
#[derive(Debug)]
225+
enum ExtData<'a> {
226+
Some(&'a mut dyn Any),
227+
None(()),
228+
}
229+
223230
/// The context of an asynchronous task.
224231
///
225232
/// Currently, `Context` only serves to provide access to a [`&Waker`](Waker)
@@ -229,6 +236,7 @@ impl RawWakerVTable {
229236
pub struct Context<'a> {
230237
waker: &'a Waker,
231238
local_waker: &'a LocalWaker,
239+
ext: ExtData<'a>,
232240
// Ensure we future-proof against variance changes by forcing
233241
// the lifetime to be invariant (argument-position lifetimes
234242
// are contravariant while return-position lifetimes are
@@ -257,13 +265,25 @@ impl<'a> Context<'a> {
257265
pub const fn waker(&self) -> &'a Waker {
258266
&self.waker
259267
}
268+
260269
/// Returns a reference to the [`LocalWaker`] for the current task.
261270
#[inline]
262271
#[unstable(feature = "local_waker", issue = "118959")]
263272
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
264273
pub const fn local_waker(&self) -> &'a LocalWaker {
265274
&self.local_waker
266275
}
276+
277+
/// Returns a reference to the extension data for the current task.
278+
#[inline]
279+
#[unstable(feature = "context_ext", issue = "none")]
280+
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
281+
pub const fn ext(&mut self) -> &mut dyn Any {
282+
match &mut self.ext {
283+
ExtData::Some(data) => *data,
284+
ExtData::None(unit) => unit,
285+
}
286+
}
267287
}
268288

269289
#[stable(feature = "futures_api", since = "1.36.0")]
@@ -300,6 +320,7 @@ impl fmt::Debug for Context<'_> {
300320
pub struct ContextBuilder<'a> {
301321
waker: &'a Waker,
302322
local_waker: &'a LocalWaker,
323+
ext: ExtData<'a>,
303324
// Ensure we future-proof against variance changes by forcing
304325
// the lifetime to be invariant (argument-position lifetimes
305326
// are contravariant while return-position lifetimes are
@@ -318,7 +339,27 @@ impl<'a> ContextBuilder<'a> {
318339
pub const fn from_waker(waker: &'a Waker) -> Self {
319340
// SAFETY: LocalWaker is just Waker without thread safety
320341
let local_waker = unsafe { transmute(waker) };
321-
Self { waker: waker, local_waker, _marker: PhantomData, _marker2: PhantomData }
342+
Self { waker: waker, local_waker, ext: ExtData::None(()), _marker: PhantomData, _marker2: PhantomData }
343+
}
344+
345+
/// Create a ContextBuilder from an existing Context.
346+
#[inline]
347+
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
348+
#[unstable(feature = "context_ext", issue = "none")]
349+
pub const fn from(cx: &'a mut Context<'_>) -> Self {
350+
let ext = match &mut cx.ext {
351+
ExtData::Some(ext) => ExtData::Some(*ext),
352+
ExtData::None(()) => ExtData::None(()),
353+
};
354+
Self { waker: cx.waker, local_waker: cx.local_waker, ext, _marker: PhantomData, _marker2: PhantomData }
355+
}
356+
357+
/// This method is used to set the value for the waker on `Context`.
358+
#[inline]
359+
#[unstable(feature = "context_ext", issue = "none")]
360+
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
361+
pub const fn waker(self, waker: &'a Waker) -> Self {
362+
Self { waker, ..self }
322363
}
323364

324365
/// This method is used to set the value for the local waker on `Context`.
@@ -329,13 +370,21 @@ impl<'a> ContextBuilder<'a> {
329370
Self { local_waker, ..self }
330371
}
331372

373+
/// This method is used to set the value for the extension data on `Context`.
374+
#[inline]
375+
#[unstable(feature = "context_ext", issue = "none")]
376+
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
377+
pub const fn ext(self, data: &'a mut dyn Any) -> Self {
378+
Self { ext: ExtData::Some(data), ..self }
379+
}
380+
332381
/// Builds the `Context`.
333382
#[inline]
334383
#[unstable(feature = "local_waker", issue = "118959")]
335384
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
336385
pub const fn build(self) -> Context<'a> {
337-
let ContextBuilder { waker, local_waker, _marker, _marker2 } = self;
338-
Context { waker, local_waker, _marker, _marker2 }
386+
let ContextBuilder { waker, local_waker, ext, _marker, _marker2 } = self;
387+
Context { waker, local_waker, ext, _marker, _marker2 }
339388
}
340389
}
341390

0 commit comments

Comments
 (0)