Movatterモバイル変換


[0]ホーム

URL:


{-# 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]ページ先頭

©2009-2025 Movatter.jp