This is a fork of the since-deleted golang.org/x/exp/inotify
package. It breaks the API in an attempt to fix some reliability
problems:
-
inotify watches are attached to inodes rather than file paths. A single inode could have multiple file paths, or change its file path between when it is watched and when events are generated.
-
AddWatchnow returns a*Watchrepresenting the watch descriptor. Watches can be compared by pointer equality, as only one watch struct will be used for each watch descriptor. For convenience, the watch stores the path it was created for. -
There is no attempt to automatically use
IN_MASK_ADD. The previous behaviour was unreliable, so you'll need to specify it manually if desired. -
Eventnow includes aWatchfield for its associated watch (or nil for events not associated with a watch likeIN_Q_OVERFLOW). TheNamefield is no longer prefixed with the watch's path. -
The
Watcher.Errorchannel has been removed. Errors are now reported whenCloseis called. -
The Watcher's mutex is now used to guard all access to the watches map.
-
When
RemoveWatchis called, we don't completely forget about the watch until we receive an associatedIN_IGNOREDevent. This way any queued events for the old watch can be correctly decoded. -
Reads from the inotify instance are performed through an
*os.File. This should take advantage of the Go runtime's IO polling system and stop thereadEventsgoroutine from tieing up an OS thread.
There is still a potential concurrency issue with the approach I've taken. Imagine this sequence of events:
- user calls
RemoveWatchfor watch descriptor N - the
Readcall in thereadEventsgoroutine returns with events for watch descriptor N - user calls
AddWatch, which happens to reuse watch descriptor N - the
readEventsgoroutine acquires the lock to decode the events it received
With this sequence of events, it would be unclear which watch the
event belonged to. According to this LKML post, watch descriptors
are allocated sequentially, and can only be reused after they wrap at
INT_MAX. So this is unlikely to be a problem in practice.