2
2
3
3
use crate :: mem:: transmute;
4
4
5
+ use crate :: any:: Any ;
5
6
use crate :: fmt;
6
7
use crate :: marker:: PhantomData ;
7
8
use crate :: ptr;
@@ -220,6 +221,12 @@ impl RawWakerVTable {
220
221
}
221
222
}
222
223
224
+ #[ derive( Debug ) ]
225
+ enum ExtData < ' a > {
226
+ Some ( & ' a mut dyn Any ) ,
227
+ None ( ( ) ) ,
228
+ }
229
+
223
230
/// The context of an asynchronous task.
224
231
///
225
232
/// Currently, `Context` only serves to provide access to a [`&Waker`](Waker)
@@ -229,6 +236,7 @@ impl RawWakerVTable {
229
236
pub struct Context < ' a > {
230
237
waker : & ' a Waker ,
231
238
local_waker : & ' a LocalWaker ,
239
+ ext : ExtData < ' a > ,
232
240
// Ensure we future-proof against variance changes by forcing
233
241
// the lifetime to be invariant (argument-position lifetimes
234
242
// are contravariant while return-position lifetimes are
@@ -257,13 +265,25 @@ impl<'a> Context<'a> {
257
265
pub const fn waker ( & self ) -> & ' a Waker {
258
266
& self . waker
259
267
}
268
+
260
269
/// Returns a reference to the [`LocalWaker`] for the current task.
261
270
#[ inline]
262
271
#[ unstable( feature = "local_waker" , issue = "118959" ) ]
263
272
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
264
273
pub const fn local_waker ( & self ) -> & ' a LocalWaker {
265
274
& self . local_waker
266
275
}
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
+ }
267
287
}
268
288
269
289
#[ stable( feature = "futures_api" , since = "1.36.0" ) ]
@@ -300,6 +320,7 @@ impl fmt::Debug for Context<'_> {
300
320
pub struct ContextBuilder < ' a > {
301
321
waker : & ' a Waker ,
302
322
local_waker : & ' a LocalWaker ,
323
+ ext : ExtData < ' a > ,
303
324
// Ensure we future-proof against variance changes by forcing
304
325
// the lifetime to be invariant (argument-position lifetimes
305
326
// are contravariant while return-position lifetimes are
@@ -318,7 +339,27 @@ impl<'a> ContextBuilder<'a> {
318
339
pub const fn from_waker ( waker : & ' a Waker ) -> Self {
319
340
// SAFETY: LocalWaker is just Waker without thread safety
320
341
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 }
322
363
}
323
364
324
365
/// This method is used to set the value for the local waker on `Context`.
@@ -329,13 +370,21 @@ impl<'a> ContextBuilder<'a> {
329
370
Self { local_waker, ..self }
330
371
}
331
372
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
+
332
381
/// Builds the `Context`.
333
382
#[ inline]
334
383
#[ unstable( feature = "local_waker" , issue = "118959" ) ]
335
384
#[ rustc_const_unstable( feature = "const_waker" , issue = "102012" ) ]
336
385
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 }
339
388
}
340
389
}
341
390
0 commit comments