diff --git a/lib/srv/desktop/rdp/rdpclient/src/lib.rs b/lib/srv/desktop/rdp/rdpclient/src/lib.rs index e1fdf66c5c6b3..8d879081b1f80 100644 --- a/lib/srv/desktop/rdp/rdpclient/src/lib.rs +++ b/lib/srv/desktop/rdp/rdpclient/src/lib.rs @@ -609,40 +609,44 @@ pub unsafe extern "C" fn read_rdp_output(client_ptr: *mut Client) -> CGOErrCode fn read_rdp_output_inner(client: &Client) -> Option { let tcp_fd = client.tcp_fd; let client_ref = client.go_ref; + // Read incoming events. // // Wait for some data to be available on the TCP socket FD before consuming it. This prevents // us from locking the mutex in Client permanently while no data is available. while wait_for_fd(tcp_fd as usize) { let mut err = CGOErrCode::ErrCodeSuccess; - let res = client - .rdp_client - .lock() - .unwrap() - .read(|rdp_event| match rdp_event { - RdpEvent::Bitmap(bitmap) => { - let mut cbitmap = match CGOBitmap::try_from(bitmap) { - Ok(cb) => cb, - Err(e) => { - error!( - "failed to convert RDP bitmap to CGO representation: {:?}", - e - ); - return; - } - }; - unsafe { - err = handle_bitmap(client_ref, &mut cbitmap) as CGOErrCode; - }; - } - // These should never really be sent by the server to us. - RdpEvent::Pointer(_) => { - debug!("got unexpected pointer event from RDP server, ignoring"); - } - RdpEvent::Key(_) => { - debug!("got unexpected keyboard event from RDP server, ignoring"); + let res = client.rdp_client.lock().unwrap().read(|rdp_event| { + // This callback can be called multiple times per rdp_client.read() + // (if multiple messages were received since the last call). Therefore, + // we check that the previous call to handle_bitmap succeeded, so we don't + // have a situation where handle_bitmap fails repeatedly and creates a + // bunch of repetitive error messages in the logs. If it fails once, + // we assume the connection is broken and stop trying to send bitmaps. + if err == CGOErrCode::ErrCodeSuccess { + match rdp_event { + RdpEvent::Bitmap(bitmap) => { + let mut cbitmap = match CGOBitmap::try_from(bitmap) { + Ok(cb) => cb, + Err(e) => { + error!( + "failed to convert RDP bitmap to CGO representation: {:?}", + e + ); + return; + } + }; + unsafe { + err = handle_bitmap(client_ref, &mut cbitmap) as CGOErrCode; + }; + } + // No other events should be sent by the server to us. + _ => { + debug!("got unexpected pointer event from RDP server, ignoring"); + } } - }); + } + }); match res { Err(RdpError::Io(io_err)) if io_err.kind() == ErrorKind::UnexpectedEof => return None, Err(e) => { @@ -831,7 +835,7 @@ unsafe fn from_go_array(len: u32, ptr: *mut u8) -> Vec { } #[repr(C)] -#[derive(Copy, Clone, PartialEq)] +#[derive(Copy, Clone, PartialEq, Debug)] pub enum CGOErrCode { ErrCodeSuccess = 0, ErrCodeFailure = 1,