[GH-ISSUE #10] Controller vibration through vuinputd-virtualized device causes Sunshine session to softlock #8

Open
opened 2026-10-30 21:32:23 +00:00 by bsakaguchi · 14 comments
Owner

Originally created by @griffi-gh on GitHub (Mar 23, 2026).
Original GitHub issue: https://github.com/joleuger/vuinputd/issues/10

vibration seems to cause all sorts of weird issues...

for example Eden emulator drops to one frame per 10 seconds or so while vibration is active.

Vibration in Dead Cells brings down both session AND the game itself, and somehow kills the entire session???

Originally created by @griffi-gh on GitHub (Mar 23, 2026). Original GitHub issue: https://github.com/joleuger/vuinputd/issues/10 vibration seems to cause all sorts of weird issues... for example Eden emulator drops to one frame per 10 seconds or so while vibration is active. Vibration in Dead Cells brings down both session AND the game itself, and somehow kills the entire session???
Author
Owner

@joleuger commented on GitHub (Mar 23, 2026):

Thanks for reporting. This seems to be an issue with the ioctls

https://github.com/joleuger/vuinputd/blob/0.3.2/vuinputd/src/cuse_device/vuinput_ioctl.rs

I actually haven't tested the vibration functionality. Can you please send the logs?

My guess: The problem seems to be the UI_BEGIN_FF_UPLOAD. I guess this code here triggers
assert!(_in_bufsz != 0, "should have _in_bufsz");.
Very likely this fails: fuse_lowlevel::fuse_reply_ioctl_retry(_req, &iov, 1, &iov, 1);
I need to read the interface in the kernel first. I guess it needs to be fuse_lowlevel::fuse_reply_ioctl_retry(_req, &iov, 1, std::ptr::null(), 0));

Edit: No, it actually is a read write structure: https://github.com/torvalds/linux/blob/master/drivers/input/misc/uinput.c

<!-- gh-comment-id:4114000511 --> @joleuger commented on GitHub (Mar 23, 2026): Thanks for reporting. This seems to be an issue with the ioctls > https://github.com/joleuger/vuinputd/blob/0.3.2/vuinputd/src/cuse_device/vuinput_ioctl.rs I actually haven't tested the vibration functionality. Can you please send the logs? My guess: The problem seems to be the UI_BEGIN_FF_UPLOAD. I guess this code here triggers `assert!(_in_bufsz != 0, "should have _in_bufsz");`. Very likely this fails: `fuse_lowlevel::fuse_reply_ioctl_retry(_req, &iov, 1, &iov, 1);` I need to read the interface in the kernel first. I guess it needs to be `fuse_lowlevel::fuse_reply_ioctl_retry(_req, &iov, 1, std::ptr::null(), 0));` Edit: No, it actually is a read write structure: https://github.com/torvalds/linux/blob/master/drivers/input/misc/uinput.c
Author
Owner

@joleuger commented on GitHub (Mar 23, 2026):

Ok, I have asked gemini (haven't tried it out, yet):

The Real Bug: Mutating _in_buf
The issue you are experiencing is almost certainly happening in the actual processing block due to how FUSE's memory is being handled:

Rust

let ff_upload_ptr = _in_buf as *mut uinput_ff_upload;
ui_begin_ff_upload(fd, ff_upload_ptr).unwrap();

FUSE provides _in_buf as a *const c_void. It is fundamentally a read-only view of the data fetched during the retry phase. Casting a *const FUSE buffer to a *mut pointer and letting ui_begin_ff_upload mutate it in-place is undefined behavior. Depending on how the FUSE C library mapped that buffer, writing to it directly can cause a segfault, a kernel EFAULT, or silent memory corruption.

The Fix
Instead of casting and modifying the read-only buffer directly, you should safely copy it into a local, mutable struct, perform the ioctl on your local copy, and then pass that local copy back to FUSE so it can handle copying it back to the calling process.

Here is how you can correct the block:

UI_BEGIN_FF_UPLOAD => {
    assert!(_in_bufsz >= ::std::mem::size_of::<uinput_ff_upload>(), "buffer too small");
    debug!("fh {}: ioctl UI_BEGIN_FF_UPLOAD", fh);
    
    // 1. Safely copy the FUSE buffer into a local, mutable struct.
    // (Using read_unaligned is safer here since FUSE buffer alignment isn't strictly guaranteed for complex structs)
    let mut ff_upload = unsafe { 
        ::std::ptr::read_unaligned(_in_buf as *const uinput_ff_upload) 
    };
    debug!("request_id: {:x}", ff_upload.request_id);
    
    // 2. Perform the ioctl on your local mutable struct.
    // Note: Consider handling the Err case gracefully with fuse_lowlevel::fuse_reply_err 
    // instead of unwrap() so your daemon doesn't panic if the kernel rejects the upload.
    ui_begin_ff_upload(fd, &mut ff_upload as *mut _).unwrap();
    
    // 3. Send the modified local struct back to FUSE.
    let out_ptr = &ff_upload as *const _ as *const ::std::os::raw::c_void;
    unsafe {
        fuse_lowlevel::fuse_reply_ioctl(_req, 0, out_ptr, _out_bufsz);
    }
}

Very likely, the same problem is in UI_BEGIN_FF_ERASE. I need to figure out, how to write an isolated test.

<!-- gh-comment-id:4114055418 --> @joleuger commented on GitHub (Mar 23, 2026): Ok, I have asked gemini (haven't tried it out, yet): The Real Bug: Mutating _in_buf The issue you are experiencing is almost certainly happening in the actual processing block due to how FUSE's memory is being handled: Rust ``` let ff_upload_ptr = _in_buf as *mut uinput_ff_upload; ui_begin_ff_upload(fd, ff_upload_ptr).unwrap(); ``` FUSE provides _in_buf as a *const c_void. It is fundamentally a read-only view of the data fetched during the retry phase. Casting a *const FUSE buffer to a *mut pointer and letting ui_begin_ff_upload mutate it in-place is undefined behavior. Depending on how the FUSE C library mapped that buffer, writing to it directly can cause a segfault, a kernel EFAULT, or silent memory corruption. The Fix Instead of casting and modifying the read-only buffer directly, you should safely copy it into a local, mutable struct, perform the ioctl on your local copy, and then pass that local copy back to FUSE so it can handle copying it back to the calling process. Here is how you can correct the block: ``` UI_BEGIN_FF_UPLOAD => { assert!(_in_bufsz >= ::std::mem::size_of::<uinput_ff_upload>(), "buffer too small"); debug!("fh {}: ioctl UI_BEGIN_FF_UPLOAD", fh); // 1. Safely copy the FUSE buffer into a local, mutable struct. // (Using read_unaligned is safer here since FUSE buffer alignment isn't strictly guaranteed for complex structs) let mut ff_upload = unsafe { ::std::ptr::read_unaligned(_in_buf as *const uinput_ff_upload) }; debug!("request_id: {:x}", ff_upload.request_id); // 2. Perform the ioctl on your local mutable struct. // Note: Consider handling the Err case gracefully with fuse_lowlevel::fuse_reply_err // instead of unwrap() so your daemon doesn't panic if the kernel rejects the upload. ui_begin_ff_upload(fd, &mut ff_upload as *mut _).unwrap(); // 3. Send the modified local struct back to FUSE. let out_ptr = &ff_upload as *const _ as *const ::std::os::raw::c_void; unsafe { fuse_lowlevel::fuse_reply_ioctl(_req, 0, out_ptr, _out_bufsz); } } ``` Very likely, the same problem is in UI_BEGIN_FF_ERASE. I need to figure out, how to write an isolated test.
Author
Owner

@joleuger commented on GitHub (Mar 23, 2026):

Just to ensure, can you please check if this line in your logs when switching debug logging on?

legacy device setup recognized! Ignore the data and use hardcoded values

If yes, then the issue is not with the ioctls but because I missed to implement copying the ff stuff here https://github.com/joleuger/vuinputd/blob/0.3.2/vuinputd/src/cuse_device/vuinput_write.rs#L61

Edit: But actually this should not be the case, because sunshine is creating the device.

<!-- gh-comment-id:4114119661 --> @joleuger commented on GitHub (Mar 23, 2026): Just to ensure, can you please check if [this](https://github.com/joleuger/vuinputd/blob/0.3.2/vuinputd/src/cuse_device/vuinput_write.rs#L38) line in your logs when switching debug logging on? > legacy device setup recognized! Ignore the data and use hardcoded values If yes, then the issue is not with the ioctls but because I missed to implement copying the ff stuff here https://github.com/joleuger/vuinputd/blob/0.3.2/vuinputd/src/cuse_device/vuinput_write.rs#L61 Edit: But actually this should not be the case, because sunshine is creating the device.
Author
Owner

@griffi-gh commented on GitHub (Mar 23, 2026):

I actually haven't tested the vibration functionality. Can you please send the logs?

nothing suspicious in vuinputd logs but sunshine is spamming literal gigabytes of logs like this:

Mar 23 21:55:28 gayming sunshine[373]: on not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading>
Mar 23 21:55:28 gayming sunshine[373]: ; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFa>
Mar 23 21:55:28 gayming sunshine[373]: ng uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not i>
Mar 23 21:55:28 gayming sunshine[373]: Failed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Fu>
Mar 23 21:55:28 gayming sunshine[373]:  implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinpu>
Mar 23 21:55:28 gayming sunshine[373]: Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed r>
Mar 23 21:55:28 gayming sunshine[373]: put fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not impleme>
Mar 23 21:55:28 gayming sunshine[373]:  reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function>
Mar 23 21:55:28 gayming sunshine[373]: mentedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; >
Mar 23 21:55:28 gayming sunshine[373]: on not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading>
Mar 23 21:55:28 gayming sunshine[373]: ; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFa>
Mar 23 21:55:28 gayming sunshine[373]: ng uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not i>
Mar 23 21:55:28 gayming sunshine[373]: Failed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Fu>
Mar 23 21:55:28 gayming sunshine[373]:  implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinpu>
Mar 23 21:55:28 gayming sunshine[373]: Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed r>
Mar 23 21:55:28 gayming sunshine[373]: put fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not impleme>
Mar 23 21:55:28 gayming sunshine[373]:  reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function>
Mar 23 21:55:28 gayming sunshine[373]: mentedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; >
Mar 23 21:55:28 gayming sunshine[373]: on not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading>
Mar 23 21:55:28 gayming sunshine[373]: ; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFa>
Mar 23 21:55:27 gayming sunshine[373]: ng uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not i>
Mar 23 21:55:27 gayming sunshine[373]: Failed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Fu>
Mar 23 21:55:27 gayming sunshine[373]:  implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinpu>
Mar 23 21:55:27 gayming sunshine[373]: Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed r>
Mar 23 21:55:27 gayming sunshine[373]: put fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not impleme>
Mar 23 21:55:27 gayming systemd-journald[61]: [🡕] Suppressed 2110 messages from sunshine.service

i am not sure if it's related to this specific issue or just some red herring that can be ignored/doesn't cause actual failure

<!-- gh-comment-id:4114196718 --> @griffi-gh commented on GitHub (Mar 23, 2026): > I actually haven't tested the vibration functionality. Can you please send the logs? nothing suspicious in vuinputd logs but sunshine is spamming literal gigabytes of logs like this: ``` Mar 23 21:55:28 gayming sunshine[373]: on not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading> Mar 23 21:55:28 gayming sunshine[373]: ; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFa> Mar 23 21:55:28 gayming sunshine[373]: ng uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not i> Mar 23 21:55:28 gayming sunshine[373]: Failed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Fu> Mar 23 21:55:28 gayming sunshine[373]: implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinpu> Mar 23 21:55:28 gayming sunshine[373]: Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed r> Mar 23 21:55:28 gayming sunshine[373]: put fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not impleme> Mar 23 21:55:28 gayming sunshine[373]: reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function> Mar 23 21:55:28 gayming sunshine[373]: mentedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; > Mar 23 21:55:28 gayming sunshine[373]: on not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading> Mar 23 21:55:28 gayming sunshine[373]: ; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFa> Mar 23 21:55:28 gayming sunshine[373]: ng uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not i> Mar 23 21:55:28 gayming sunshine[373]: Failed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Fu> Mar 23 21:55:28 gayming sunshine[373]: implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinpu> Mar 23 21:55:28 gayming sunshine[373]: Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed r> Mar 23 21:55:28 gayming sunshine[373]: put fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not impleme> Mar 23 21:55:28 gayming sunshine[373]: reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function> Mar 23 21:55:28 gayming sunshine[373]: mentedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; > Mar 23 21:55:28 gayming sunshine[373]: on not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading> Mar 23 21:55:28 gayming sunshine[373]: ; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFa> Mar 23 21:55:27 gayming sunshine[373]: ng uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not i> Mar 23 21:55:27 gayming sunshine[373]: Failed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Fu> Mar 23 21:55:27 gayming sunshine[373]: implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinpu> Mar 23 21:55:27 gayming sunshine[373]: Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed r> Mar 23 21:55:27 gayming sunshine[373]: put fd; ret=Function not implementedFailed reading uinput fd; ret=Function not implementedFailed reading uinput fd; ret=Function not impleme> Mar 23 21:55:27 gayming systemd-journald[61]: [🡕] Suppressed 2110 messages from sunshine.service ``` i am not sure if it's related to this specific issue or just some red herring that can be ignored/doesn't cause actual failure
Author
Owner

@griffi-gh commented on GitHub (Mar 23, 2026):

Just to ensure, can you please check if this line in your logs when switching debug logging on?

legacy device setup recognized! Ignore the data and use hardcoded values

If yes, then the issue is not with the ioctls but because I missed to implement copying the ff stuff here https://github.com/joleuger/vuinputd/blob/0.3.2/vuinputd/src/cuse_device/vuinput_write.rs#L61

Edit: But actually this should not be the case, because sunshine is creating the device.

i don't think i've ever seen that appear in journalctl logs

<!-- gh-comment-id:4114216514 --> @griffi-gh commented on GitHub (Mar 23, 2026): > Just to ensure, can you please check if [this](https://github.com/joleuger/vuinputd/blob/0.3.2/vuinputd/src/cuse_device/vuinput_write.rs#L38) line in your logs when switching debug logging on? > > > legacy device setup recognized! Ignore the data and use hardcoded values > > If yes, then the issue is not with the ioctls but because I missed to implement copying the ff stuff here https://github.com/joleuger/vuinputd/blob/0.3.2/vuinputd/src/cuse_device/vuinput_write.rs#L61 > > Edit: But actually this should not be the case, because sunshine is creating the device. i don't think i've ever seen that appear in journalctl logs
Author
Owner
<!-- gh-comment-id:4114311926 --> @joleuger commented on GitHub (Mar 23, 2026): Failed reading uinput fd comes from inputtino: https://github.com/games-on-whales/inputtino/blob/f4ce2b0df536ef309e9ff318f75b460f7097d7c1/src/uinput/include/inputtino/protected_types.hpp#L28 The reason is a ENOSYS 38 Function not implemented https://man7.org/linux/man-pages/man3/errno.3.html ENOSYS is thrown here https://github.com/torvalds/linux/blob/master/drivers/input/misc/uinput.c#L265-L266
Author
Owner

@joleuger commented on GitHub (Mar 23, 2026):

Hmmm, from my understanding, EV_FF should actually be set

github.com/games-on-whales/inputtino@f4ce2b0df5/src/uinput/joypad_xbox.cpp

libevdev_enable_event_type(dev, EV_FF);
  libevdev_enable_event_code(dev, EV_FF, FF_RUMBLE, nullptr);
  libevdev_enable_event_code(dev, EV_FF, FF_CONSTANT, nullptr);
  libevdev_enable_event_code(dev, EV_FF, FF_PERIODIC, nullptr);
  libevdev_enable_event_code(dev, EV_FF, FF_SINE, nullptr);
  libevdev_enable_event_code(dev, EV_FF, FF_RAMP, nullptr);
  libevdev_enable_event_code(dev, EV_FF, FF_GAIN, nullptr);

https://gitlab.freedesktop.org/libevdev/libevdev/-/blob/master/libevdev/libevdev-uinput.c?ref_type=heads#L93

case EV_FF: uinput_bit = UI_SET_FFBIT; break;
<!-- gh-comment-id:4114398226 --> @joleuger commented on GitHub (Mar 23, 2026): Hmmm, from my understanding, EV_FF should actually be set https://github.com/games-on-whales/inputtino/blob/f4ce2b0df536ef309e9ff318f75b460f7097d7c1/src/uinput/joypad_xbox.cpp ``` libevdev_enable_event_type(dev, EV_FF); libevdev_enable_event_code(dev, EV_FF, FF_RUMBLE, nullptr); libevdev_enable_event_code(dev, EV_FF, FF_CONSTANT, nullptr); libevdev_enable_event_code(dev, EV_FF, FF_PERIODIC, nullptr); libevdev_enable_event_code(dev, EV_FF, FF_SINE, nullptr); libevdev_enable_event_code(dev, EV_FF, FF_RAMP, nullptr); libevdev_enable_event_code(dev, EV_FF, FF_GAIN, nullptr); ``` https://gitlab.freedesktop.org/libevdev/libevdev/-/blob/master/libevdev/libevdev-uinput.c?ref_type=heads#L93 ``` case EV_FF: uinput_bit = UI_SET_FFBIT; break; ```
Author
Owner

@joleuger commented on GitHub (Mar 23, 2026):

I guess I need to try it out on my own machine to be able to write a reproducible test case. Just to be able to reproduce: Did you manage to get any game working? Might also be the case that for vibration, ioctls after device setup are necessary. Need to check out. But will be next week.

Anyway, thanks for reporting!

<!-- gh-comment-id:4114426358 --> @joleuger commented on GitHub (Mar 23, 2026): I guess I need to try it out on my own machine to be able to write a reproducible test case. Just to be able to reproduce: Did you manage to get any game working? Might also be the case that for vibration, ioctls after device setup are necessary. Need to check out. But will be next week. Anyway, thanks for reporting!
Author
Owner

@griffi-gh commented on GitHub (Mar 23, 2026):

yes, games work properly if i turn off controller vibration in in-game settings

https://github.com/girl-pp-ua/nixos-infra/tree/master/modules/services/experimental/gayming-nixos

this is the full config of the container and system (as reproducible nix) i'm running for testing; if you need any configs from my system it should all be there

<!-- gh-comment-id:4114447032 --> @griffi-gh commented on GitHub (Mar 23, 2026): yes, games work properly if i turn off controller vibration in in-game settings https://github.com/girl-pp-ua/nixos-infra/tree/master/modules/services/experimental/gayming-nixos this is the full config of the container and system (as reproducible nix) i'm running for testing; if you need any configs from my system it should all be there
Author
Owner

@joleuger commented on GitHub (Mar 31, 2026):

Ok, I can reproduce the problem:

upload a simple RUMBLE effect
Error reading in thread: Function not implemented (os error 38)

thread 'main' (31163) panicked at vuinputd-tests/src/devices/xbox_gamepad.rs:197:30:
called `Result::unwrap()` on an `Err` value: ETIMEDOUT
stack backtrace:

I need to implement the read and poll functions of the cuse device to forward the data of the ff request, which contains the pattern. The applications actually write that data via a write to the event device. When the application writes that ff data, we (as virtual device) need to read that data. Thus, whenever someone tries to read from the vuinput device, we need to read that data from the real uinput device.

<!-- gh-comment-id:4165762399 --> @joleuger commented on GitHub (Mar 31, 2026): Ok, I can reproduce the problem: ``` upload a simple RUMBLE effect Error reading in thread: Function not implemented (os error 38) thread 'main' (31163) panicked at vuinputd-tests/src/devices/xbox_gamepad.rs:197:30: called `Result::unwrap()` on an `Err` value: ETIMEDOUT stack backtrace: ``` I need to implement the read and poll functions of the cuse device to forward the data of the ff request, which contains the pattern. The applications actually write that data via a write to the event device. When the application writes that ff data, we (as virtual device) need to read that data. Thus, whenever someone tries to read from the vuinput device, we need to read that data from the real uinput device.
Author
Owner

@joleuger commented on GitHub (Apr 6, 2026):

I have implemented a simple poll function that should work for sunshine/inputtino. Should only work for that special case and might be a bit racy. I still need to work further on it and implement proper testing.

<!-- gh-comment-id:4195364267 --> @joleuger commented on GitHub (Apr 6, 2026): I have implemented a simple poll function that should work for sunshine/inputtino. Should only work for that special case and might be a bit racy. I still need to work further on it and implement proper testing.
Author
Owner

@joleuger commented on GitHub (Apr 14, 2026):

Ok, removed the code, because sunshine hangs during shutdown, see issue #12

I'll fix it, when I have the time to test. My current assumption is that a poll of sunshine is waiting for a response, but doesn't get it, when the device gets deleted to fast.

<!-- gh-comment-id:4246574823 --> @joleuger commented on GitHub (Apr 14, 2026): Ok, removed the code, because sunshine hangs during shutdown, see issue #12 I'll fix it, when I have the time to test. My current assumption is that a poll of sunshine is waiting for a response, but doesn't get it, when the device gets deleted to fast.
Author
Owner

@joleuger commented on GitHub (Apr 15, 2026):

Code is active again. Could not test it yet with a real gamepad, but at least fftest doesn't break

<!-- gh-comment-id:4256139048 --> @joleuger commented on GitHub (Apr 15, 2026): Code is active again. Could not test it yet with a real gamepad, but at least `fftest` doesn't break
Author
Owner

@joleuger commented on GitHub (Apr 16, 2026):

Fixed 100% cpu bug due to polling

<!-- gh-comment-id:4262882588 --> @joleuger commented on GitHub (Apr 16, 2026): Fixed 100% cpu bug due to polling
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
joleuger/vuinputd#8
No description provided.