Ticket #7216: expose-threadWaitSTM-on-master.3.patch
| File expose-threadWaitSTM-on-master.3.patch, 6.3 KB (added by AndreasVoellmy, 5 months ago) |
|---|
-
Control/Concurrent.hs
From 8e516baa061c9572f77ad51e5c57e302b6b80c5d Mon Sep 17 00:00:00 2001 From: Andreas Voellmy <andreas.voellmy@gmail.com> Date: Sun, 30 Dec 2012 22:11:56 +0100 Subject: [PATCH] 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 | 43 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/Control/Concurrent.hs b/Control/Concurrent.hs index 100ccc5..3733a07 100644
a b 66 66 threadDelay, 67 67 threadWaitRead, 68 68 threadWaitWrite, 69 threadWaitReadSTM, 70 threadWaitWriteSTM, 69 71 #endif 70 72 71 73 -- * Communication abstractions … … 116 118 117 119 #ifdef __GLASGOW_HASKELL__ 118 120 import GHC.Exception 119 import GHC.Conc hiding (threadWaitRead, threadWaitWrite) 121 import GHC.Conc hiding (threadWaitRead, threadWaitWrite, 122 threadWaitReadSTM, threadWaitWriteSTM) 120 123 import qualified GHC.Conc 121 124 import GHC.IO ( IO(..), unsafeInterleaveIO, unsafeUnmask ) 122 125 import GHC.IORef ( newIORef, readIORef, writeIORef ) … … 130 133 #ifdef mingw32_HOST_OS 131 134 import Foreign.C 132 135 import System.IO 136 import Data.Maybe (Maybe(..)) 133 137 #endif 134 138 #endif 135 139 … … 448 452 = GHC.Conc.threadWaitWrite fd 449 453 #endif 450 454 455 -- | Returns an STM action that can be used to wait for data 456 -- to read from a file descriptor. The second returned value 457 -- is an IO action that can be used to deregister interest 458 -- in the file descriptor. 459 threadWaitReadSTM :: Fd -> IO (STM (), IO ()) 460 threadWaitReadSTM fd 461 #ifdef mingw32_HOST_OS 462 | threaded = do v <- newTVarIO Nothing 463 mask_ $ forkIO $ do result <- try (waitFd fd 0) 464 atomically (writeTVar v $ Just result) 465 let waitAction = do result <- readTVar v 466 case result of 467 Nothing -> retry 468 Just (Right ()) -> return () 469 Just (Left e) -> throwSTM e 470 let killAction = return () 471 return (waitAction, killAction) 472 | otherwise = error "threadWaitReadSTM requires -threaded on Windows" 473 #else 474 = GHC.Conc.threadWaitReadSTM fd 475 #endif 476 477 -- | Returns an STM action that can be used to wait until data 478 -- can be written to a file descriptor. The second returned value 479 -- is an IO action that can be used to deregister interest 480 -- in the file descriptor. 481 threadWaitWriteSTM :: Fd -> IO (STM (), IO ()) 482 threadWaitWriteSTM fd 483 #ifdef mingw32_HOST_OS 484 | threaded = do v <- newTVarIO Nothing 485 mask_ $ forkIO $ do result <- try (waitFd fd 1) 486 atomically (writeTVar v $ Just result) 487 let waitAction = do result <- readTVar v 488 case result of 489 Nothing -> retry 490 Just (Right ()) -> return () 491 Just (Left e) -> throwSTM e 492 let killAction = return () 493 return (waitAction, killAction) 494 | otherwise = error "threadWaitWriteSTM requires -threaded on Windows" 495 #else 496 = GHC.Conc.threadWaitWriteSTM fd 497 #endif 498 451 499 #ifdef mingw32_HOST_OS 452 500 foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool 453 501 -
GHC/Conc.lhs
diff --git a/GHC/Conc.lhs b/GHC/Conc.lhs index 914db3f..f5fb275 100644
a b 62 62 , registerDelay 63 63 , threadWaitRead 64 64 , threadWaitWrite 65 , threadWaitReadSTM 66 , threadWaitWriteSTM 65 67 , closeFdWith 66 68 67 69 -- * TVars -
GHC/Conc/IO.hs
diff --git a/GHC/Conc/IO.hs b/GHC/Conc/IO.hs index 94a63a9..4a0c083 100644
a b 38 38 , registerDelay 39 39 , threadWaitRead 40 40 , threadWaitWrite 41 , threadWaitReadSTM 42 , threadWaitWriteSTM 41 43 , closeFdWith 42 44 43 45 #ifdef mingw32_HOST_OS … … 54 56 #endif 55 57 ) where 56 58 59 import Data.Maybe (Maybe(..), maybe) 57 60 import Foreign 58 61 import GHC.Base 59 62 import GHC.Conc.Sync as Sync … … 108 111 case waitWrite# fd# s of { s' -> (# s', () #) 109 112 }} 110 113 114 -- | Returns an STM action that can be used to wait for data 115 -- to read from a file descriptor. The second returned value 116 -- is an IO action that can be used to deregister interest 117 -- in the file descriptor. 118 threadWaitReadSTM :: Fd -> IO (Sync.STM (), IO ()) 119 threadWaitReadSTM fd 120 #ifndef mingw32_HOST_OS 121 | threaded = Event.threadWaitReadSTM fd 122 #endif 123 | otherwise = do 124 m <- Sync.newTVarIO Nothing 125 Sync.forkIO $ do 126 threadWaitRead fd 127 Sync.atomically $ Sync.writeTVar m (Just ()) 128 let waitAction = do 129 e <- Sync.readTVar m 130 maybe Sync.retry return e 131 let killAction = return () 132 return (waitAction, killAction) 133 134 -- | Returns an STM action that can be used to wait until data 135 -- can be written to a file descriptor. The second returned value 136 -- is an IO action that can be used to deregister interest 137 -- in the file descriptor. 138 threadWaitWriteSTM :: Fd -> IO (Sync.STM (), IO ()) 139 threadWaitWriteSTM fd 140 #ifndef mingw32_HOST_OS 141 | threaded = Event.threadWaitWriteSTM fd 142 #endif 143 | otherwise = do 144 m <- Sync.newTVarIO Nothing 145 Sync.forkIO $ do 146 threadWaitWrite fd 147 Sync.atomically $ Sync.writeTVar m (Just ()) 148 let waitAction = do 149 e <- Sync.readTVar m 150 maybe Sync.retry return e 151 let killAction = return () 152 return (waitAction, killAction) 153 111 154 -- | Close a file descriptor in a concurrency-safe way (GHC only). If 112 155 -- you are using 'threadWaitRead' or 'threadWaitWrite' to perform 113 156 -- blocking I\/O, you /must/ use this function to close file
