
Hi, I'm writing a program which listens to some D-Bus signals using DBus.Client.onSignal function from dbus-client package. This function runs IO action in separate haskell thread when signal is received. My program does nothing except signal handling, so after setting up signals it has to wait indefinitely. Now I'm using not very clean (I think so) forever $ threadDelay 10000000 . Is there another (I mean, correct) method to do this thing?

dpx.infinity:
Hi, I'm writing a program which listens to some D-Bus signals using DBus.Client.onSignal function from dbus-client package. This function runs IO action in separate haskell thread when signal is received. My program does nothing except signal handling, so after setting up signals it has to wait indefinitely. Now I'm using not very clean (I think so) forever $ threadDelay 10000000 . Is there another (I mean, correct) method to do this thing?
Block on an MVar that will be set by the child thread when it terminates? main = do done <- newEmptyMVar forkIO $ do ... child code ... putMVar done () takeMVar done print "Child is done"

On Mon, May 17, 2010 at 7:12 PM, Don Stewart
dpx.infinity:
Hi, I'm writing a program which listens to some D-Bus signals using DBus.Client.onSignal function from dbus-client package. This function runs IO action in separate haskell thread when signal is received. My program does nothing except signal handling, so after setting up signals it has to wait indefinitely. Now I'm using not very clean (I think so) forever $ threadDelay 10000000 . Is there another (I mean, correct) method to do this thing?
Block on an MVar that will be set by the child thread when it terminates?
main = do done <- newEmptyMVar
forkIO $ do ... child code ... putMVar done ()
takeMVar done print "Child is done"
Note that this code will dead-lock on the takeMVar if 'child code' throws an exception. Our threads package correctly handles this by installing an exception handler around 'child code' that ensures that putMVar will always be called: http://hackage.haskell.org/packages/archive/threads/0.1/doc/html/src/Control... (make sure your browser uses UTF8 encoding otherwise some characters get screwed up) BTW A new version of threads will be released in a couple of days that will replace all the MVars by TMVars. This enables us to get rid of "interruptible" operations like takeMVar that may throw asynchronous exceptions even in the scope of a block. If you can't wait: darcs get http://code.haskell.org/~basvandijk/code/threads Regards, Bas

On Mon, May 17, 2010 at 10:04 AM, DPX-Infinity
Hi, I'm writing a program which listens to some D-Bus signals using DBus.Client.onSignal function from dbus-client package. This function runs IO action in separate haskell thread when signal is received. My program does nothing except signal handling, so after setting up signals it has to wait indefinitely. Now I'm using not very clean (I think so) forever $ threadDelay 10000000 . Is there another (I mean, correct) method to do this thing?
You could ask yourself why you need a child thread if the main thread doesn't do anything else. I presume you're at a step in the development of something larger and that you'll eventually have a use for the main thread... otherwise the child thread is buying you nothing. Dave
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Author of dbus-client here. Don Stewart's solution (blocking on an
mvar) is the best way to handle it. Presumably, you've got some way to
make your program shut down (method call? signal handler?) -- just set
the mvar in that.
On Mon, May 17, 2010 at 11:07, David Leimbach
You could ask yourself why you need a child thread if the main thread doesn't do anything else. I presume you're at a step in the development of something larger and that you'll eventually have a use for the main thread... otherwise the child thread is buying you nothing. Dave
DBus is an asynchronous protocol; running signal handlers in a common thread would let one long-running computation block receipt of any others.

On Mon, May 17, 2010 at 2:37 PM, John Millikin
Author of dbus-client here. Don Stewart's solution (blocking on an mvar) is the best way to handle it. Presumably, you've got some way to make your program shut down (method call? signal handler?) -- just set the mvar in that.
You could ask yourself why you need a child thread if the main thread doesn't do anything else. I presume you're at a step in the development of something larger and
On Mon, May 17, 2010 at 11:07, David Leimbach
wrote: that you'll eventually have a use for the main thread... otherwise the child thread is buying you nothing. Dave
DBus is an asynchronous protocol; running signal handlers in a common thread would let one long-running computation block receipt of any others.
Is there not a way to multiplex the signal handlers into one thread, and then dispatch new threads to do the work when events that require such concurrency occur? That would be the initial way I'd structure such a program. In fact, if the results of a computation based on a signal aren't even needed immediately, one could rely on the fact that Haskell is a non-strict language to partially evaluate an expression and get to it later when it's really needed. Haskell has "built in Futures" of a sort. That may not be appropriate depending on the processing at hand, but it's worth noting that it's possible. Dave

On Mon, May 17, 2010 at 19:41, David Leimbach
Is there not a way to multiplex the signal handlers into one thread, and then dispatch new threads to do the work when events that require such concurrency occur? That would be the initial way I'd structure such a program.
All signals, method calls, method returns, etc are read from the socket in a single thread. If some computation needs to be performed, a thread is spawned. There's no "thread pool", and I doubt such a construct would provide any benefit.
In fact, if the results of a computation based on a signal aren't even needed immediately, one could rely on the fact that Haskell is a non-strict language to partially evaluate an expression and get to it later when it's really needed. Haskell has "built in Futures" of a sort. That may not be appropriate depending on the processing at hand, but it's worth noting that it's possible.
I'm not sure what partial evaluation has to do with anything under discussion. If received messages are processed in the same thread, then some long-running computation would block that thread (and, hence, message reception). This occurs regardless of exactly when the computation is performed, relative to its declaration. Removing the fork from within the signal/method dispatcher would simply force every user to write "forkIO $ ..." everywhere.

On Tue, May 18, 2010 at 7:08 AM, John Millikin
On Mon, May 17, 2010 at 19:41, David Leimbach
wrote: Is there not a way to multiplex the signal handlers into one thread, and then dispatch new threads to do the work when events that require such concurrency occur? That would be the initial way I'd structure such a program.
All signals, method calls, method returns, etc are read from the socket in a single thread. If some computation needs to be performed, a thread is spawned. There's no "thread pool", and I doubt such a construct would provide any benefit.
I think you just said the same thing I just said. So are we arguing? I'm kind of confused. "If some computation needs to be performed, a thread is spawned" is very similar to what I just said about multiplexing the signal handling into one thread and spawning worker threads. I never mentioned a thread pool, and agree with you that it probably doesn't make any sense in this discussion. It might just be that I don't know anything about your DBus library that's causing this discussion to go this way. Let me look at it and get back to you.
In fact, if the results of a computation based on a signal aren't even needed immediately, one could rely on the fact that Haskell is a non-strict language to partially evaluate an expression and get to it later when it's really needed. Haskell has "built in Futures" of a sort. That may not be appropriate depending on the processing at hand, but it's worth noting that it's possible.
I'm not sure what partial evaluation has to do with anything under discussion. If received messages are processed in the same thread, then some long-running computation would block that thread (and, hence, message reception). This occurs regardless of exactly when the computation is performed, relative to its declaration. Removing the fork from within the signal/method dispatcher would simply force every user to write "forkIO $ ..." everywhere.
When I think of Haskell, I think of laziness and partial evaluation, so to me it's always on topic. Maybe that's because I've been bitten by assuming strictness where it doesn't exist and had ridiculously bad data leaks in my code as a result. What I've been trying to come to terms with is a way to leverage the laziness rather than constantly striving to turn it off so I get reasonable runtime footprint of my Haskell programs. Dave

On Tue, May 18, 2010 at 8:06 AM, David Leimbach
On Tue, May 18, 2010 at 7:08 AM, John Millikin
wrote: On Mon, May 17, 2010 at 19:41, David Leimbach
wrote: Is there not a way to multiplex the signal handlers into one thread, and then dispatch new threads to do the work when events that require such concurrency occur? That would be the initial way I'd structure such a program.
All signals, method calls, method returns, etc are read from the socket in a single thread. If some computation needs to be performed, a thread is spawned. There's no "thread pool", and I doubt such a construct would provide any benefit.
I think you just said the same thing I just said. So are we arguing? I'm kind of confused. "If some computation needs to be performed, a thread is spawned" is very similar to what I just said about multiplexing the signal handling into one thread and spawning worker threads.
I never mentioned a thread pool, and agree with you that it probably doesn't make any sense in this discussion.
It might just be that I don't know anything about your DBus library that's causing this discussion to go this way. Let me look at it and get back to you.
I've taken a few minutes to look through the documentation and dbus-core stuff on Hackage (quite nice by the way!!!), and I get where this is all going finally. The original poster of this thread asked a generic question about making a thread wait and synchronize with another, but the thread in question didn't do anything so I could not figure out why on earth anyone would want to do that. I think I see now that your library takes registered handlers to run and that there is nothing to be done in the main thread if you're just gathering events and dealing with them in each handler thread. For the application at hand, you're correct on all points. I was trying to have a more general discussion of what might be possible in other frameworks assuming nothing about their design. Sorry if I derailed the thread. At least it's given me a couple of ideas for things to try out, and I learned a little something about DBus. Dave

On Tue, May 18, 2010 at 08:06, David Leimbach
I think you just said the same thing I just said. So are we arguing? I'm kind of confused. "If some computation needs to be performed, a thread is spawned" is very similar to what I just said about multiplexing the signal handling into one thread and spawning worker threads. I never mentioned a thread pool, and agree with you that it probably doesn't make any sense in this discussion. It might just be that I don't know anything about your DBus library that's causing this discussion to go this way. Let me look at it and get back to you.
This might be a terminology problem. A "signal handler" is a computation (an IO value) which is performed when a signal message is received. It doesn't make any sense to run signal handlers in one thread, because each handler might take an arbitrary amount of time to execute. I read your email as suggesting that handlers should be run in a single thread, with additional threads being pooled/spawned when the developer suspects some handler might take a significant amount of time. In theory this would be identical to giving each handler its own thread, but I suspect that it would simply make it more likely for inexperienced developers to accidentally block their socket.

Use our threads package [1].
import Control.Concurrent.Thread ( forkIO, wait_ )
myDBusThingie :: IO ()
myDBusThingie = error "TODO"
main :: IO ()
main = do tid <- forkIO myDBusThingie
wait_ tid
But like David said, this is only usefull if you plan on multiple
concurrent waits or doing some other work during the wait. Otherwise
you can simply replace the contents of main with myDBusThingie.
Regards,
Roel
1 - http://hackage.haskell.org/package/threads (new, backwards
compatible, version will be released soon)
On Mon, May 17, 2010 at 7:04 PM, DPX-Infinity
Hi, I'm writing a program which listens to some D-Bus signals using DBus.Client.onSignal function from dbus-client package. This function runs IO action in separate haskell thread when signal is received. My program does nothing except signal handling, so after setting up signals it has to wait indefinitely. Now I'm using not very clean (I think so) forever $ threadDelay 10000000 . Is there another (I mean, correct) method to do this thing? _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (6)
-
Bas van Dijk
-
David Leimbach
-
Don Stewart
-
DPX-Infinity
-
John Millikin
-
Roel van Dijk