BlockedIndefinitelyOnMVar

Hi, I have a code like this ``` producer :: Int -> MVar Int -> IO () producer c mvar = case c > 10 of True -> throwIO HighNumberException False -> do putMVar mvar (c + 1) producer (c + 1) mvar consumer :: MVar Int -> IO () consumer mvar = do _ <- takeMVar mvar consumer mvar coordinator :: MVar Int -> IO () coordinator mvar = do withAsync (producer 0 mvar) $ \p -> withAsync (consumer mvar) $ \c -> do wait c wait p main :: IO () main = do mvar <- newEmptyMVar withAsync (coordinator mvar) (wait) putStrLn "done" ``` The producer send the informative exception HighNumberException, but the coordinator job receives a generic BlockedIndefinitelyOnMVar, because the producer stop working. How can I discard the generic exception, and re-throw/catch only HighNumberException? In case the complete source code is on https://github.com/massimo-zaniboni/blocked-on-mvar Thanks in any case, Massimo

Hi, I were discussing the problem on #haskell-it , and they noted that the correct exception is thrown changing from ``` wait c wait p ``` to ``` wait p wait c ``` More importantly, this code ``` () <$ (waitAny [c, p]) ``` and this ``` () <$ (waitAny [p, c]) ``` works in the expected way. So it seems that ``waitAny`` is a lot more robust, and extensible to 2 or more threads. I'm not interested to the final result of threads, so ``waitAny`` it is a good solution, but in the real code (not this example) I have many nested threads, so I need to create a unique ``waitAny`` on the main caller, that is not optimal, but probably viable. So I'm still interested, if there are better solutions, not requring a `waitAny` with all launched threads. Regards, Massimo Il 13/07/2018 16:51, Massimo Zaniboni ha scritto:
Hi,
I have a code like this
``` producer :: Int -> MVar Int -> IO () producer c mvar = case c > 10 of True -> throwIO HighNumberException False -> do putMVar mvar (c + 1) producer (c + 1) mvar
consumer :: MVar Int -> IO () consumer mvar = do _ <- takeMVar mvar consumer mvar
coordinator :: MVar Int -> IO () coordinator mvar = do withAsync (producer 0 mvar) $ \p -> withAsync (consumer mvar) $ \c -> do wait c wait p
main :: IO () main = do mvar <- newEmptyMVar withAsync (coordinator mvar) (wait) putStrLn "done" ```
The producer send the informative exception HighNumberException, but the coordinator job receives a generic BlockedIndefinitelyOnMVar, because the producer stop working.
How can I discard the generic exception, and re-throw/catch only HighNumberException?
In case the complete source code is on https://github.com/massimo-zaniboni/blocked-on-mvar
Thanks in any case, Massimo

Il 13/07/2018 17:29, Massimo Zaniboni ha scritto:
``` () <$ (waitAny [p, c]) ```
waitAny was not the correct solution, because it waits completition of only one thread, and not all threads. So I defined ``waitAll``. It returns also the most informative exception. In particular synchronous exceptions are favoured respect asynchronous exceptions, because synchronous exceptions are generated from the processing code, and not from other threads or the run-time system. I updated the repo with the code: https://github.com/massimo-zaniboni/blocked-on-mvar
participants (1)
-
Massimo Zaniboni