Re: [Haskell-cafe] timely shutdown of timer threads

2011-02-02 Thread Warren Harris
Interesting. I hadn't thought of this solution. You're forking the timer to yet 
a third thread so that if it continues waiting beyond the checkpoint thread 
shutdown it doesn't really matter. I guess that works as long as the main 
thread doesn't wait for all other threads to terminate before terminating the 
app.

It still seems to me that haskell is lacking when it comes to operations that 
can wait for multiple conditions.

Warren


On Feb 1, 2011, at 6:25 PM, Albert Y. C. Lai wrote:

 On 11-02-01 02:58 PM, Warren Harris wrote:
 I have an application that forks a thread to run an activity on a timer. 
 (The activity happens to be Berkeley DB checkpointing, but that's actually 
 beside the point here.) The problem is that when the application wants to 
 quit, I would like my main thread to be able to tell the timer thread to 
 shut down in a timely way. However, I don't see a primitive in haskell that 
 allows me to both wait for a timeout, or a notification. (If I were to do 
 this in java, I would use wait/notify.)
 
 Use an MVar for signalling; use a two-valued data type to represent 
 time-to-work or time-to-die. For extra correctness, use a second MVar to be 
 notified that the child thread is really done --- because otherwise there 
 would be the race condition of the child thread still in the middle of 
 critical I/O when the program quits.
 
 import Control.Concurrent
 import Control.Exception(finally)
 
 data DoOrDie = Do | Die
 
 main = do
  v - newEmptyMVar
  finale - newEmptyMVar
  forkIO (timeloop v `finally` putMVar finale ())
  putStrLn press enter to quit
  getLine
  putMVar v Die
  takeMVar finale
 
 timeloop v = run where
  run = do
forkIO (threadDelay 1500  putMVar v Do)
m - takeMVar v
case m of
  Do - putStrLn checkpoint  run
  Die - putStrLn checkmate
 
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] timely shutdown of timer threads

2011-02-02 Thread Johan Tibell
On Wed, Feb 2, 2011 at 10:42 PM, Warren Harris warrensomeb...@gmail.com wrote:
 Interesting. I hadn't thought of this solution. You're forking the timer to 
 yet a third thread so that if it continues waiting beyond the checkpoint 
 thread shutdown it doesn't really matter. I guess that works as long as the 
 main thread doesn't wait for all other threads to terminate before 
 terminating the app.

 It still seems to me that haskell is lacking when it comes to operations that 
 can wait for multiple conditions.

I think we can make waiting for both I/O activity and timers at the
same time using the I/O manager. I will need to do this for my planned
timeout support in the network package.

Johan

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] timely shutdown of timer threads

2011-02-02 Thread Warren Harris

On Feb 2, 2011, at 2:02 PM, Johan Tibell wrote:

 On Wed, Feb 2, 2011 at 10:42 PM, Warren Harris warrensomeb...@gmail.com 
 wrote:
 Interesting. I hadn't thought of this solution. You're forking the timer to 
 yet a third thread so that if it continues waiting beyond the checkpoint 
 thread shutdown it doesn't really matter. I guess that works as long as the 
 main thread doesn't wait for all other threads to terminate before 
 terminating the app.
 
 It still seems to me that haskell is lacking when it comes to operations 
 that can wait for multiple conditions.
 
 I think we can make waiting for both I/O activity and timers at the
 same time using the I/O manager. I will need to do this for my planned
 timeout support in the network package.

I could see wanting to wait for an MVar, timeout, IO activity, STM channels 
(anything that could block), all in the same event handler. (Rather like the 
old WaitForMultipleObjects on Windows.) This would also require a way to test 
each condition without blocking (MVar has this with tryTakeMVar, but it doesn't 
look like they all support it.)

Warren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] timely shutdown of timer threads

2011-02-02 Thread Albert Y. C. Lai

On 11-02-02 04:42 PM, Warren Harris wrote:

It still seems to me that haskell is lacking when it comes to operations that 
can wait for multiple conditions.


STM opens the avenue to waiting for multiple conditions.

import Control.Concurrent
import Control.Concurrent.STM
import Control.Exception(finally)

data DoOrDie = Do | Die

main = do
  die - atomically newEmptyTMVar
  finale - atomically newEmptyTMVar
  forkIO (timeloop die `finally` atomically (putTMVar finale ()))
  putStrLn press enter to quit
  getLine
  atomically (putTMVar die Die)
  atomically (takeTMVar finale)

timeloop die = run where
  run = do
w - atomically newEmptyTMVar
i - forkIO (threadDelay 1500  atomically (putTMVar w Do))
r - atomically (takeTMVar w `orElse` takeTMVar die)
case r of
  Do - putStrLn checkpoint  run
  Die - killThread i  putStrLn checkmate

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] timely shutdown of timer threads

2011-02-01 Thread Warren Harris
I have an application that forks a thread to run an activity on a timer. (The 
activity happens to be Berkeley DB checkpointing, but that's actually beside 
the point here.) The problem is that when the application wants to quit, I 
would like my main thread to be able to tell the timer thread to shut down in a 
timely way. However, I don't see a primitive in haskell that allows me to both 
wait for a timeout, or a notification. (If I were to do this in java, I would 
use wait/notify.) 

Here's the code I wrote to attempt this shutdown procedure:

import Control.Exception
import Database.Berkeley.Db
import Data.IORef
import System.Posix.Unistd
...

closeEnv :: Env - IO ()
closeEnv env = do
  threadId - readIORef (envCheckpointThread env)
  case threadId of
Just tid - killThread tid
Nothing - return ()
  dbEnv_close [] (envDbEnv env)

startCheckpointing :: Env - IO ThreadId
startCheckpointing env = do
  forkOS run
  where run = catch checkpoint handler
checkpoint = checkpoint1  checkpoint
checkpoint1 = unblock $ do
  let dbenv = envDbEnv env
  _ - sleep checkpointInterval
  putStrLn # checkpoint
  dbEnv_txn_checkpoint [] dbenv 0 0
handler ThreadKilled = return ()
handler exn = throw exn

However, there are several problems here: First, the checkpointInterval is 15 
sec, so it takes at least 15 seconds for the thread to wake up and be 
interrupted. Second, it isn't clear to me whether the killThread call should 
interrupt the sleep or not. In practice, several checkpoints occur before the 
ThreadKilled message is delivered, and this can take up to 2 minutes to shut 
down.

Is there a better way to do this? Suggestions would be greatly appreciated,

Warren
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] timely shutdown of timer threads

2011-02-01 Thread Albert Y. C. Lai

On 11-02-01 02:58 PM, Warren Harris wrote:

I have an application that forks a thread to run an activity on a timer. (The 
activity happens to be Berkeley DB checkpointing, but that's actually beside 
the point here.) The problem is that when the application wants to quit, I 
would like my main thread to be able to tell the timer thread to shut down in a 
timely way. However, I don't see a primitive in haskell that allows me to both 
wait for a timeout, or a notification. (If I were to do this in java, I would 
use wait/notify.)


Use an MVar for signalling; use a two-valued data type to represent 
time-to-work or time-to-die. For extra correctness, use a second MVar to 
be notified that the child thread is really done --- because otherwise 
there would be the race condition of the child thread still in the 
middle of critical I/O when the program quits.


import Control.Concurrent
import Control.Exception(finally)

data DoOrDie = Do | Die

main = do
  v - newEmptyMVar
  finale - newEmptyMVar
  forkIO (timeloop v `finally` putMVar finale ())
  putStrLn press enter to quit
  getLine
  putMVar v Die
  takeMVar finale

timeloop v = run where
  run = do
forkIO (threadDelay 1500  putMVar v Do)
m - takeMVar v
case m of
  Do - putStrLn checkpoint  run
  Die - putStrLn checkmate

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe