<div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div>Hi,</div><div><br></div>the last few days, I tried to get an IO-Event system running with GHC i.e. trigger an IO action when there is data to read from a fd.<br></div>I looked at a few different implementations, but all of them have some downside.<br><br></div> * using select package<br></div>   - This uses the select syscall. select is rather limited (fd cannot be >1024)<br></div><div><br></div><div> * using GHC.Event<br></div><div>   - GHC.Event is broken in 7.10.1 (unless unsafeCoerce and a hacky trick are used)<br></div><div>   - GHC.Event is GHC internal according to hackage<br></div><div>   - Both Network libraries I looked at (networking (Network.Socket) and socket (System.Socket)) crash the application with GHC.Event<br></div><div>    - with 7.8+ I didn't see a way to create your own EventManager, so it only works with -threaded<br><br></div><div> * using forkIO and threadWaitRead for each fd in a loop</div><div>    - needs some kind of custom control structure around it<br></div><div>    - uses a separate thread for each fd<br></div><div>    - might become pretty awkward to handle multiple events<br></div><div><br></div> * using poll package<br></div>   - blocks in a safe foreign call<br></div>   - needs some kind of wrapper<br><br><br></div>From the above list, GHC.Event isn't usable (for me) right now. It would require some work for my usecase.<br></div>The select option is usable, but suffers from the same problems as poll + the limitation mentioned, so it is strictly worse.<br><br></div>This leaves me with two options: poll and forkIO + blocking.<br><br></div>Those are based on two completely different approaches to event handling..<br><br></div>poll can be used in a rather classic event handling system with a main loop that blocks until an event occurs (or a timeout triggers) and handles the event in the loop.<br></div>forkIO + blocking is closer to registering an action later that should be triggered by an event.<br><br></div>My main questions right now are:<br></div>1. How bad is it for the (non-threaded) runtime to be blocking in a foreign call most of the time?<br></div>2. How significant will the overhead be for the forkIO version?<br></div>3. Is there a *good* way to use something like threadWaitRead that allows to wake up on other events as well?<br></div>4. Is there a better way to handle multiple fds that may get readable data at any time, in Haskell/with GHC right now?<br><br></div>Thanks in advance,<br></div>Ongy<br></div>