@@ -5,7 +5,10 @@ use core::{
5
5
use std:: io:: { Error as IoError , ErrorKind as IoErrorKind } ;
6
6
7
7
use async_trait:: async_trait;
8
- use futures_util:: ready;
8
+ use futures_util:: {
9
+ future:: { self , Either } ,
10
+ ready,
11
+ } ;
9
12
use ssh2:: { BlockDirections , Error as Ssh2Error , Session } ;
10
13
use tokio:: net:: TcpStream ;
11
14
#[ cfg( unix) ]
@@ -52,8 +55,43 @@ impl AsyncSessionStream for TcpStream {
52
55
assert ! ( expected_block_directions. is_readable( ) ) ;
53
56
assert ! ( expected_block_directions. is_writable( ) ) ;
54
57
55
- self . ready ( tokio:: io:: Interest :: READABLE | tokio:: io:: Interest :: WRITABLE )
56
- . await ?;
58
+ let mut n_retry = 0 ;
59
+ loop {
60
+ let ready = self
61
+ . ready ( tokio:: io:: Interest :: READABLE | tokio:: io:: Interest :: WRITABLE )
62
+ . await ?;
63
+ if ready. is_readable ( ) {
64
+ let either = future:: select (
65
+ Box :: pin ( self . writable ( ) ) ,
66
+ Box :: pin ( sleep ( Duration :: from_millis ( 1000 ) ) ) ,
67
+ )
68
+ . await ;
69
+ match either {
70
+ Either :: Left ( ( x, _) ) => x?,
71
+ Either :: Right ( _) => { }
72
+ }
73
+ break ;
74
+ } else if ready. is_writable ( ) {
75
+ let either = future:: select (
76
+ Box :: pin ( self . readable ( ) ) ,
77
+ Box :: pin ( sleep ( Duration :: from_millis ( 1000 ) ) ) ,
78
+ )
79
+ . await ;
80
+ match either {
81
+ Either :: Left ( ( x, _) ) => x?,
82
+ Either :: Right ( _) => { }
83
+ }
84
+ break ;
85
+ } else if ready. is_empty ( ) {
86
+ n_retry += 1 ;
87
+ if n_retry > 3 {
88
+ break ;
89
+ }
90
+ continue ;
91
+ } else {
92
+ break ;
93
+ }
94
+ }
57
95
}
58
96
}
59
97
@@ -152,8 +190,43 @@ impl AsyncSessionStream for UnixStream {
152
190
assert ! ( expected_block_directions. is_readable( ) ) ;
153
191
assert ! ( expected_block_directions. is_writable( ) ) ;
154
192
155
- self . ready ( tokio:: io:: Interest :: READABLE | tokio:: io:: Interest :: WRITABLE )
156
- . await ?;
193
+ let mut n_retry = 0 ;
194
+ loop {
195
+ let ready = self
196
+ . ready ( tokio:: io:: Interest :: READABLE | tokio:: io:: Interest :: WRITABLE )
197
+ . await ?;
198
+ if ready. is_readable ( ) {
199
+ let either = future:: select (
200
+ Box :: pin ( self . writable ( ) ) ,
201
+ Box :: pin ( sleep ( Duration :: from_millis ( 1000 ) ) ) ,
202
+ )
203
+ . await ;
204
+ match either {
205
+ Either :: Left ( ( x, _) ) => x?,
206
+ Either :: Right ( _) => { }
207
+ }
208
+ break ;
209
+ } else if ready. is_writable ( ) {
210
+ let either = future:: select (
211
+ Box :: pin ( self . readable ( ) ) ,
212
+ Box :: pin ( sleep ( Duration :: from_millis ( 1000 ) ) ) ,
213
+ )
214
+ . await ;
215
+ match either {
216
+ Either :: Left ( ( x, _) ) => x?,
217
+ Either :: Right ( _) => { }
218
+ }
219
+ break ;
220
+ } else if ready. is_empty ( ) {
221
+ n_retry += 1 ;
222
+ if n_retry > 3 {
223
+ break ;
224
+ }
225
+ continue ;
226
+ } else {
227
+ break ;
228
+ }
229
+ }
157
230
}
158
231
}
159
232
0 commit comments