Event Manager: Make one-shot a per-registration property
authorBen Gamari <bgamari.foss@gmail.com>
Mon, 12 Jan 2015 23:36:23 +0000 (18:36 -0500)
committerBen Gamari <bgamari.foss@gmail.com>
Mon, 12 Jan 2015 23:36:23 +0000 (18:36 -0500)
commit023439980f6ef6ec051f676279ed2be5f031efe6
tree33c19b6f0654c8f2cb0a1ea9555ad6fb79dc94c0
parent8464fa29e677e6845ca96d21474840803218f0b9
Event Manager: Make one-shot a per-registration property

Summary:
Currently the event manager has a global flag for whether to create
epoll-like notifications as one-shot (e.g. EPOLLONESHOT, where an fd
will be deactivated after its first event) or standard multi-shot
notifications.

Unfortunately this means that the event manager may export either
one-shot or multi-shot semantics to the user. Even worse, the user has
no way of knowing which semantics are being delivered. This resulted in
breakage in the usb[1] library which deadlocks after notifications on
its fd are disabled after the first event is delivered.  This patch
reworks one-shot event support to allow the user to choose whether
one-shot or multi-shot semantics are desired on a per-registration
basis. The event manager can then decide whether to use a one-shot or
multi-shot epoll.

A registration is now defined by a set of Events (as before) as well as
a Lifetime (either one-shot or multi-shot). We lend monoidal structure
to Lifetime choosing OneShot as the identity. This allows us to combine
Lifetime/Event pairs of an fd to give the longest desired lifetime of
the registration and the full set of Events for which we want
notification.

[1] https://github.com/basvandijk/usb/issues/7

Test Plan: Add more test cases and validate

Reviewers: tibbe, AndreasVoellmy, hvr, austin

Reviewed By: austin

Subscribers: thomie, carter, simonmar

Differential Revision: https://phabricator.haskell.org/D347
libraries/base/GHC/Event.hs
libraries/base/GHC/Event/IntTable.hs
libraries/base/GHC/Event/Internal.hs
libraries/base/GHC/Event/Manager.hs
libraries/base/GHC/Event/Thread.hs