15
15
fmt,
16
16
future:: Future ,
17
17
iter,
18
- mem:: { self , ManuallyDrop , MaybeUninit } ,
18
+ mem:: { self , MaybeUninit } ,
19
19
pin:: Pin ,
20
+ sync:: atomic:: { AtomicU32 , Ordering :: Relaxed } ,
20
21
task:: { Context , Poll } ,
21
22
vec:: Vec ,
22
23
} ,
@@ -28,7 +29,7 @@ fn ceiling(x: usize, y: usize) -> usize {
28
29
29
30
#[ doc( hidden) ]
30
31
pub struct StreamVtable < T > {
31
- pub write : fn ( future : u32 , values : & [ T ] ) -> Pin < Box < dyn Future < Output = Option < usize > > + ' _ > > ,
32
+ pub write : fn ( future : u32 , values : & [ T ] ) -> Pin < Box < dyn Future < Output = usize > + ' _ > > ,
32
33
pub read : fn (
33
34
future : u32 ,
34
35
values : & mut [ MaybeUninit < T > ] ,
@@ -173,14 +174,7 @@ impl<T> Sink<Vec<T>> for StreamWriter<T> {
173
174
vtable,
174
175
} ;
175
176
self . get_mut ( ) . future = Some ( Box :: pin ( async move {
176
- let mut offset = 0 ;
177
- while offset < item. len ( ) {
178
- if let Some ( count) = ( vtable. write ) ( handle, & item[ offset..] ) . await {
179
- offset += count;
180
- } else {
181
- break ;
182
- }
183
- }
177
+ ( vtable. write ) ( handle, & item) . await ;
184
178
cancel_on_drop. handle = None ;
185
179
drop ( cancel_on_drop) ;
186
180
} ) ) ;
@@ -246,7 +240,7 @@ impl<T> Drop for CancelReadOnDrop<T> {
246
240
247
241
/// Represents the readable end of a Component Model `stream`.
248
242
pub struct StreamReader < T : ' static > {
249
- handle : u32 ,
243
+ handle : AtomicU32 ,
250
244
future : Option < Pin < Box < dyn Future < Output = Option < Vec < T > > > + ' static > > > ,
251
245
vtable : & ' static StreamVtable < T > ,
252
246
}
@@ -273,7 +267,7 @@ impl<T> StreamReader<T> {
273
267
#[ doc( hidden) ]
274
268
pub fn new ( handle : u32 , vtable : & ' static StreamVtable < T > ) -> Self {
275
269
Self {
276
- handle,
270
+ handle : AtomicU32 :: new ( handle ) ,
277
271
future : None ,
278
272
vtable,
279
273
}
@@ -300,15 +294,16 @@ impl<T> StreamReader<T> {
300
294
} ) ;
301
295
302
296
Self {
303
- handle,
297
+ handle : AtomicU32 :: new ( handle ) ,
304
298
future : None ,
305
299
vtable,
306
300
}
307
301
}
308
302
309
303
#[ doc( hidden) ]
310
- pub fn into_handle ( self ) -> u32 {
311
- super :: with_entry ( self . handle , |entry| match entry {
304
+ pub fn take_handle ( & self ) -> u32 {
305
+ let handle = self . handle . swap ( u32:: MAX , Relaxed ) ;
306
+ super :: with_entry ( handle, |entry| match entry {
312
307
Entry :: Vacant ( _) => unreachable ! ( ) ,
313
308
Entry :: Occupied ( mut entry) => match entry. get ( ) {
314
309
Handle :: LocalOpen => {
@@ -321,7 +316,7 @@ impl<T> StreamReader<T> {
321
316
} ,
322
317
} ) ;
323
318
324
- ManuallyDrop :: new ( self ) . handle
319
+ handle
325
320
}
326
321
}
327
322
@@ -332,60 +327,65 @@ impl<T> Stream for StreamReader<T> {
332
327
let me = self . get_mut ( ) ;
333
328
334
329
if me. future . is_none ( ) {
335
- me. future = Some ( super :: with_entry ( me. handle , |entry| match entry {
336
- Entry :: Vacant ( _) => unreachable ! ( ) ,
337
- Entry :: Occupied ( mut entry) => match entry. get ( ) {
338
- Handle :: Write | Handle :: LocalWaiting ( _) => unreachable ! ( ) ,
339
- Handle :: Read => {
340
- let handle = me. handle ;
341
- let vtable = me. vtable ;
342
- let mut cancel_on_drop = CancelReadOnDrop :: < T > {
343
- handle : Some ( handle) ,
344
- vtable,
345
- } ;
346
- Box :: pin ( async move {
347
- let mut buffer = iter:: repeat_with ( MaybeUninit :: uninit)
348
- . take ( ceiling ( 64 * 1024 , mem:: size_of :: < T > ( ) ) )
349
- . collect :: < Vec < _ > > ( ) ;
350
-
351
- let result =
352
- if let Some ( count) = ( vtable. read ) ( handle, & mut buffer) . await {
353
- buffer. truncate ( count) ;
354
- Some ( unsafe {
355
- mem:: transmute :: < Vec < MaybeUninit < T > > , Vec < T > > ( buffer)
356
- } )
357
- } else {
358
- None
359
- } ;
360
- cancel_on_drop. handle = None ;
361
- drop ( cancel_on_drop) ;
362
- result
363
- } ) as Pin < Box < dyn Future < Output = _ > > >
364
- }
365
- Handle :: LocalOpen => {
366
- let ( tx, rx) = oneshot:: channel ( ) ;
367
- entry. insert ( Handle :: LocalWaiting ( tx) ) ;
368
- let mut cancel_on_drop = CancelReadOnDrop :: < T > {
369
- handle : Some ( me. handle ) ,
370
- vtable : me. vtable ,
371
- } ;
372
- Box :: pin ( async move {
373
- let result = rx. map ( |v| v. ok ( ) . map ( |v| * v. downcast ( ) . unwrap ( ) ) ) . await ;
374
- cancel_on_drop. handle = None ;
375
- drop ( cancel_on_drop) ;
376
- result
377
- } )
378
- }
379
- Handle :: LocalClosed => Box :: pin ( future:: ready ( None ) ) ,
380
- Handle :: LocalReady ( ..) => {
381
- let Handle :: LocalReady ( v, waker) = entry. insert ( Handle :: LocalOpen ) else {
382
- unreachable ! ( )
383
- } ;
384
- waker. wake ( ) ;
385
- Box :: pin ( future:: ready ( Some ( * v. downcast ( ) . unwrap ( ) ) ) )
386
- }
330
+ me. future = Some ( super :: with_entry (
331
+ me. handle . load ( Relaxed ) ,
332
+ |entry| match entry {
333
+ Entry :: Vacant ( _) => unreachable ! ( ) ,
334
+ Entry :: Occupied ( mut entry) => match entry. get ( ) {
335
+ Handle :: Write | Handle :: LocalWaiting ( _) => unreachable ! ( ) ,
336
+ Handle :: Read => {
337
+ let handle = me. handle . load ( Relaxed ) ;
338
+ let vtable = me. vtable ;
339
+ let mut cancel_on_drop = CancelReadOnDrop :: < T > {
340
+ handle : Some ( handle) ,
341
+ vtable,
342
+ } ;
343
+ Box :: pin ( async move {
344
+ let mut buffer = iter:: repeat_with ( MaybeUninit :: uninit)
345
+ . take ( ceiling ( 64 * 1024 , mem:: size_of :: < T > ( ) ) )
346
+ . collect :: < Vec < _ > > ( ) ;
347
+
348
+ let result =
349
+ if let Some ( count) = ( vtable. read ) ( handle, & mut buffer) . await {
350
+ buffer. truncate ( count) ;
351
+ Some ( unsafe {
352
+ mem:: transmute :: < Vec < MaybeUninit < T > > , Vec < T > > ( buffer)
353
+ } )
354
+ } else {
355
+ None
356
+ } ;
357
+ cancel_on_drop. handle = None ;
358
+ drop ( cancel_on_drop) ;
359
+ result
360
+ } ) as Pin < Box < dyn Future < Output = _ > > >
361
+ }
362
+ Handle :: LocalOpen => {
363
+ let ( tx, rx) = oneshot:: channel ( ) ;
364
+ entry. insert ( Handle :: LocalWaiting ( tx) ) ;
365
+ let mut cancel_on_drop = CancelReadOnDrop :: < T > {
366
+ handle : Some ( me. handle . load ( Relaxed ) ) ,
367
+ vtable : me. vtable ,
368
+ } ;
369
+ Box :: pin ( async move {
370
+ let result =
371
+ rx. map ( |v| v. ok ( ) . map ( |v| * v. downcast ( ) . unwrap ( ) ) ) . await ;
372
+ cancel_on_drop. handle = None ;
373
+ drop ( cancel_on_drop) ;
374
+ result
375
+ } )
376
+ }
377
+ Handle :: LocalClosed => Box :: pin ( future:: ready ( None ) ) ,
378
+ Handle :: LocalReady ( ..) => {
379
+ let Handle :: LocalReady ( v, waker) = entry. insert ( Handle :: LocalOpen )
380
+ else {
381
+ unreachable ! ( )
382
+ } ;
383
+ waker. wake ( ) ;
384
+ Box :: pin ( future:: ready ( Some ( * v. downcast ( ) . unwrap ( ) ) ) )
385
+ }
386
+ } ,
387
387
} ,
388
- } ) ) ;
388
+ ) ) ;
389
389
}
390
390
391
391
match me. future . as_mut ( ) . unwrap ( ) . as_mut ( ) . poll ( cx) {
@@ -402,24 +402,30 @@ impl<T> Drop for StreamReader<T> {
402
402
fn drop ( & mut self ) {
403
403
self . future = None ;
404
404
405
- super :: with_entry ( self . handle , |entry| match entry {
406
- Entry :: Vacant ( _) => unreachable ! ( ) ,
407
- Entry :: Occupied ( mut entry) => match entry. get_mut ( ) {
408
- Handle :: LocalReady ( ..) => {
409
- let Handle :: LocalReady ( _, waker) = entry. insert ( Handle :: LocalClosed ) else {
410
- unreachable ! ( )
411
- } ;
412
- waker. wake ( ) ;
413
- }
414
- Handle :: LocalOpen | Handle :: LocalWaiting ( _) => {
415
- entry. insert ( Handle :: LocalClosed ) ;
416
- }
417
- Handle :: Read | Handle :: LocalClosed => {
418
- entry. remove ( ) ;
419
- ( self . vtable . close_readable ) ( self . handle ) ;
420
- }
421
- Handle :: Write => unreachable ! ( ) ,
422
- } ,
423
- } ) ;
405
+ match self . handle . load ( Relaxed ) {
406
+ u32:: MAX => { }
407
+ handle => {
408
+ super :: with_entry ( handle, |entry| match entry {
409
+ Entry :: Vacant ( _) => unreachable ! ( ) ,
410
+ Entry :: Occupied ( mut entry) => match entry. get_mut ( ) {
411
+ Handle :: LocalReady ( ..) => {
412
+ let Handle :: LocalReady ( _, waker) = entry. insert ( Handle :: LocalClosed )
413
+ else {
414
+ unreachable ! ( )
415
+ } ;
416
+ waker. wake ( ) ;
417
+ }
418
+ Handle :: LocalOpen | Handle :: LocalWaiting ( _) => {
419
+ entry. insert ( Handle :: LocalClosed ) ;
420
+ }
421
+ Handle :: Read | Handle :: LocalClosed => {
422
+ entry. remove ( ) ;
423
+ ( self . vtable . close_readable ) ( handle) ;
424
+ }
425
+ Handle :: Write => unreachable ! ( ) ,
426
+ } ,
427
+ } ) ;
428
+ }
429
+ }
424
430
}
425
431
}
0 commit comments