The File Alteration Monitor, or FAM for short, is an utility that monitors changes made to files and directories and delivers asynchronous notifications to applications interested in them. GNOME uses it to keep Nautilus windows in sync with the on-disk contents, among other uses. For example, if you have your home folder open, and you do touch ~/foo from a terminal, you can see how the folder immediately updates its status to show the new file.

FAM uses imon internally, a kernel facility found in IRIX and Linux that provides notifications of changes to files and directories asynchronously (the kernel sends you an event when a change happens). If imon is not supported, it falls back to manual polling: the daemon scans the files being monitored every 6 seconds to see if there have been any changes. Polling is the only way to go if the kernel does not provide you of better ways to receive notifications, but is a suboptimal solution (there is a small time frame where the data hold by the application and the data on-disk differ). And NetBSD, up until now, was using polling.

However, NetBSD (as well as OpenBSD) has the kqueue framework, which is similar to imon in functionality. Which are the differences between kqueue and imon? On one hand, kqueue monitors open file descriptors, while imon monitors inodes (this is a problem, as you'll see later). On the other hand, kqueue is handled entirely with system calls, while imon is managed through a pseudo-device (/dev/imon). There are probably many other differences, but these are the main ones AFAICT.

Unfortunately, FAM did not use this interface in these operating systems. This was not acceptable to me (Nautilus with the polling backend is very annoying), so I've been adding support to FAM to work with kqueue. It has not been a trivial task; first, I had to read the kqueue documentation to understand how it worked; I had to understand how the FAM code worked (more or less); and, at last, implement the funcionality (which I've done twice).

The main problem in implementing kqueue support is that FAM is coded with imon and polling in mind, which makes the use of other event notification mechanisms quite difficult. Not to say that the code is not very easy to understand (in fact, some comments in the code tell you that it's messy).

So, what I have done is simulate an imon interface using kqueue. The IMonKQueue.c++ file, which you can find here, contains a good description on how the "emulation" works (it's not worth to repeat it here). I'd suggest you reading it, testing it, and spotting any errors you find ;-)

Go to posts index

Comments from the original Blogger-hosted post: