summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/Event/Thread.hs
diff options
context:
space:
mode:
authorAndreas Voellmy <andreas.voellmy@gmail.com>2014-09-16 07:56:54 -0500
committerAustin Seipp <austin@well-typed.com>2014-09-16 07:58:36 -0500
commit7e658bc14e2dd6baf208deebbdab9e1285ce4c72 (patch)
tree526c6557dd697360c4bc58ff99ecdf6b60c046ed /libraries/base/GHC/Event/Thread.hs
parentcaf449e39f5e7545eeabd567349661450aa8c6e5 (diff)
downloadhaskell-7e658bc14e2dd6baf208deebbdab9e1285ce4c72.tar.gz
Revert "Revert "rts/base: Fix #9423"" and resolve issue that caused the revert.
Summary: This reverts commit 4748f5936fe72d96edfa17b153dbfd84f2c4c053. The fix for #9423 was reverted because this commit introduced a C function setIOManagerControlFd() (defined in Schedule.c) defined for all OS types, while the prototype (in includes/rts/IOManager.h) was only included when mingw32_HOST_OS is not defined. This broke Windows builds. This commit reverts the original commit and resolves the problem by only defining setIOManagerControlFd() when mingw32_HOST_OS is defined. Hence the missing prototype error should not occur on Windows. In addition, since the io_manager_control_wr_fd field of the Capability struct is only usd by the setIOManagerControlFd, this commit includes the io_manager_control_wr_fd field in the Capability struct only when mingw32_HOST_OS is not defined. Test Plan: Try to compile successfully on all platforms. Reviewers: austin Reviewed By: austin Subscribers: simonmar, ezyang, carter Differential Revision: https://phabricator.haskell.org/D174
Diffstat (limited to 'libraries/base/GHC/Event/Thread.hs')
-rw-r--r--libraries/base/GHC/Event/Thread.hs35
1 files changed, 21 insertions, 14 deletions
diff --git a/libraries/base/GHC/Event/Thread.hs b/libraries/base/GHC/Event/Thread.hs
index dcfa32aa28..0a82a548da 100644
--- a/libraries/base/GHC/Event/Thread.hs
+++ b/libraries/base/GHC/Event/Thread.hs
@@ -22,6 +22,7 @@ import Data.List (zipWith3)
import Data.Maybe (Maybe(..))
import Data.Tuple (snd)
import Foreign.C.Error (eBADF, errnoToIOError)
+import Foreign.C.Types (CInt(..), CUInt(..))
import Foreign.Ptr (Ptr)
import GHC.Base
import GHC.Conc.Sync (TVar, ThreadId, ThreadStatus(..), atomically, forkIO,
@@ -33,12 +34,14 @@ import GHC.IO.Exception (ioError)
import GHC.IOArray (IOArray, newIOArray, readIOArray, writeIOArray,
boundsIOArray)
import GHC.MVar (MVar, newEmptyMVar, newMVar, putMVar, takeMVar)
+import GHC.Event.Control (controlWriteFd)
import GHC.Event.Internal (eventIs, evtClose)
import GHC.Event.Manager (Event, EventManager, evtRead, evtWrite, loop,
new, registerFd, unregisterFd_)
import qualified GHC.Event.Manager as M
import qualified GHC.Event.TimerManager as TM
import GHC.Num ((-), (+))
+import GHC.Real (fromIntegral)
import GHC.Show (showSignedInt)
import System.IO.Unsafe (unsafePerformIO)
import System.Posix.Types (Fd)
@@ -261,7 +264,11 @@ startIOManagerThread :: IOArray Int (Maybe (ThreadId, EventManager))
startIOManagerThread eventManagerArray i = do
let create = do
!mgr <- new True
- !t <- forkOn i $ loop mgr
+ !t <- forkOn i $ do
+ c_setIOManagerControlFd
+ (fromIntegral i)
+ (fromIntegral $ controlWriteFd $ M.emControl mgr)
+ loop mgr
labelThread t ("IOManager on cap " ++ show_int i)
writeIOArray eventManagerArray i (Just (t,mgr))
old <- readIOArray eventManagerArray i
@@ -277,6 +284,7 @@ startIOManagerThread eventManagerArray i = do
-- the fork, for example. In this case we should clean up
-- open pipes and everything else related to the event manager.
-- See #4449
+ c_setIOManagerControlFd (fromIntegral i) (-1)
M.cleanup em
create
_other -> return ()
@@ -285,8 +293,10 @@ startTimerManagerThread :: IO ()
startTimerManagerThread = modifyMVar_ timerManagerThreadVar $ \old -> do
let create = do
!mgr <- TM.new
+ c_setTimerManagerControlFd
+ (fromIntegral $ controlWriteFd $ TM.emControl mgr)
writeIORef timerManager $ Just mgr
- !t <- forkIO $ TM.loop mgr `finally` shutdownManagers
+ !t <- forkIO $ TM.loop mgr
labelThread t "TimerManager"
return $ Just t
case old of
@@ -304,21 +314,11 @@ startTimerManagerThread = modifyMVar_ timerManagerThreadVar $ \old -> do
mem <- readIORef timerManager
_ <- case mem of
Nothing -> return ()
- Just em -> TM.cleanup em
+ Just em -> do c_setTimerManagerControlFd (-1)
+ TM.cleanup em
create
_other -> return st
-shutdownManagers :: IO ()
-shutdownManagers =
- withMVar ioManagerLock $ \_ -> do
- eventManagerArray <- readIORef eventManager
- let (_, high) = boundsIOArray eventManagerArray
- forM_ [0..high] $ \i -> do
- mmgr <- readIOArray eventManagerArray i
- case mmgr of
- Nothing -> return ()
- Just (_,mgr) -> M.shutdown mgr
-
foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool
ioManagerCapabilitiesChanged :: IO ()
@@ -352,3 +352,10 @@ ioManagerCapabilitiesChanged = do
Just (_,mgr) <- readIOArray eventManagerArray i
tid <- restartPollLoop mgr i
writeIOArray eventManagerArray i (Just (tid,mgr))
+
+-- Used to tell the RTS how it can send messages to the I/O manager.
+foreign import ccall unsafe "setIOManagerControlFd"
+ c_setIOManagerControlFd :: CUInt -> CInt -> IO ()
+
+foreign import ccall unsafe "setTimerManagerControlFd"
+ c_setTimerManagerControlFd :: CInt -> IO ()