
On Mon, Nov 21, 2005 at 10:41:38PM +0000, Joel Reymont wrote:
STM would complicate things too much for me. At least I think so. I would love to use STM but I would need to fit it into "type ScriptState = ErrorT String (StateT World IO)" just to use the logger. I'm not THAT comfortable with monads.
I am talking about Software Transactional Memory, which is in Control.Concurrent.STM. I think you confused it with State Transformer Monad. In your case STM would allow you to wait simultaneously on (T)MVar and (T)Chan. It would look like this: logger :: TMVar () -> IO () logger die = join $ atomically $ (do x <- readTChan parent return $ do putStrLn x logger die) `orElse` (do takeTMVar die return (return ())) but you have to modify the rest of code to use STM. I modified your Conc.hs to use STM, but using the greater guarantees of STM you could surely simplify it further (see the attached patch).
Let me see if I understand you correctly... Are you saying that I should be using getChanContents in the code below?
I am not proposing to use getChanContents. You are busy-waiting on MVar and Chan. I just proposed a solution to stuff messages and die-request into the same concurrency primitive, so you can wait for both events using a single operation. But you are right (below) that this bug doesn't explain the behaviour of your program. It is "only" a performance bug.
logger :: Handle -> MVar () -> IO () logger h die = do empty <- isEmptyChan parent unless empty $ do x <- readChan parent putStrLn x hPutStrLn h x alive <- isEmptyMVar die when (alive || not empty) $ logger h die
I think using Maybe is a great trick but I'm curious why so few messages actually get taken out of the channel in the code above?
Actually, I am not sure. I just noticed that your code uses a bad coding practice and could be improved. If I find some time I'll try to examine it more closely.
Are you saing that with all the checking it does not get to pull messages out?
As it is, you code can impose a big performance penalty, but indeed it shouldn't change the semantics. Perhaps I miss something.
I see clearly how using Maybe with getChanContents will work out perfectly. I don't understand why the above code is inefficient to the point of printing just a few messages (out of hundreds) out on Windows. I would like to understand it to avoid such mistakes in the future.
Yes, this is strange. Perhaps we're both missing something obvious. Best regards Tomasz