<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 7 October 2015 at 18:16, 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:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">2015-10-07 18:30 GMT+02:00 David Turner <<a href="mailto:dct25-561bs@mythic-beasts.com">dct25-561bs@mythic-beasts.com</a>>:<br>
> Hi,<br>
><br>
> Why the non-threaded runtime, out of interest?<br>
<br>
</span>Mostly because i am used to the poll/select method I mentioned and that<br>
one works without any threading.<br>
I don't really mind using the threaded runtime though, it's more habit.<br>
<span class=""><br>
> Threads forked with forkIO are pretty lightweight, and although things look<br>
> like blocking calls from the Haskell point of view, as I understand it under<br>
> the hood it's all done with events of one form or another. Thus even with<br>
> the non-threaded runtime you will see forkIO-threads behaving as if they're<br>
> running concurrently. In particular, you have two threads blocked trying to<br>
> read from two different Handles and each will be awoken just when there's<br>
> data to read, and the rest of the runtime will carry on even while they're<br>
> blocked. Try it!<br>
<br>
</span>Yeah, I know and I tried that.<br>
As far as I can see, that's actually why things break with GHC.Event.<br>
The Event system tries to register the Fd while it was registered by me<br>
and encounters an EEXIST from epoll.<br>
<span class=""><br></span></blockquote><div><br></div><div>Ah, ok, so you can either do your epolling through the Haskell runtime or with your bare hands but you can't do both on a single FD.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">> If you're dealing with FDs that you've acquired from elsewhere, the function<br>
> unix:System.Posix.IO.ByteString.fdToHandle can be used to import them and<br>
> then they work like normal Handles in terms of blocking operations etc.<br>
><br>
> Whenever I've had to deal with waking up for one of a number of reasons (not<br>
> all of which are FDs) I've found the simplicity of STM is hard to beat.<br>
> Something like:<br>
><br>
> atomically ((Left <$> waitForFirstThing) <|> (Right <$> waitForSecondThing))<br>
<br>
</span>Looks like I should look up STM. Does this scale easily?<br>
I don't really need huge amounts, but I don't have any knowledge about the<br>
number of Fds I will have.<br></blockquote><div><br></div><div>Waiting on arbitrarily many things is pretty much as simple (as long as they all have the same type so you can put them in a list):</div><div><br></div><div>atomically (asum listOfWaitingThings)</div><div><br></div><div>In terms of code complexity that scales just fine! I'm afraid I've no real idea what the performance characteristics of such a device would be without trying it out in your use case. Whenever I've been doing this kind of thing I've always found myself IO-bound rather than CPU-bound so I've never found myself worrying too much about the efficiency of the code itself.</div><div><br></div><div>If you're used to doing select/poll things yourself then it may help to think of Haskell threads blocking on Handles as basically a way to do an epoll-based event loop on the underlying FDs but with a much nicer syntax and less mucking around with explicit continuations. Similarly, if you're used to dealing with task scheduling at a low level then it may help to think of STM transactions blocking as a way to muck around with the run queues in the scheduler but with a much nicer syntax and less mucking around with explicit continuations.</div><div><br></div><div><br></div><div><br></div><div>Best wishes,</div><div><br></div><div>David</div><div><br></div><div><br></div></div></div></div>