One-shot semantics in GHC event manager

Ben Gamari bgamari.foss at
Sat Oct 11 15:52:48 UTC 2014

Andreas Voellmy <andreas.voellmy at> writes:

> Another way to fix usb would be to re-register the callback after a
> previously registered callback is fired. Of course it is cheaper not to
> have to re-register, but re-registration in the latest IO manager should be
> fairly cheap, so this may not be a performance problem for usb. Would this
> work for you?
> You could also use a CPP directive to only do this for GHC 7.8 and up.
This is a possibility that I had considered. It would require that some
code be reworked however.

I'm leaning towards just using our non-event-manager-driven fallback
path on GHC 7.8 for now until the event manager semantics can be worked

> If we want to allow usb to work unchanged, then we will have to revert to
> the non-ONE_SHOT behavior of registerFd and add some things to the API to
> allow GHC.Thread to register with ONE_SHOT behavior. Reverting could break
> clients of this semi-public API who have adapted to the 7.8 behavior.
> There probably aren't of these clients other than GHC.Thread, so this may
> not be a big issue.
I don't think we need to revert the changes just for usb as we have the
fallback path that will work for now. I do think it might be good
to explore other points in the design space, however.

> To do per-FD setting of ONE_SHOT or not, we actually need to have
> per-subscription settings, since there can be multiple invocations to
> register callbacks for a single file descriptor (e.g. from two different
> threads) and they might want different settings.

> If all the clients want
> ONE_SHOT we use ONE_SHOT registration, if all want persistent registrations
> we don't use ONE_SHOT. If it is mixed, then the manager has to choose one
> or the other and simulate the required behavior for the other registrations
> (e.g. choose persistent and automatically unregister for ONE_SHOT
> registrations). We could either always make the same choice (e.g. if there
> is a mix, use persistent), or we could have per-FD setting that is
> configurable by clients.
I would think we would actually want the desired one-shottedness to be a
property of the registration. We would have,

    -- | Will this registration be valid until unregistration ('ManyShot')
    -- or only for a single event ('OneShot')?
    data Lifetime = OneShot | ManyShot

    registerFd :: EventManager -> Fd -> Event -> Lifetime -> IO FdKey
The event manager would then have to choose either ONE_SHOT or not in
the case of heterogenous registrations and emulate the other set, as you

This seems like a nice interface as it allows the user to specify
the semantics that they want (instead of working around whatever the
manager happens to provide) and gives the the event manager enough
knowledge and freedom to do what it can to efficiently implement what is


- Ben
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 472 bytes
Desc: not available
URL: <>

More information about the ghc-devs mailing list