
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.
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.
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.
Andi
On Sat, Oct 11, 2014 at 9:31 AM, Andreas Voellmy
On Sat, Oct 11, 2014 at 1:07 AM, Ben Gamari
wrote: Thanks for your quick reply!
Andreas Voellmy
writes: On Sat, Oct 11, 2014 at 12:17 AM, Ben Gamari
wrote: I'm a bit perplexed as to why the change was made in the way that it was. Making one-shot a event-manager-wide attribute seems to add a
fair
bit of complexity to the subsystem while breaking backwards compatibility with library code.
It added some complexity to the IO manager, but that should not affect clients except those using the internal interface.
What I'm wondering is what the extra complexity bought us. It seems like the same thing could have been achieved with less breakage by making this per-fd instead of per-manager. I may be missing something, however.
Generally, ONE_SHOT helped improve performance. I agree with you that it may be possible to do this on a per-FD basis. I'll look into what it would take to do this.
Going forward library authors now need to worry about whether the system event manager is one-shot or not.
Yes, but only library authors using the internal interface.
Not only is this platform dependent but it seems that there is no way for a user to determine which semantics the system event handler uses.
Is there a reason why one-shot wasn't exported as a per-fd attribute instead of per-manager? Might it be possible to back out this change
instead add a variant of `registerFd` which exposes one-shot semantics?
The system event manager is configured by GHC.Thread using ONE_SHOT if
and the
system supports it.
You can always create your own EventManager using GHC.Event.Manager.new or GHC.Event.Manager.newWith functions. Those functions take a Bool argument that control whether ONE_SHOT is used by the Manager returned by that function (False means not to use ONE_SHOT). Would this work for usb?
I had considered this but looked for other options for two reasons,
* `loop` isn't exported by GHC.Event
Right - it wouldn't make sense to export the system EventManager's loop. However, the GHC.Event.Manager module does export its loop function, so if you create your own non-ONE_SHOT event manager, you can just invoke its loop function.
* there is already a perfectly usable event loop thread in existence
I'm a bit curious to know what advantages ONE_SHOT being per-manager carries over per-fd. If the advantages are large enough then we can just export `loop` and be done with it but the design as it stands strikes me as a bit odd.
I suspect that a per-FD design would perform just as well, but I need to look at the details to be sure.
Cheers,
- Ben