GHC.Internal.Conc.Bound

ghc-internal-9.1001.0: Basic libraries

Copyright | (c) The University of Glasgow 2001
License | BSD-style (see the file libraries/base/LICENSE)
Maintainer | libraries@haskell.org
Stability | stable
Portability | non-portable (concurrency)
Safe Haskell | Unsafe
Language | Haskell2010

GHC.Internal.Conc.Bound

Description

Bound thread support.

Synopsis

- forkOS :: IO () -> IO ThreadId
- forkOSWithUnmask :: ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId
- isCurrentThreadBound :: IO Bool
- runInBoundThread :: IO a -> IO a
- runInUnboundThread :: IO a -> IO a
- rtsSupportsBoundThreads :: Bool

# Documentation

forkOS :: IO () -> IO ThreadId Source #

Like `forkIO`, this sparks off a new thread to run the `IO` computation passed as the first argument, and returns the `ThreadId` of the newly created thread.

However, `forkOS` creates a bound thread, which is necessary if you need to call foreign (non-Haskell) libraries that make use of thread-local state, such as OpenGL (see Control.Concurrent).

Using `forkOS` instead of `forkIO` makes no difference at all to the scheduling behaviour of the Haskell runtime system. It is a common misconception that you need to use `forkOS` instead of `forkIO` to avoid blocking all the Haskell threads when making a foreign call; this isn't the case. To allow foreign calls to be made without blocking all the Haskell threads (with GHC), it is only necessary to use the `-threaded` option when linking your program, and to make sure the foreign import is not marked `unsafe`.

forkOSWithUnmask :: ((forall a. IO a -> IO a) -> IO ()) -> IO ThreadId Source #

Like `forkIOWithUnmask`, but the child thread is a bound thread, as with `forkOS`.

isCurrentThreadBound :: IO Bool Source #

Returns `True` if the calling thread is bound, that is, if it is safe to use foreign libraries that rely on thread-local state from the calling thread.

runInBoundThread :: IO a -> IO a Source #

Run the `IO` computation passed as the first argument. If the calling thread is not bound, a bound thread is created temporarily. `runInBoundThread` doesn't finish until the `IO` computation finishes.

You can wrap a series of foreign function calls that rely on thread-local state with `runInBoundThread` so that you can use them without knowing whether the current thread is bound.

runInUnboundThread :: IO a -> IO a Source #

Run the `IO` computation passed as the first argument. If the calling thread is bound, an unbound thread is created temporarily using `forkIO`. `runInBoundThread` doesn't finish until the `IO` computation finishes.

Use this function only in the rare case that you have actually observed a performance loss due to the use of bound threads. A program that doesn't need its main thread to be bound and makes heavy use of concurrency (e.g. a web server), might want to wrap its `main` action in `runInUnboundThread`.

Note that exceptions which are thrown to the current thread are thrown in turn to the thread that is executing the given computation. This ensures there's always a way of killing the forked thread.

rtsSupportsBoundThreads :: Bool Source #

`True` if bound threads are supported. If `rtsSupportsBoundThreads` is `False`, `isCurrentThreadBound` will always return `False` and both `forkOS` and `runInBoundThread` will fail.