<div dir="ltr">Hi,<div><br></div><div>Why the non-threaded runtime, out of interest?</div><div><br></div><div>Threads forked with forkIO are pretty lightweight, and although things look like blocking calls from the Haskell point of view, as I understand it under the hood it's all done with events of one form or another. Thus even with the non-threaded runtime you will see forkIO-threads behaving as if they're running concurrently. In particular, you have two threads blocked trying to read from two different Handles and each will be awoken just when there's data to read, and the rest of the runtime will carry on even while they're blocked. Try it!</div><div><br></div><div>If you're dealing with FDs that you've acquired from elsewhere, the function <font face="monospace, monospace">unix:System.Posix.IO.ByteString.</font><a name="v:fdToHandle" class="" style="font-size:13px;margin:0px;padding:0px;color:rgb(0,0,0);line-height:16.12px"><font face="monospace, monospace">fdToHandle</font></a> can be used to import them and then they work like normal Handles in terms of blocking operations etc.</div><div><br></div><div>Whenever I've had to deal with waking up for one of a number of reasons (not all of which are FDs) I've found the simplicity of STM is hard to beat. Something like:</div><div><br></div><div><font face="monospace, monospace">atomically ((Left <$> waitForFirstThing) <|> (Right <$> waitForSecondThing))</font></div><div><br></div><div>where <font face="monospace, monospace">waitForFirstThing </font>and <font face="monospace, monospace">waitForSecondThing </font>are blocked waiting for something interesting to occur in a TVar that they're watching. It's so simple that I reckon it's worth doing it like that and only trying something more complicated if it turns out from experimentation that this has too much overhead for you - "make it right" precedes "make it fast".</div><div><br></div><div>Hope that helps,</div><div><br></div><div>David</div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 7 October 2015 at 08:49, Markus Ongyerth <span dir="ltr"><<a href="mailto:ongy44@gmail.com" target="_blank">ongy44@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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>
<br>_______________________________________________<br>
Glasgow-haskell-users mailing list<br>
<a href="mailto:Glasgow-haskell-users@haskell.org">Glasgow-haskell-users@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users</a><br>
<br></blockquote></div><br></div>