Movatterモバイル変換
[0]ホーム
{-# LANGUAGE Unsafe #-}{-# LANGUAGE NoImplicitPrelude, MagicHash, UnboxedTuples #-}{-# OPTIONS_GHC -funbox-strict-fields #-}{-# OPTIONS_HADDOCK hide #-}------------------------------------------------------------------------------- |-- Module : GHC.MVar-- Copyright : (c) The University of Glasgow 2008-- License : see libraries/base/LICENSE---- Maintainer : cvs-ghc@haskell.org-- Stability : internal-- Portability : non-portable (GHC Extensions)---- The MVar type-------------------------------------------------------------------------------moduleGHC.MVar(-- * MVarsMVar(..),newMVar,newEmptyMVar,takeMVar,readMVar,putMVar,tryTakeMVar,tryPutMVar,tryReadMVar,isEmptyMVar,addMVarFinalizer)whereimportGHC.BasedataMVara=MVar(MVar#RealWorlda){- ^An 'MVar' (pronounced \"em-var\") is a synchronising variable, usedfor communication between concurrent threads. It can be thought ofas a box, which may be empty or full.-}-- pull in Eq (Mvar a) too, to avoid GHC.Conc being an orphan-instance module-- | @since 4.1.0.0instanceEq(MVara)where(MVarmvar1#)==(MVarmvar2#)=isTrue#(sameMVar#mvar1#mvar2#){-M-Vars are rendezvous points for concurrent threads. They beginempty, and any attempt to read an empty M-Var blocks. When an M-Varis written, a single blocked thread may be freed. Reading an M-Vartoggles its state from full back to empty. Therefore, any valuewritten to an M-Var may only be read once. Multiple reads and writesare allowed, but there must be at least one read between any twowrites.-}--Defined in IOBase to avoid cycle: data MVar a = MVar (SynchVar# RealWorld a)-- |Create an 'MVar' which is initially empty.newEmptyMVar::IO(MVara)newEmptyMVar=IO$\s#->casenewMVar#s#of(#s2#,svar##)->(#s2#,MVarsvar##)-- |Create an 'MVar' which contains the supplied value.newMVar::a->IO(MVara)newMVarvalue=newEmptyMVar>>=\mvar->putMVarmvarvalue>>returnmvar-- |Return the contents of the 'MVar'. If the 'MVar' is currently-- empty, 'takeMVar' will wait until it is full. After a 'takeMVar',-- the 'MVar' is left empty.---- There are two further important properties of 'takeMVar':---- * 'takeMVar' is single-wakeup. That is, if there are multiple-- threads blocked in 'takeMVar', and the 'MVar' becomes full,-- only one thread will be woken up. The runtime guarantees that-- the woken thread completes its 'takeMVar' operation.---- * When multiple threads are blocked on an 'MVar', they are-- woken up in FIFO order. This is useful for providing-- fairness properties of abstractions built using 'MVar's.--takeMVar::MVara->IOatakeMVar(MVarmvar#)=IO$\s#->takeMVar#mvar#s#-- |Atomically read the contents of an 'MVar'. If the 'MVar' is-- currently empty, 'readMVar' will wait until it is full.-- 'readMVar' is guaranteed to receive the next 'putMVar'.---- 'readMVar' is multiple-wakeup, so when multiple readers are-- blocked on an 'MVar', all of them are woken up at the same time.---- /Compatibility note:/ Prior to base 4.7, 'readMVar' was a combination-- of 'takeMVar' and 'putMVar'. This mean that in the presence of-- other threads attempting to 'putMVar', 'readMVar' could block.-- Furthermore, 'readMVar' would not receive the next 'putMVar' if there-- was already a pending thread blocked on 'takeMVar'. The old behavior-- can be recovered by implementing 'readMVar as follows:---- @-- readMVar :: MVar a -> IO a-- readMVar m =-- mask_ $ do-- a <- takeMVar m-- putMVar m a-- return a-- @readMVar::MVara->IOareadMVar(MVarmvar#)=IO$\s#->readMVar#mvar#s#-- |Put a value into an 'MVar'. If the 'MVar' is currently full,-- 'putMVar' will wait until it becomes empty.---- There are two further important properties of 'putMVar':---- * 'putMVar' is single-wakeup. That is, if there are multiple-- threads blocked in 'putMVar', and the 'MVar' becomes empty,-- only one thread will be woken up. The runtime guarantees that-- the woken thread completes its 'putMVar' operation.---- * When multiple threads are blocked on an 'MVar', they are-- woken up in FIFO order. This is useful for providing-- fairness properties of abstractions built using 'MVar's.--putMVar::MVara->a->IO()putMVar(MVarmvar#)x=IO$\s#->caseputMVar#mvar#xs#ofs2#->(#s2#,()#)-- |A non-blocking version of 'takeMVar'. The 'tryTakeMVar' function-- returns immediately, with 'Nothing' if the 'MVar' was empty, or-- @'Just' a@ if the 'MVar' was full with contents @a@. After 'tryTakeMVar',-- the 'MVar' is left empty.tryTakeMVar::MVara->IO(Maybea)tryTakeMVar(MVarm)=IO$\s->casetryTakeMVar#msof(#s',0#,_#)->(#s',Nothing#)-- MVar is empty(#s',_,a#)->(#s',Justa#)-- MVar is full-- |A non-blocking version of 'putMVar'. The 'tryPutMVar' function-- attempts to put the value @a@ into the 'MVar', returning 'True' if-- it was successful, or 'False' otherwise.tryPutMVar::MVara->a->IOBooltryPutMVar(MVarmvar#)x=IO$\s#->casetryPutMVar#mvar#xs#of(#s,0##)->(#s,False#)(#s,_#)->(#s,True#)-- |A non-blocking version of 'readMVar'. The 'tryReadMVar' function-- returns immediately, with 'Nothing' if the 'MVar' was empty, or-- @'Just' a@ if the 'MVar' was full with contents @a@.---- @since 4.7.0.0tryReadMVar::MVara->IO(Maybea)tryReadMVar(MVarm)=IO$\s->casetryReadMVar#msof(#s',0#,_#)->(#s',Nothing#)-- MVar is empty(#s',_,a#)->(#s',Justa#)-- MVar is full-- |Check whether a given 'MVar' is empty.---- Notice that the boolean value returned is just a snapshot of-- the state of the MVar. By the time you get to react on its result,-- the MVar may have been filled (or emptied) - so be extremely-- careful when using this operation. Use 'tryTakeMVar' instead if possible.isEmptyMVar::MVara->IOBoolisEmptyMVar(MVarmv#)=IO$\s#->caseisEmptyMVar#mv#s#of(#s2#,flg#)->(#s2#,isTrue#(flg/=#0#)#)-- |Add a finalizer to an 'MVar' (GHC only). See "Foreign.ForeignPtr" and-- "System.Mem.Weak" for more about finalizers.addMVarFinalizer::MVara->IO()->IO()addMVarFinalizer(MVarm)(IOfinalizer)=IO$\s->casemkWeak#m()finalizersof{(#s1,_#)->(#s1,()#)}
[8]ページ先頭