[commit: base] master: Expose new threadWaitSTM functions in Control.Concurrent (see #7216). (228f0ed)
Ian Lynagh
igloo at earth.li
Sat Jan 12 21:49:55 CET 2013
Repository : ssh://darcs.haskell.org//srv/darcs/packages/base
On branch : master
http://hackage.haskell.org/trac/ghc/changeset/228f0edeb3b68e29b675c136b7fb8a577646d36a
>---------------------------------------------------------------
commit 228f0edeb3b68e29b675c136b7fb8a577646d36a
Author: Andreas Voellmy <andreas.voellmy at gmail.com>
Date: Sun Dec 30 22:11:56 2012 +0100
Expose new threadWaitSTM functions in Control.Concurrent (see #7216).
Supports threadWaitReadSTM and threadWaitWriteSTM on Windows with the threaded runtime system.
>---------------------------------------------------------------
Control/Concurrent.hs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-
GHC/Conc.lhs | 2 +
GHC/Conc/IO.hs | 40 +++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 1 deletions(-)
diff --git a/Control/Concurrent.hs b/Control/Concurrent.hs
index 100ccc5..3733a07 100644
--- a/Control/Concurrent.hs
+++ b/Control/Concurrent.hs
@@ -66,6 +66,8 @@ module Control.Concurrent (
threadDelay,
threadWaitRead,
threadWaitWrite,
+ threadWaitReadSTM,
+ threadWaitWriteSTM,
#endif
-- * Communication abstractions
@@ -116,7 +118,8 @@ import Control.Exception.Base as Exception
#ifdef __GLASGOW_HASKELL__
import GHC.Exception
-import GHC.Conc hiding (threadWaitRead, threadWaitWrite)
+import GHC.Conc hiding (threadWaitRead, threadWaitWrite,
+ threadWaitReadSTM, threadWaitWriteSTM)
import qualified GHC.Conc
import GHC.IO ( IO(..), unsafeInterleaveIO, unsafeUnmask )
import GHC.IORef ( newIORef, readIORef, writeIORef )
@@ -130,6 +133,7 @@ import Control.Monad ( when )
#ifdef mingw32_HOST_OS
import Foreign.C
import System.IO
+import Data.Maybe (Maybe(..))
#endif
#endif
@@ -448,6 +452,50 @@ threadWaitWrite fd
= GHC.Conc.threadWaitWrite fd
#endif
+-- | Returns an STM action that can be used to wait for data
+-- to read from a file descriptor. The second returned value
+-- is an IO action that can be used to deregister interest
+-- in the file descriptor.
+threadWaitReadSTM :: Fd -> IO (STM (), IO ())
+threadWaitReadSTM fd
+#ifdef mingw32_HOST_OS
+ | threaded = do v <- newTVarIO Nothing
+ mask_ $ forkIO $ do result <- try (waitFd fd 0)
+ atomically (writeTVar v $ Just result)
+ let waitAction = do result <- readTVar v
+ case result of
+ Nothing -> retry
+ Just (Right ()) -> return ()
+ Just (Left e) -> throwSTM e
+ let killAction = return ()
+ return (waitAction, killAction)
+ | otherwise = error "threadWaitReadSTM requires -threaded on Windows"
+#else
+ = GHC.Conc.threadWaitReadSTM fd
+#endif
+
+-- | Returns an STM action that can be used to wait until data
+-- can be written to a file descriptor. The second returned value
+-- is an IO action that can be used to deregister interest
+-- in the file descriptor.
+threadWaitWriteSTM :: Fd -> IO (STM (), IO ())
+threadWaitWriteSTM fd
+#ifdef mingw32_HOST_OS
+ | threaded = do v <- newTVarIO Nothing
+ mask_ $ forkIO $ do result <- try (waitFd fd 1)
+ atomically (writeTVar v $ Just result)
+ let waitAction = do result <- readTVar v
+ case result of
+ Nothing -> retry
+ Just (Right ()) -> return ()
+ Just (Left e) -> throwSTM e
+ let killAction = return ()
+ return (waitAction, killAction)
+ | otherwise = error "threadWaitWriteSTM requires -threaded on Windows"
+#else
+ = GHC.Conc.threadWaitWriteSTM fd
+#endif
+
#ifdef mingw32_HOST_OS
foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool
diff --git a/GHC/Conc.lhs b/GHC/Conc.lhs
index 914db3f..f5fb275 100644
--- a/GHC/Conc.lhs
+++ b/GHC/Conc.lhs
@@ -62,6 +62,8 @@ module GHC.Conc
, registerDelay
, threadWaitRead
, threadWaitWrite
+ , threadWaitReadSTM
+ , threadWaitWriteSTM
, closeFdWith
-- * TVars
diff --git a/GHC/Conc/IO.hs b/GHC/Conc/IO.hs
index 94a63a9..a99b334 100644
--- a/GHC/Conc/IO.hs
+++ b/GHC/Conc/IO.hs
@@ -38,6 +38,8 @@ module GHC.Conc.IO
, registerDelay
, threadWaitRead
, threadWaitWrite
+ , threadWaitReadSTM
+ , threadWaitWriteSTM
, closeFdWith
#ifdef mingw32_HOST_OS
@@ -108,6 +110,44 @@ threadWaitWrite fd
case waitWrite# fd# s of { s' -> (# s', () #)
}}
+-- | Returns an STM action that can be used to wait for data
+-- to read from a file descriptor. The second returned value
+-- is an IO action that can be used to deregister interest
+-- in the file descriptor.
+threadWaitReadSTM :: Fd -> IO (Sync.STM (), IO ())
+threadWaitReadSTM fd
+#ifndef mingw32_HOST_OS
+ | threaded = Event.threadWaitReadSTM fd
+#endif
+ | otherwise = do
+ m <- Sync.newTVarIO False
+ Sync.forkIO $ do
+ threadWaitRead fd
+ Sync.atomically $ Sync.writeTVar m True
+ let waitAction = do b <- Sync.readTVar m
+ if b then return () else retry
+ let killAction = return ()
+ return (waitAction, killAction)
+
+-- | Returns an STM action that can be used to wait until data
+-- can be written to a file descriptor. The second returned value
+-- is an IO action that can be used to deregister interest
+-- in the file descriptor.
+threadWaitWriteSTM :: Fd -> IO (Sync.STM (), IO ())
+threadWaitWriteSTM fd
+#ifndef mingw32_HOST_OS
+ | threaded = Event.threadWaitWriteSTM fd
+#endif
+ | otherwise = do
+ m <- Sync.newTVarIO False
+ Sync.forkIO $ do
+ threadWaitWrite fd
+ Sync.atomically $ Sync.writeTVar m True
+ let waitAction = do b <- Sync.readTVar m
+ if b then return () else retry
+ let killAction = return ()
+ return (waitAction, killAction)
+
-- | Close a file descriptor in a concurrency-safe way (GHC only). If
-- you are using 'threadWaitRead' or 'threadWaitWrite' to perform
-- blocking I\/O, you /must/ use this function to close file
More information about the ghc-commits
mailing list