@@ -4,7 +4,7 @@ use async_std::path::PathBuf;
4
4
use async_std:: sync:: Arc ;
5
5
use async_std:: task:: { Context , Poll } ;
6
6
use std:: pin:: Pin ;
7
- use std:: sync:: Mutex ;
7
+ use std:: sync:: { atomic :: AtomicBool , Mutex } ;
8
8
9
9
#[ derive( Debug , Copy , Clone ) ]
10
10
#[ allow( dead_code) ]
@@ -19,6 +19,12 @@ pub struct TestCase {
19
19
source_fixture : Arc < File > ,
20
20
expected_fixture : Arc < Mutex < File > > ,
21
21
result : Arc < Mutex < File > > ,
22
+ throttle : Arc < Throttle > ,
23
+ }
24
+
25
+ enum Throttle {
26
+ NoThrottle ,
27
+ YieldPending ( AtomicBool , AtomicBool ) ,
22
28
}
23
29
24
30
impl TestCase {
@@ -68,9 +74,14 @@ impl TestCase {
68
74
source_fixture : Arc :: new ( source_fixture) ,
69
75
expected_fixture : Arc :: new ( Mutex :: new ( expected_fixture) ) ,
70
76
result,
77
+ throttle : Arc :: new ( Throttle :: NoThrottle ) ,
71
78
}
72
79
}
73
80
81
+ pub fn throttle ( & mut self ) {
82
+ self . throttle = Arc :: new ( Throttle :: YieldPending ( AtomicBool :: new ( false ) , AtomicBool :: new ( false ) ) ) ;
83
+ }
84
+
74
85
pub async fn read_result ( & self ) -> String {
75
86
use async_std:: prelude:: * ;
76
87
let mut result = String :: new ( ) ;
@@ -128,13 +139,46 @@ impl Read for TestCase {
128
139
cx : & mut Context ,
129
140
buf : & mut [ u8 ] ,
130
141
) -> Poll < io:: Result < usize > > {
131
- Pin :: new ( & mut & * self . source_fixture ) . poll_read ( cx, buf)
142
+ match & * self . throttle {
143
+ Throttle :: NoThrottle => {
144
+ Pin :: new ( & mut & * self . source_fixture ) . poll_read ( cx, buf)
145
+ } ,
146
+ Throttle :: YieldPending ( read_flag, _) => {
147
+ if read_flag. fetch_xor ( true , std:: sync:: atomic:: Ordering :: SeqCst ) {
148
+ println ! ( "read yield" ) ;
149
+ Poll :: Pending
150
+ } else {
151
+ // read partial
152
+ let throttle_len = std:: cmp:: min ( buf. len ( ) , 10 ) ;
153
+ let buf = & mut buf[ ..throttle_len] ;
154
+ let ret = Pin :: new ( & mut & * self . source_fixture ) . poll_read ( cx, buf) ;
155
+ println ! ( "read partial 10 {:?} {:?}" , ret, buf) ;
156
+ ret
157
+ }
158
+ } ,
159
+ }
132
160
}
133
161
}
134
162
135
163
impl Write for TestCase {
136
164
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
+ println ! ( "write yield" ) ;
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
+ println ! ( "write partial 10 {:?}" , buf) ;
178
+ Pin :: new ( & mut & * self . result . lock ( ) . unwrap ( ) ) . poll_write ( cx, buf)
179
+ }
180
+ } ,
181
+ }
138
182
}
139
183
140
184
fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context ) -> Poll < io:: Result < ( ) > > {
0 commit comments