@@ -23,6 +23,7 @@ import Data.Dynamic (Typeable)
2323import Data.IORef
2424 (IORef, atomicModifyIORef, readIORef, writeIORef, modifyIORef,
2525 newIORef)
26+import Data.List (delete)
2627import Data.Maybe (fromJust)
2728import Control.Monad.IO.Class (MonadIO(..))
2829import Control.Monad.State
@@ -48,31 +49,31 @@ runCont EventF { xcomp = x, fcomp = fs } = runAsyncT $ do
4849-- Thread Management (creation, reaping and killing)
4950------------------------------------------------------------------------------
5051
51−tryReclaimZombies :: MonadIO m => TChan ThreadId -> IORef [EventF] -> m ()
52+tryReclaimZombies :: MonadIO m => TChan ThreadId -> IORef [ThreadId] -> m ()
5253tryReclaimZombies chan pendingRef = do
5354 pending <- liftIO $ readIORef pendingRef
54− if length pending == 0
55− then return ()
56− else do
55+ case pending of
56+ [] -> return ()
57+ _ -> do
5758 mtid <- liftIO $ atomically $ tryReadTChan chan
5859 case mtid of
5960 Nothing -> return ()
6061 Just tid -> do
61− liftIO $ writeIORef pendingRef $ filter (\x -> threadId x /= tid) pending
62+ liftIO $ writeIORef pendingRef $ delete tid pending
6263 tryReclaimZombies chan pendingRef
6364
64−waitForOneChild :: MonadIO m => TChan ThreadId -> IORef [EventF] -> m ()
65+waitForOneChild :: MonadIO m => TChan ThreadId -> IORef [ThreadId] -> m ()
6566waitForOneChild chan pendingRef = do
6667 -- XXX assert pending must have at least one element
6768 -- assert that the tid is found in our list
6869 tid <- liftIO $ atomically $ readTChan chan
69− liftIO $ modifyIORef pendingRef $ filter (\x -> threadId x /= tid)
70+ liftIO $ modifyIORef pendingRef $ delete tid
7071
7172-- | kill all the child threads associated with the continuation context
7273killChildren :: EventF -> IO ()
7374killChildren ctx = do
7475 ths <- readIORef (pendingThreads ctx)
75− mapM_ (killThread . threadId) ths
76+ mapM_ killThread ths
7677
7778-- XXX this is not a real semaphore as it does not really block on wait,
7879-- instead it returns whether the value is zero or non-zero.
@@ -120,15 +121,15 @@ forkIt current proc = do
120121 $ \res -> do
121122 thId <- myThreadId
122123 beforeExit child{threadId = thId} res
123− updatePendingThreads current child{threadId = tid}
124+ updatePendingThreads current tid
124125
125126 where
126127
127− updatePendingThreads :: MonadIO m => EventF -> EventF -> m ()
128− updatePendingThreads cur child = do
129− -- update the new thread first so that if it exited already reclaim
130− -- finds it in the list and does not panic.
131− liftIO $ modifyIORef (pendingThreads cur) $ (\ts -> child:ts)
128+ updatePendingThreads :: MonadIO m => EventF -> ThreadId -> m ()
129+ updatePendingThreads cur tid = do
130+ -- update the new thread before reclaiming zombies so that if it exited
131+ -- already reclaim finds it in the list and does not panic.
132+ liftIO $ modifyIORef (pendingThreads cur) $ (\ts -> tid:ts)
132133 tryReclaimZombies (zombieChannel cur) (pendingThreads cur)
133134
134135 newChildCont cur = do