I've taken a cue from Arne's inotify module and have started working on one for kqueue based systems. The code basically works but suffers from a (imho) major drawback: it's not integrated with the Pike backend.
The inotify code slides nicely into the backend, primarily because inotify presents itself as a standard fd with a read data event to indicate events. kqueue, however, uses different event types monitored by kqueue.
Right now, a secondary kqueue loop can be run in a thread to wait for events, but that seems pretty ugly to me. I'd like to find a better approach.
An alternate approach might be to hook a second, immediate-timeout call to kqueue() into the backend, similar to the GTK or ObjectiveC module. That's a little better, as at least the end user sees a more consistent approach to asynchronous events. Internally, I think it probably at least less efficient, with other possible drawbacks.
I think the nicest approach would be to modify the kqueue backend so that it can register VNODE, PROC and SIGNAL filters and shunt them off to an appropriate handler. That, however, means that the backend would be split again (creating a KqueueBackend or similar), with the new implementation having different features.
If anyone's interested in looking at the code, it's available here:
https://bitbucket.org/hww3/public_system_kqueue/
I should note that I've commited some changes today away from my development box, so it's likely that the last few revisions have errors in them.
Does anyone else have thoughts about these approaches (or have an alternate one?) Perhaps I've missed something obvious... it wouldn't be the first time!
Best,
Bill
I've taken a cue from Arne's inotify module and have started working on one for kqueue based systems. The code basically works but suffers from a (imho) major drawback: it's not integrated with the Pike backend.
[...]
I think the nicest approach would be to modify the kqueue backend so that it can register VNODE, PROC and SIGNAL filters and shunt them off to an appropriate handler. That, however, means that the backend would be split again (creating a KqueueBackend or similar), with the new implementation having different features.
[...]
Does anyone else have thoughts about these approaches (or have an alternate one?) Perhaps I've missed something obvious... it wouldn't be the first time!
Have you looked closer at backend.cmod? There is already a backend variant using kqueue...
/grubba
I wasn't sure if hacking the existing kqueue backend alone would do the trick. I imagine that for consistency, you'd also want something like
Stdio.File()->set_event_callback(cb, FLAGS);
right? If so, then, what about the other event types you can use kqueue to follow, like signals and process events?
Messing around with the backend is a little more advanced than I've undertaken in the past, but I'd be willing to play around with it in my spare time, if I had a good idea of what it out to look like.
Bill
On Tue, 29 Nov 2011, Henrik Grubbström (Lysator) @ Pike (-) developers forum wrote:
Have you looked closer at backend.cmod? There is already a backend variant using kqueue...
/grubba
I've taken an initial shot at modifying Stdio.Fd and the Backend to support filesystem events using kqueue. It's not complete, but it doesn't seem to break anything at this point. I'm mostly interested in (implementation and design) feedback:
http://bill.welliver.org/dist/kqueue_events_7.8.601.diff
Some details off the top of my head:
1. adds constants for the VNODE events defined by kqueue() when it's present. These are present in files, and thus show up in Stdio. There's a constant __HAVE_FS_EVENTS__ that indicates whether the flags should be present. Would it make sense for these flags to be generic rather than kqueue specific?
2. adds set_fs_event_callback(cb, event_mask) to Stdio.Fd. The callback receives the event mask that triggered the event.
3. fs event callbacks are only triggered when the backend is running.
4. currently, the pike level glue to make it behave like the other callbacks is not present, and i'm not sure the extent to which that should be included. For example, it is probably not feasible to add support to set_callbacks(), as the event mask would also need to be set somehow, etc.
5. there's no way to un-register a given fs event currently, though set_blocking() and set_nonblocking() both seem to disable the events.
6. the callbacks are always present but obviously don't result in any events if you're not using a kqueue backend.
7. there's currently no way to retrieve the event mask. Not sure the best way to do this, as the event mask is really only stored in the fd_callback_box or the kernel (where it's really inaccessible).
8. i'd eventually like to add support for process, signal and timer events, but they'd probably have to be added as methods to the backend directly, as they don't involve an fd.
Example:
int main() { s = Stdio.File("/tmp/t1"); s->set_fs_event_callback(lambda(mixed ...args){werror("%O\n", args);}, Stdio.NOTE_WRITE|Stdio.NOTE_RENAME); return -1; }
As always, comments and suggestions are most appreciated!
Bill
pike-devel@lists.lysator.liu.se