@@ -4,7 +4,7 @@ use async_std::path::PathBuf;
44use async_std:: sync:: Arc ;
55use async_std:: task:: { Context , Poll } ;
66use std:: pin:: Pin ;
7- use std:: sync:: Mutex ;
7+ use std:: sync:: { atomic :: AtomicBool , Mutex } ;
88
99#[ derive( Debug , Copy , Clone ) ]
1010#[ allow( dead_code) ]
@@ -19,6 +19,12 @@ pub struct TestCase {
1919 source_fixture : Arc < File > ,
2020 expected_fixture : Arc < Mutex < File > > ,
2121 result : Arc < Mutex < File > > ,
22+ throttle : Arc < Throttle > ,
23+ }
24+
25+ enum Throttle {
26+ NoThrottle ,
27+ YieldPending ( AtomicBool , AtomicBool ) ,
2228}
2329
2430impl TestCase {
@@ -68,9 +74,15 @@ impl TestCase {
6874 source_fixture : Arc :: new ( source_fixture) ,
6975 expected_fixture : Arc :: new ( Mutex :: new ( expected_fixture) ) ,
7076 result,
77+ throttle : Arc :: new ( Throttle :: NoThrottle ) ,
7178 }
7279 }
7380
81+ #[ allow( dead_code) ]
82+ pub fn throttle ( & mut self ) {
83+ self . throttle = Arc :: new ( Throttle :: YieldPending ( AtomicBool :: new ( false ) , AtomicBool :: new ( false ) ) ) ;
84+ }
85+
7486 pub async fn read_result ( & self ) -> String {
7587 use async_std:: prelude:: * ;
7688 let mut result = String :: new ( ) ;
@@ -128,13 +140,44 @@ impl Read for TestCase {
128140 cx : & mut Context ,
129141 buf : & mut [ u8 ] ,
130142 ) -> Poll < io:: Result < usize > > {
131- Pin :: new ( & mut & * self . source_fixture ) . poll_read ( cx, buf)
143+ match & * self . throttle {
144+ Throttle :: NoThrottle => {
145+ Pin :: new ( & mut & * self . source_fixture ) . poll_read ( cx, buf)
146+ } ,
147+ Throttle :: YieldPending ( read_flag, _) => {
148+ if read_flag. fetch_xor ( true , std:: sync:: atomic:: Ordering :: SeqCst ) {
149+ cx. waker ( ) . wake_by_ref ( ) ;
150+ Poll :: Pending
151+ } else {
152+ // read partial
153+ let throttle_len = std:: cmp:: min ( buf. len ( ) , 10 ) ;
154+ let buf = & mut buf[ ..throttle_len] ;
155+ let ret = Pin :: new ( & mut & * self . source_fixture ) . poll_read ( cx, buf) ;
156+ ret
157+ }
158+ } ,
159+ }
132160 }
133161}
134162
135163impl Write for TestCase {
136164 fn poll_write ( self : Pin < & mut Self > , cx : & mut Context , buf : & [ u8 ] ) -> Poll < io:: Result < usize > > {
137- Pin :: new ( & mut & * self . result . lock ( ) . unwrap ( ) ) . poll_write ( cx, buf)
165+ match & * self . throttle {
166+ Throttle :: NoThrottle => {
167+ Pin :: new ( & mut & * self . result . lock ( ) . unwrap ( ) ) . poll_write ( cx, buf)
168+ } ,
169+ Throttle :: YieldPending ( _, write_flag) => {
170+ if write_flag. fetch_xor ( true , std:: sync:: atomic:: Ordering :: SeqCst ) {
171+ cx. waker ( ) . wake_by_ref ( ) ;
172+ Poll :: Pending
173+ } else {
174+ // write partial
175+ let throttle_len = std:: cmp:: min ( buf. len ( ) , 10 ) ;
176+ let buf = & buf[ ..throttle_len] ;
177+ Pin :: new ( & mut & * self . result . lock ( ) . unwrap ( ) ) . poll_write ( cx, buf)
178+ }
179+ } ,
180+ }
138181 }
139182
140183 fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context ) -> Poll < io:: Result < ( ) > > {
0 commit comments