Hi everyone, I'm fairly new to Rust and especially async Rust. Some context: I'm writing a program that takes in a string and converts it to instructions to press buttons/axes on a virtual input device. For example, up'1
would hold up on a controller's joystick for 1 second. I want to run an async method executing the instructions on said device. For creating and managing the virtual devices, I'm using evdev-rs.
So back to my problem. I intend to run the instructions through an input handler like this:
let mut v_joystick_manager = VirtualJoystickManager::new(1);
// Create a virtual joystick
_ = v_joystick_manager.create_joystick(0, "TRBot Joystick 0", 0x378, 0x3, 3);
let mut join_set = JoinSet::new();
let input_handler = input_handler::InputHandler::new(Arc::new(v_joystick_manager));
join_set.spawn(async move { input_handler.execute_instructions(&instructions) });
// ^ Compiler error occurs here!
The compiler is complaining because the input handler isn't safe to send because it has a VirtualJoystickManager
which contains a VirtualJoystick
, which in turn contains a UinputDevice
from evdev-rs. That definition for that is as follows:
pub struct UInputDevice {
raw: *mut raw::libevdev_uinput, <---- Compiler complains about this pointer!
}
unsafe impl Send for UInputDevice {}
The exact error I get is:
error[E0277]: `*mut evdev_sys::libevdev_uinput` cannot be shared between threads safely
--> src/main.rs:164:22
|
164 | join_set.spawn(async move { input_handler.execute_instructions(&instructions) });
| ^^^^^ `*mut evdev_sys::libevdev_uinput` cannot be shared between threads safely
|
= help: within `VirtualJoystickManager`, the trait `Sync` is not implemented for `*mut evdev_sys::libevdev_uinput`
note: required because it appears within the type `UInputDevice`
I've tried modifying evdev-rs to implement Sync, but it still complains. I've also tried wrapping the spawn
in an unsafe block, but it still throws the same error.
I'm okay with breaking the thread safety of the virtual devices since it's intended for multiple different threads to access the devices and write different states to them. My program would not function as well otherwise.
What are my options here to get this working? Please let me know if you need more details. Thanks so much in advance!