pyfuse3 currently does not appear to expose libfuse’s low-level poll notification support.
libfuse provides the relevant APIs:
fuse_reply_poll(req, revents)
fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)
fuse_pollhandle_destroy(struct fuse_pollhandle *ph)
However pyfuse3 does not seem to expose an Operations.poll() callback, a Python-visible poll handle object or a notify_poll() helper equivalent to fuse_lowlevel_notify_poll().
This is needed for filesystems that emulate interfaces where userspace relies on poll(2) / select(2) readiness notifications. One concrete example is a GPIO sysfs compatibility filesystem: /sys/class/gpio/gpioN/value should be pollable and edge events should wake a process waiting for POLLPRI.
The older fuse-python bindings support this through Fuse.NotifyPoll(pollhandle), which makes it possible to store a poll handle from the file’s poll() callback and later notify it when an event occurs.
A possible pyfuse3 API could look something like:
class Operations:
async def poll(self, inode, fh, poll_handle, ctx):
...
return select.POLLIN | select.POLLOUT | select.POLLPRI
and:
pyfuse3.notify_poll(poll_handle)
where poll_handle is a safe Python wrapper around struct fuse_pollhandle *.
A typical use case would be:
async def poll(self, inode, fh, poll_handle, ctx):
entry = self._inode_map[inode]
revents = entry.current_revents()
if poll_handle is not None:
entry.poll_handle = poll_handle
return revents
def notify_event(self, entry):
if entry.poll_handle is not None:
pyfuse3.notify_poll(entry.poll_handle)
entry.poll_handle = None
The tricky part is probably lifetime/ownership of the underlying struct fuse_pollhandle *, especially whether pyfuse3 should automatically destroy the handle after notification or expose an explicit close/destroy operation. But without this, it does not seem possible to implement proper poll wakeups using pyfuse3.
Would you be open to adding support for libfuse poll notifications in pyfuse3?
I am happy to help test this against a real use case. The concrete case I am looking at is migrating a GPIO sysfs compatibility proxy from fuse-python to pyfuse3, while preserving poll()/select() behaviour for GPIO value files, see brgl/gpiod-sysfs-proxy#4
pyfuse3 currently does not appear to expose libfuse’s low-level poll notification support.
libfuse provides the relevant APIs:
fuse_reply_poll(req, revents)fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph)fuse_pollhandle_destroy(struct fuse_pollhandle *ph)However pyfuse3 does not seem to expose an
Operations.poll()callback, a Python-visible poll handle object or anotify_poll()helper equivalent tofuse_lowlevel_notify_poll().This is needed for filesystems that emulate interfaces where userspace relies on
poll(2)/select(2)readiness notifications. One concrete example is a GPIO sysfs compatibility filesystem:/sys/class/gpio/gpioN/valueshould be pollable and edge events should wake a process waiting forPOLLPRI.The older
fuse-pythonbindings support this throughFuse.NotifyPoll(pollhandle), which makes it possible to store a poll handle from the file’spoll()callback and later notify it when an event occurs.A possible pyfuse3 API could look something like:
and:
where
poll_handleis a safe Python wrapper aroundstruct fuse_pollhandle *.A typical use case would be:
The tricky part is probably lifetime/ownership of the underlying
struct fuse_pollhandle *, especially whether pyfuse3 should automatically destroy the handle after notification or expose an explicit close/destroy operation. But without this, it does not seem possible to implement proper poll wakeups using pyfuse3.Would you be open to adding support for libfuse poll notifications in pyfuse3?
I am happy to help test this against a real use case. The concrete case I am looking at is migrating a GPIO sysfs compatibility proxy from
fuse-pythontopyfuse3, while preservingpoll()/select()behaviour for GPIO value files, see brgl/gpiod-sysfs-proxy#4