threadWaitRead and threadWaitWrite on multiple fds

Hi all, I read the paper about the new ghc7 event handling IO manager goodies. This is all very exciting stuff. I didn't know GHC's RTS had these smart async-IO facilities. The paper pointed me at threadWaitRead/threadWaitWrite. While very nice the way they are, I would also like to be able to wait on more than 1 fd until 1 of them becomes available. Would it be possible to create this functionality myself? Or do I need to request it and wait for a new GHC? It looks like the functionality I need is in System/Event/Thread. I think I can manage to write my own version of those functions which then loop through a list of fds, but the original file imports System/Event/Manager (registerFd, unregisterFd_) which I can't do because it's a hidden module. Is there a way around this? Thanks, Mathijs

On Sun, Dec 12, 2010 at 6:37 PM, Mathijs Kwik
Hi all,
I read the paper about the new ghc7 event handling IO manager goodies. This is all very exciting stuff. I didn't know GHC's RTS had these smart async-IO facilities. The paper pointed me at threadWaitRead/threadWaitWrite. While very nice the way they are, I would also like to be able to wait on more than 1 fd until 1 of them becomes available.
Would it be possible to create this functionality myself? Or do I need to request it and wait for a new GHC? It looks like the functionality I need is in System/Event/Thread. I think I can manage to write my own version of those functions which then loop through a list of fds, but the original file imports System/Event/Manager (registerFd, unregisterFd_) which I can't do because it's a hidden module. Is there a way around this?
Can you do it with forkIO? That is, have two light-weight threads, each waiting on a different fd, which perform the same action when one of them wakes up. Maybe that would become too hard to synchronize the threads together, but it might be the first thing to try before delving into GHC internals. Take care, Antoine
Thanks, Mathijs
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Hi!
On Mon, Dec 13, 2010 at 2:14 AM, Antoine Latter
Can you do it with forkIO? That is, have two light-weight threads, each waiting on a different fd, which perform the same action when one of them wakes up.
Or you could wait for each fd in its own thread (those are really light-weight threads) and once some is triggered you spawn another thread which deals with the event, while the original thread goes back into the waiting. Or you can also send data over Chan to another thread which then processes the even (if you need to serialize processing). Mitar

Yep, that's like the workaround I'm using right now.
I create an empty mvar, fire up 2 threads that will wait for an fd and
tryPutMVar afterwards.
My original thread justs gets the MVar to wait for any of the 2
fd-waiting-threads to complete.
But however light threads may be, I still think this might give some
overhead, and it's almost the same trick that System/Event/Thread is
using internally, although in that case, the putMVar is performed by
the event manager thread.
As far as I can tell, the behavior isn't hard-coded in the RTS (no
need to change that), but applications that use base will tell it to
use the mvar-trick as callback. That's why I was hoping to be able to
just tell it to use a different callback.
But indeed it's a solution for now.
I'll just post a feature-request for GHC.
Thanks
On Mon, Dec 13, 2010 at 3:19 AM, Mitar
Hi!
On Mon, Dec 13, 2010 at 2:14 AM, Antoine Latter
wrote: Can you do it with forkIO? That is, have two light-weight threads, each waiting on a different fd, which perform the same action when one of them wakes up.
Or you could wait for each fd in its own thread (those are really light-weight threads) and once some is triggered you spawn another thread which deals with the event, while the original thread goes back into the waiting. Or you can also send data over Chan to another thread which then processes the even (if you need to serialize processing).
Mitar

Just to reply to myself once again,
System.Event (which isn't hidden) re-exports (un)registerFd and other
functions I need for this.
So I can implement all this myself. The only thing I can't do is ask
the RTS's eventmanager to watch the fds for me, but I can just create
my own ("new" constructor is exposed as well) to keep all fd-watching
in 1 thread.
So it seems just enough functionality is exposed to do what I'm after.
Those GHC devs must be clever guys :)
On Mon, Dec 13, 2010 at 8:24 AM, Mathijs Kwik
Yep, that's like the workaround I'm using right now. I create an empty mvar, fire up 2 threads that will wait for an fd and tryPutMVar afterwards. My original thread justs gets the MVar to wait for any of the 2 fd-waiting-threads to complete. But however light threads may be, I still think this might give some overhead, and it's almost the same trick that System/Event/Thread is using internally, although in that case, the putMVar is performed by the event manager thread. As far as I can tell, the behavior isn't hard-coded in the RTS (no need to change that), but applications that use base will tell it to use the mvar-trick as callback. That's why I was hoping to be able to just tell it to use a different callback.
But indeed it's a solution for now. I'll just post a feature-request for GHC.
Thanks
On Mon, Dec 13, 2010 at 3:19 AM, Mitar
wrote: Hi!
On Mon, Dec 13, 2010 at 2:14 AM, Antoine Latter
wrote: Can you do it with forkIO? That is, have two light-weight threads, each waiting on a different fd, which perform the same action when one of them wakes up.
Or you could wait for each fd in its own thread (those are really light-weight threads) and once some is triggered you spawn another thread which deals with the event, while the original thread goes back into the waiting. Or you can also send data over Chan to another thread which then processes the even (if you need to serialize processing).
Mitar

On Mon, Dec 13, 2010 at 9:06 AM, Mathijs Kwik
Just to reply to myself once again,
System.Event (which isn't hidden) re-exports (un)registerFd and other functions I need for this. So I can implement all this myself. The only thing I can't do is ask the RTS's eventmanager to watch the fds for me, but I can just create my own ("new" constructor is exposed as well) to keep all fd-watching in 1 thread.
So it seems just enough functionality is exposed to do what I'm after. Those GHC devs must be clever guys :)
Bryan and I intend the System.Event API to become more official in the future. It's not quite portable to other implementations yet so you should consider it to be GHC specific (like GHC.Conc) for now. Johan

On Mon, Dec 13, 2010 at 1:37 AM, Mathijs Kwik
Hi all,
I read the paper about the new ghc7 event handling IO manager goodies. This is all very exciting stuff. I didn't know GHC's RTS had these smart async-IO facilities. The paper pointed me at threadWaitRead/threadWaitWrite. While very nice the way they are, I would also like to be able to wait on more than 1 fd until 1 of them becomes available.
You can fork a thread per fd and have the first thread that wakes up kill the other threads using asynchronous exceptions. This is how e.g. System.Timeout.timeout works. Johan
participants (4)
-
Antoine Latter
-
Johan Tibell
-
Mathijs Kwik
-
Mitar