@@ -110,30 +110,37 @@ impl Remote for RemoteResource {
110110 // "emulates" full duplex for the websocket case locking here and not outside the loop.
111111 let mut state = self . state . lock ( ) . expect ( OTHER_THREAD_ERR ) ;
112112 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)
121133 }
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
134134 }
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
135142 }
136- }
143+ } ,
137144 RemoteState :: Handshake ( handshake) => {
138145 let current_handshake = handshake. take ( ) . unwrap ( ) ;
139146 match current_handshake. mid_handshake . handshake ( ) {
@@ -191,6 +198,19 @@ impl RemoteResource {
191198 }
192199 }
193200 }
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+ }
194214}
195215
196216pub ( crate ) struct LocalResource {
0 commit comments