@@ -110,30 +110,37 @@ impl Remote for RemoteResource {
110
110
// "emulates" full duplex for the websocket case locking here and not outside the loop.
111
111
let mut state = self . state . lock ( ) . expect ( OTHER_THREAD_ERR ) ;
112
112
match state. deref_mut ( ) {
113
- RemoteState :: WebSocket ( web_socket) => {
114
- match web_socket. read_message ( ) {
115
- Ok ( message) => match message {
116
- Message :: Binary ( data) => {
117
- // We can not call process_data while the socket is blocked.
118
- // The user could lock it again if sends from the callback.
119
- drop ( state) ;
120
- process_data ( & data) ;
113
+ RemoteState :: WebSocket ( web_socket) => match web_socket. read_message ( ) {
114
+ Ok ( message) => match message {
115
+ Message :: Binary ( data) => {
116
+ // As an optimization.
117
+ // Fast check to know if there is more data to avoid call
118
+ // WebSocket::read_message() again.
119
+ // TODO: investigate why this code doesn't work in windows.
120
+ // Seems like windows consume the `WouldBlock` notification
121
+ // at peek() when it happens, and the poll never wakes it again.
122
+ #[ cfg( not( target_os = "windows" ) ) ]
123
+ let _peek_result = web_socket. get_ref ( ) . peek ( & mut [ 0 ; 0 ] ) ;
124
+
125
+ // We can not call process_data while the socket is blocked.
126
+ // The user could lock it again if sends from the callback.
127
+ drop ( state) ;
128
+ process_data ( & data) ;
129
+
130
+ #[ cfg( not( target_os = "windows" ) ) ]
131
+ if let Err ( err) = _peek_result {
132
+ break Self :: io_error_to_read_status ( & err)
121
133
}
122
- Message :: Close ( _) => break ReadStatus :: Disconnected ,
123
- _ => continue ,
124
- } ,
125
- Err ( Error :: Io ( ref err) ) if err. kind ( ) == ErrorKind :: WouldBlock => {
126
- break ReadStatus :: WaitNextEvent
127
- }
128
- Err ( Error :: Io ( ref err) ) if err. kind ( ) == ErrorKind :: ConnectionReset => {
129
- break ReadStatus :: Disconnected
130
- }
131
- Err ( err) => {
132
- log:: error!( "WS receive error: {}" , err) ;
133
- break ReadStatus :: Disconnected // should not happen
134
134
}
135
+ Message :: Close ( _) => break ReadStatus :: Disconnected ,
136
+ _ => continue ,
137
+ } ,
138
+ Err ( Error :: Io ( ref err) ) => break Self :: io_error_to_read_status ( err) ,
139
+ Err ( err) => {
140
+ log:: error!( "WS receive error: {}" , err) ;
141
+ break ReadStatus :: Disconnected // should not happen
135
142
}
136
- }
143
+ } ,
137
144
RemoteState :: Handshake ( handshake) => {
138
145
let current_handshake = handshake. take ( ) . unwrap ( ) ;
139
146
match current_handshake. mid_handshake . handshake ( ) {
@@ -191,6 +198,19 @@ impl RemoteResource {
191
198
}
192
199
}
193
200
}
201
+
202
+ fn io_error_to_read_status ( err : & io:: Error ) -> ReadStatus {
203
+ if err. kind ( ) == io:: ErrorKind :: WouldBlock {
204
+ ReadStatus :: WaitNextEvent
205
+ }
206
+ else if err. kind ( ) == io:: ErrorKind :: ConnectionReset {
207
+ ReadStatus :: Disconnected
208
+ }
209
+ else {
210
+ log:: error!( "WS receive error: {}" , err) ;
211
+ ReadStatus :: Disconnected // should not happen
212
+ }
213
+ }
194
214
}
195
215
196
216
pub ( crate ) struct LocalResource {
0 commit comments