22
33use crate :: mem:: transmute;
44
5+ use crate :: any:: Any ;
56use crate :: fmt;
67use crate :: marker:: PhantomData ;
78use 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 {
229236pub 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<'_> {
300320pub 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