summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstolz <unknown>2002-06-27 13:40:37 +0000
committerstolz <unknown>2002-06-27 13:40:37 +0000
commit7158d54ec38d70806d4d90db1864d9a91d9eda87 (patch)
treec49ebe9424c298d78ebdbaf90f2d951f92eddd87
parent56b518776b07980c62f8bfbb605fa86b24ea3599 (diff)
downloadhaskell-7158d54ec38d70806d4d90db1864d9a91d9eda87.tar.gz
[project @ 2002-06-27 13:40:37 by stolz]
- forkProcess[Prim] wrapper - document forkProcess[Prim] & labelThread
-rw-r--r--libraries/base/GHC/Conc.lhs50
1 files changed, 46 insertions, 4 deletions
diff --git a/libraries/base/GHC/Conc.lhs b/libraries/base/GHC/Conc.lhs
index 46120c1f30..e5c33339bb 100644
--- a/libraries/base/GHC/Conc.lhs
+++ b/libraries/base/GHC/Conc.lhs
@@ -25,7 +25,8 @@ module GHC.Conc
, pseq -- :: a -> b -> b
, yield -- :: IO ()
, labelThread -- :: ThreadId -> String -> IO ()
- , forkProcess -- :: IO Int
+ , forkProcessPrim -- :: IO Int
+ , forkProcess -- :: IO (Maybe Int)
-- Waiting
, threadDelay -- :: Int -> IO ()
@@ -48,7 +49,8 @@ module GHC.Conc
import Data.Maybe
import GHC.Base
-import GHC.IOBase ( IO(..), MVar(..) )
+import GHC.IOBase ( IO(..), MVar(..), ioException, IOException(..), IOErrorType(..) )
+import GHC.Num ( fromInteger, negate )
import GHC.Base ( Int(..) )
import GHC.Exception ( Exception(..), AsyncException(..) )
import GHC.Pack ( packCString# )
@@ -123,14 +125,54 @@ yield :: IO ()
yield = IO $ \s ->
case (yield# s) of s1 -> (# s1, () #)
+{- | 'labelThread' stores a string as identifier for this thread if
+you built a RTS with debugging support. This identifier will be used in
+the debugging output to make distinction of different threads easier
+(otherwise you only have the thread state object\'s address in the heap).
+
+Other applications like the graphical Concurrent Haskell Debugger
+(<http://www.informatik.uni-kiel.de/~fhu/chd/>) may choose to overload
+'labelThread' for their purposes as well.
+-}
+
labelThread :: ThreadId -> String -> IO ()
labelThread (ThreadId t) str = IO $ \ s ->
let ps = packCString# str
adr = byteArrayContents# ps in
case (labelThread# t adr s) of s1 -> (# s1, () #)
-forkProcess :: IO Int
-forkProcess = IO $ \s -> case (forkProcess# s) of (# s1, id #) -> (# s1, (I# id) #)
+{- | This function is a replacement for "Posix.forkProcess": This implementation
+/will stop all other Concurrent Haskell threads/ in the (heavyweight) forked copy.
+'forkProcessPrim' returns the pid of the child process to the parent, 0 to the child,
+and a value less than 0 in case of errors. See also: 'forkProcess'.
+
+Without this function, you need excessive and often impractical
+explicit synchronization using the regular Concurrent Haskell constructs to assure
+that only the desired thread is running after the fork().
+
+The stopped threads are /not/ garbage collected! This behaviour may change in
+future releases.
+-}
+
+forkProcessPrim :: IO Int
+forkProcessPrim = IO $ \s -> case (forkProcess# s) of (# s1, id #) -> (# s1, (I# id) #)
+
+{- | 'forkProcess' is a wrapper around 'forkProcessPrim' similar to the one found in
+"Posix.forkProcess" which returns a Maybe-type. The child receives @Nothing@, the
+parent @Just (pid::Int)@. In case of an error, an exception is thrown.
+-}
+
+forkProcess :: IO (Maybe Int)
+forkProcess = do
+ pid <- forkProcessPrim
+ case pid of
+ -1 -> ioException (IOError Nothing -- stolen from hslibs/posix/PosixUtil
+ SystemError
+ "forkProcess"
+ ""
+ Nothing)
+ 0 -> return Nothing
+ _ -> return (Just pid)
-- Nota Bene: 'pseq' used to be 'seq'
-- but 'seq' is now defined in PrelGHC