-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Label all threads and make sure they are killable
Labeling all threads ensures we can identify them when analyzing a GHC event log file using ghc-events-analyze. I also solve the current bug that all threads created by snap are unkillable when you start the server in a masked state. It is solved by using: forkIOWithUnmask $ \unmask -> unmask ... so that asynchronous exception can always be delivered to the forked thread.
- Loading branch information
1 parent
35eeaf2
commit cfdd3e0
Showing
5 changed files
with
102 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
{-# LANGUAGE RankNTypes #-} | ||
|
||
-- | Handy functions that should really be merged into | ||
-- Control.Concurrent itself. | ||
module Control.Concurrent.Extended | ||
( forkIOLabeled | ||
, forkIOLabeledWithUnmask | ||
|
||
, forkOnLabeled | ||
, forkOnLabeledWithUnmask | ||
) where | ||
|
||
import Control.Exception | ||
import Control.Concurrent | ||
import GHC.Conc.Sync (labelThread) | ||
|
||
-- | Sparks off a new thread using 'forkIO' to run the given IO | ||
-- computation, but first labels the thread with the given label | ||
-- (using 'labelThread'). | ||
-- | ||
-- The implementation makes sure that asynchronous exceptions are | ||
-- masked until the given computation is executed. This ensures the | ||
-- thread will always be labeled which guarantees you can always | ||
-- easily find it in the GHC event log. | ||
-- | ||
-- Note that the given computation is executed in the masked state of | ||
-- the calling thread. | ||
-- | ||
-- Returns the 'ThreadId' of the newly created thread. | ||
forkIOLabeled :: String -- ^ Thread label | ||
-> IO () | ||
-> IO ThreadId | ||
forkIOLabeled label m = | ||
mask $ \restore -> forkIO $ do | ||
tid <- myThreadId | ||
labelThread tid label | ||
restore m | ||
|
||
-- | Like 'forkIOLabeled', but lets you specify on which capability | ||
-- (think CPU) the thread should run. | ||
forkOnLabeled :: String -- ^ Thread label | ||
-> Int -- ^ Capability | ||
-> IO () | ||
-> IO ThreadId | ||
forkOnLabeled label cap m = | ||
mask $ \restore -> forkOn cap $ do | ||
tid <- myThreadId | ||
labelThread tid label | ||
restore m | ||
|
||
-- | Sparks off a new thread using 'forkIOWithUnmask' to run the given | ||
-- IO computation, but first labels the thread with the given label | ||
-- (using 'labelThread'). | ||
-- | ||
-- The implementation makes sure that asynchronous exceptions are | ||
-- masked until the given computation is executed. This ensures the | ||
-- thread will always be labeled which guarantees you can always | ||
-- easily find it in the GHC event log. | ||
-- | ||
-- Like 'forkIOWithUnmask', the given computation is given a function | ||
-- to unmask asynchronous exceptions. See the documentation of that | ||
-- function for the motivation. | ||
-- | ||
-- Returns the 'ThreadId' of the newly created thread. | ||
forkIOLabeledWithUnmask :: String -- ^ Thread label | ||
-> ((forall a. IO a -> IO a) -> IO ()) | ||
-> IO ThreadId | ||
forkIOLabeledWithUnmask label m = | ||
mask_ $ forkIOWithUnmask $ \unmask -> do | ||
tid <- myThreadId | ||
labelThread tid label | ||
m unmask | ||
|
||
-- | Like 'forkIOLabeledWithUnmask', but lets you specify on which | ||
-- capability (think CPU) the thread should run. | ||
forkOnLabeledWithUnmask :: String -- ^ Thread label | ||
-> Int -- ^ Capability | ||
-> ((forall a. IO a -> IO a) -> IO ()) | ||
-> IO ThreadId | ||
forkOnLabeledWithUnmask label cap m = | ||
mask_ $ forkOnWithUnmask cap $ \unmask -> do | ||
tid <- myThreadId | ||
labelThread tid label | ||
m unmask |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters