buttplugio / buttplug

Rust Implementation of the Buttplug Sex Toy Control Protocol

Home Page:https://buttplug.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WouldBlock error when running example 03-device-enumeration

ThatBatLuna opened this issue · comments

Describe the bug
On Unix, when running the example 03-device-enumeration example, the connection between the server and the client is broken, because at the UnixStream of the ButtplugPipeServerTransport returns a WouldBlock error, here:

match server.try_read(&mut data) {
Ok(n) => {
if n == 0 {
continue;
}
data.truncate(n);
let json_str = if let Ok(json) = String::from_utf8(data) {
json
} else {
error!("Could not parse incoming values as valid utf8.");
continue;
};
if response_sender.send(ButtplugTransportIncomingMessage::Message(ButtplugSerializedMessage::Text(json_str))).await.is_err() {
error!("Connector that owns transport no longer available, exiting.");
break;
}
},
Err(err) => {
error!("Error from pipe server, assuming disconnection: {:?}", err);
break;
}

The tokio docs say: If the stream is not ready to read data, Err(io::ErrorKind::WouldBlock) is returned. Which is what I believe happens.

The big question is, WHY is the stream not ready?

Expected behavior
The stuff I just describe does not happen, and instead client and server communicate happily ever after -

Actual behavior
The example does not continue beyond

client
//.connect_in_process(None)
.connect(ButtplugRemoteClientConnector::<
_,
ButtplugClientJSONSerializer,
>::new(
ButtplugPipeClientTransportBuilder::new("\\\\.\\pipe\\testpipe").finish(),
))
.await
.unwrap();

and just idles - seemingly without doing anything.

Additional context

2022-12-29T17:22:27.305482Z  INFO Device Enumeration Example: 03_device_enumeration: Starting Device Enumeration Example
2022-12-29T17:22:27.309442Z  INFO buttplug::server: Buttplug Server Operating System Info: Arch Linux [64-bit]
2022-12-29T17:22:27.309548Z  INFO buttplug::util::device_configuration: Loading from custom base device configuration...
2022-12-29T17:22:27.367720Z  INFO buttplug::util::device_configuration: No user configuration given.
2022-12-29T17:22:27.371024Z  INFO buttplug::server::device::server_device_manager: BtlePlugCommunicationManager: false
2022-12-29T17:22:27.373638Z  INFO buttplug::server::device::hardware::communication::btleplug::btleplug_adapter_task: Bluetooth LE adapter found.
2022-12-29T17:22:27.377549Z  INFO buttplug::server::device::server_device_manager_event_loop: Device [...] (PeripheralId(DeviceId { object_path: Path("/org/bluez/hci0/dev_94_65_2D_42_17_AA\0") })) found.
2022-12-29T17:22:27.379602Z  INFO buttplug::server::device::server_device_manager_event_loop: Device [...] (PeripheralId(DeviceId { object_path: Path("/org/bluez/hci0/dev_B8_D5_0B_E6_43_B8\0") })) found.
2022-12-29T17:22:27.381710Z  INFO buttplug::server::device::server_device_manager_event_loop: Device [...] (PeripheralId(DeviceId { object_path: Path("/org/bluez/hci0/dev_CC_98_8B_56_D0_6D\0") })) found.
2022-12-29T17:22:27.407088Z  INFO Device Enumeration Example: 03_device_enumeration: Client connecting...
2022-12-29T17:22:27.407180Z  INFO Device Enumeration Example: buttplug::client: Connecting to server.
2022-12-29T17:22:27.407400Z  INFO Device Enumeration Example: buttplug::client: Connection to server succeeded.
2022-12-29T17:22:27.407424Z  INFO buttplug::core::connector::transport::pipe::pipe_client: Starting pipe server connection event loop.
2022-12-29T17:22:27.407485Z  INFO buttplug::server::remote_server: Starting remote server loop
2022-12-29T17:22:27.407493Z  INFO buttplug::core::connector::transport::pipe::pipe_server: Starting pipe server connection event loop.
2022-12-29T17:22:27.407520Z  INFO Device Enumeration Example: buttplug::client: Running handshake with server.
2022-12-29T17:22:27.414139Z ERROR buttplug::core::connector::transport::pipe::pipe_server: Error from pipe server, assuming disconnection: Kind(WouldBlock)
2022-12-29T17:22:27.417843Z  INFO buttplug::core::message::serializer::json_serializer: Setting JSON Wrapper message version to Version3
2022-12-29T17:22:27.417898Z  INFO buttplug::core::connector::remote_connector: Connector closing connection Pipe server closed
2022-12-29T17:22:27.418840Z  INFO buttplug::server::remote_server: Connector disconnected, exiting loop.
2022-12-29T17:22:27.418879Z  INFO buttplug::server: Server disconnected, stopping device scanning if it was started...
2022-12-29T17:22:27.418893Z  INFO buttplug::server: Server disconnected, stopping all devices...
2022-12-29T17:22:27.418904Z  INFO buttplug::server::remote_server: Exiting remote server loop
2022-12-29T17:22:27.419477Z  INFO buttplug::server: Performing server handshake check with client test client at message version Version3.
2022-12-29T17:22:27.419665Z ERROR buttplug::server::remote_server: Cannot send reply to server, dropping and assuming remote server thread has exited.
2022-12-29T17:22:27.419701Z  INFO buttplug::server::device::server_device_manager: Dropping device manager!

(Idles forever...)

This occurs on the main and dev branches as far as I could tell.

Okay, that the stream.try_read fails with WouldBlock is the correct behaviour, because stream.ready and ready.is_readable() do not guarantee that the stream is actually ready, as seen in the documentation and the example here.

I believe in case of a WouldBlock error, we don't have to assume disconnection and break the loop, but we can simply continue to wait.