Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
Asynchronous communication between pipes
Synopsis
- newtype Input a = Input {}
- newtype Output a = Output {}
- fromInput :: MonadIO m => Input a -> Producer' a m ()
- toOutput :: MonadIO m => Output a -> Consumer' a m ()
- type Mailbox a = (Output a, Input a)
- fromMailbox :: MonadIO m => Mailbox a -> Producer' a m ()
- toMailbox :: MonadIO m => Mailbox a -> Consumer' a m ()
- send' :: Mailbox a -> a -> STM Bool
- recv' :: Mailbox a -> STM (Maybe a)
- spawn :: Buffer a -> IO (Output a, Input a)
- spawn' :: Buffer a -> IO (Output a, Input a, STM ())
- withSpawn :: Buffer a -> ((Output a, Input a) -> IO r) -> IO r
- withBuffer :: Buffer a -> (Output a -> IO l) -> (Input a -> IO r) -> IO (l, r)
- data Buffer a
- unbounded :: Buffer a
- bounded :: Int -> Buffer a
- latest :: a -> Buffer a
- newest :: Int -> Buffer a
- forkIO :: IO () -> IO ThreadId
- readTVar :: TVar a -> STM a
- newTVarIO :: a -> IO (TVar a)
- atomically :: STM a -> IO a
- data STM a
- mkWeakTVar :: TVar a -> IO () -> IO (Weak (TVar a))
- performGC :: IO ()
Inputs and Outputs
Pipe utilities
Mailboxes
fromMailbox :: MonadIO m => Mailbox a -> Producer' a m () Source #
Convert a Mailbox
to a Producer
fromMailbox
terminates when the Mailbox
source of values is exhausted.
Actors
spawn :: Buffer a -> IO (Output a, Input a) Source #
Spawn a mailbox using the specified Buffer
to store messages
- fails and returns
False
if the mailbox is sealed, otherwise it: - retries if the mailbox is full, or:
- adds a message to the mailbox and returns
True
.
- retrieves a message from the mailbox wrapped in
Just
if the mailbox is not empty, otherwise it: - retries if the mailbox is not sealed, or:
- fails and returns
Nothing
.
If either the Input
or Output
is garbage collected the mailbox will
become sealed.
spawn' :: Buffer a -> IO (Output a, Input a, STM ()) Source #
Like spawn
, but also returns an action to manually seal
the mailbox
early:
(output, input, seal) <- spawn' buffer ...
Use the seal
action to allow early cleanup of readers and writers to the
mailbox without waiting for the next garbage collection cycle.
withSpawn :: Buffer a -> ((Output a, Input a) -> IO r) -> IO r Source #
withSpawn
passes its enclosed action an Output
and Input
like you'd get from spawn
,
but automatically seal
s them after the action completes. This can be used when you need the
seal
ing behavior available from 'spawn'', but want to work at a bit higher level:
withSpawn buffer $ \(output, input) -> ...
withSpawn
is exception-safe, since it uses bracket
internally.
withBuffer :: Buffer a -> (Output a -> IO l) -> (Input a -> IO r) -> IO (l, r) Source #
A more restrictive alternative to withSpawn
that prevents deadlocks
Buffer
specifies how to buffer messages stored within the mailbox
bounded :: Int -> Buffer a Source #
Store a bounded number of messages, specified by the Int
argument
newest :: Int -> Buffer a Source #
Like Bounded
, but send
never fails (the buffer is never full).
Instead, old elements are discarded to make room for new elements
Re-exports
Control.Concurrent
re-exports forkIO
, although I recommend using the
async
library instead.
Control.Concurrent.STM
re-exports atomically
and STM
.
System.Mem
re-exports performGC
.
forkIO :: IO () -> IO ThreadId #
Creates a new thread to run the IO
computation passed as the
first argument, and returns the ThreadId
of the newly created
thread.
The new thread will be a lightweight, unbound thread. Foreign calls
made by this thread are not guaranteed to be made by any particular OS
thread; if you need foreign calls to be made by a particular OS
thread, then use forkOS
instead.
The new thread inherits the masked state of the parent (see
mask
).
The newly created thread has an exception handler that discards the
exceptions BlockedIndefinitelyOnMVar
, BlockedIndefinitelyOnSTM
, and
ThreadKilled
, and passes all other exceptions to the uncaught
exception handler.
newTVarIO :: a -> IO (TVar a) #
IO
version of newTVar
. This is useful for creating top-level
TVar
s using unsafePerformIO
, because using
atomically
inside unsafePerformIO
isn't
possible.
atomically :: STM a -> IO a #
Perform a series of STM actions atomically.
Using atomically
inside an unsafePerformIO
or unsafeInterleaveIO
subverts some of guarantees that STM provides. It makes it possible to
run a transaction inside of another transaction, depending on when the
thunk is evaluated. If a nested transaction is attempted, an exception
is thrown by the runtime. It is possible to safely use atomically
inside
unsafePerformIO
or unsafeInterleaveIO
, but the typechecker does not
rule out programs that may attempt nested transactions, meaning that
the programmer must take special care to prevent these.
However, there are functions for creating transactional variables that
can always be safely called in unsafePerformIO
. See: newTVarIO
,
newTChanIO
,
newBroadcastTChanIO
,
newTQueueIO
,
newTBQueueIO
, and
newTMVarIO
.
Using unsafePerformIO
inside of atomically
is also dangerous but for
different reasons. See unsafeIOToSTM
for more on this.
A monad supporting atomic memory transactions.
Instances
Monad STM | Since: base-4.3.0.0 |
Functor STM | Since: base-4.3.0.0 |
Applicative STM | Since: base-4.8.0.0 |
Alternative STM | Since: base-4.8.0.0 |
MonadPlus STM | Since: base-4.3.0.0 |