2
2
//! module documentation in `future_support.rs`.
3
3
4
4
use crate :: async_support:: waitable:: { WaitableOp , WaitableOperation } ;
5
- use crate :: async_support:: { AbiBuffer , ReturnCode } ;
5
+ use crate :: async_support:: { AbiBuffer , ReturnCode , DROPPED } ;
6
6
use {
7
7
crate :: Cleanup ,
8
8
std:: {
@@ -85,12 +85,17 @@ pub unsafe fn stream_new<T>(
85
85
pub struct StreamWriter < T : ' static > {
86
86
handle : u32 ,
87
87
vtable : & ' static StreamVtable < T > ,
88
+ done : bool ,
88
89
}
89
90
90
91
impl < T > StreamWriter < T > {
91
92
#[ doc( hidden) ]
92
93
pub unsafe fn new ( handle : u32 , vtable : & ' static StreamVtable < T > ) -> Self {
93
- Self { handle, vtable }
94
+ Self {
95
+ handle,
96
+ vtable,
97
+ done : false ,
98
+ }
94
99
}
95
100
96
101
/// Initiate a write of the `values` provided into this stream.
@@ -239,6 +244,10 @@ where
239
244
type Cancel = ( StreamResult , AbiBuffer < T > ) ;
240
245
241
246
fn start ( ( writer, buf) : Self :: Start ) -> ( u32 , Self :: InProgress ) {
247
+ if writer. done {
248
+ return ( DROPPED , ( writer, buf) ) ;
249
+ }
250
+
242
251
let ( ptr, len) = buf. abi_ptr_and_len ( ) ;
243
252
// SAFETY: sure hope this is safe, everything in this module and
244
253
// `AbiBuffer` is trying to make this safe.
@@ -262,9 +271,14 @@ where
262
271
ReturnCode :: Blocked => Err ( ( writer, buf) ) ,
263
272
ReturnCode :: Dropped ( 0 ) => Ok ( ( StreamResult :: Dropped , buf) ) ,
264
273
ReturnCode :: Cancelled ( 0 ) => Ok ( ( StreamResult :: Cancelled , buf) ) ,
265
- ReturnCode :: Completed ( amt) | ReturnCode :: Dropped ( amt) | ReturnCode :: Cancelled ( amt) => {
274
+ code @ ( ReturnCode :: Completed ( amt)
275
+ | ReturnCode :: Dropped ( amt)
276
+ | ReturnCode :: Cancelled ( amt) ) => {
266
277
let amt = amt. try_into ( ) . unwrap ( ) ;
267
278
buf. advance ( amt) ;
279
+ if let ReturnCode :: Dropped ( _) = code {
280
+ writer. done = true ;
281
+ }
268
282
Ok ( ( StreamResult :: Complete ( amt) , buf) )
269
283
}
270
284
}
@@ -321,6 +335,7 @@ impl<'a, T: 'static> StreamWrite<'a, T> {
321
335
pub struct StreamReader < T : ' static > {
322
336
handle : AtomicU32 ,
323
337
vtable : & ' static StreamVtable < T > ,
338
+ done : bool ,
324
339
}
325
340
326
341
impl < T > fmt:: Debug for StreamReader < T > {
@@ -337,6 +352,7 @@ impl<T> StreamReader<T> {
337
352
Self {
338
353
handle : AtomicU32 :: new ( handle) ,
339
354
vtable,
355
+ done : false ,
340
356
}
341
357
}
342
358
@@ -444,6 +460,10 @@ where
444
460
type Cancel = ( StreamResult , Vec < T > ) ;
445
461
446
462
fn start ( ( reader, mut buf) : Self :: Start ) -> ( u32 , Self :: InProgress ) {
463
+ if reader. done {
464
+ return ( DROPPED , ( reader, buf, None ) ) ;
465
+ }
466
+
447
467
let cap = buf. spare_capacity_mut ( ) ;
448
468
let ptr;
449
469
let cleanup;
@@ -493,7 +513,9 @@ where
493
513
// the read allocation?
494
514
ReturnCode :: Cancelled ( 0 ) => Ok ( ( StreamResult :: Cancelled , buf) ) ,
495
515
496
- ReturnCode :: Completed ( amt) | ReturnCode :: Dropped ( amt) | ReturnCode :: Cancelled ( amt) => {
516
+ code @ ( ReturnCode :: Completed ( amt)
517
+ | ReturnCode :: Dropped ( amt)
518
+ | ReturnCode :: Cancelled ( amt) ) => {
497
519
let amt = usize:: try_from ( amt) . unwrap ( ) ;
498
520
let cur_len = buf. len ( ) ;
499
521
assert ! ( amt <= buf. capacity( ) - cur_len) ;
@@ -523,6 +545,9 @@ where
523
545
// Intentionally dispose of `cleanup` here as, if it was used, all
524
546
// allocations have been read from it and appended to `buf`.
525
547
drop ( cleanup) ;
548
+ if let ReturnCode :: Dropped ( _) = code {
549
+ reader. done = true ;
550
+ }
526
551
Ok ( ( StreamResult :: Complete ( amt) , buf) )
527
552
}
528
553
}
0 commit comments