summaryrefslogtreecommitdiff
path: root/libraries/base/GHC/Event/Thread.hs
diff options
context:
space:
mode:
authorAndreas Voellmy <andreas.voellmy@gmail.com>2012-12-22 20:11:21 -0500
committerJohan Tibell <johan.tibell@gmail.com>2013-02-11 21:38:06 -0800
commitdd54a09c7ccc53d209d328d9a5f10e4d1727f4df (patch)
treea245a5828193944b6f64e3b6110c1af995011c66 /libraries/base/GHC/Event/Thread.hs
parent0df14e340755fc7469157719899940bafec812cb (diff)
downloadhaskell-dd54a09c7ccc53d209d328d9a5f10e4d1727f4df.tar.gz
Introduce IORef to refer to array of IO managers.
This change prepares the way for supporting changing number of IO managers when number of capabilities changes.
Diffstat (limited to 'libraries/base/GHC/Event/Thread.hs')
-rw-r--r--libraries/base/GHC/Event/Thread.hs45
1 files changed, 25 insertions, 20 deletions
diff --git a/libraries/base/GHC/Event/Thread.hs b/libraries/base/GHC/Event/Thread.hs
index 8c5989be2a..bef907c1f1 100644
--- a/libraries/base/GHC/Event/Thread.hs
+++ b/libraries/base/GHC/Event/Thread.hs
@@ -24,12 +24,13 @@ import Foreign.C.Error (eBADF, errnoToIOError)
import Foreign.Ptr (Ptr)
import GHC.Base
import GHC.Conc.Sync (TVar, ThreadId, ThreadStatus(..), atomically, forkIO,
- labelThread, modifyMVar_, newTVar, sharedCAF,
+ labelThread, modifyMVar_, withMVar, newTVar, sharedCAF,
numCapabilities, threadCapability, myThreadId, forkOn,
threadStatus, writeTVar, newTVarIO, readTVar, retry,throwSTM,STM)
import GHC.IO (mask_, onException)
import GHC.IO.Exception (ioError)
-import GHC.IOArray (IOArray, newIOArray, readIOArray, writeIOArray)
+import GHC.IOArray (IOArray, newIOArray, readIOArray, writeIOArray,
+ boundsIOArray)
import GHC.MVar (MVar, newEmptyMVar, newMVar, putMVar, takeMVar)
import GHC.Event.Internal (eventIs, evtClose)
import GHC.Event.Manager (Event, EventManager, evtRead, evtWrite, loop,
@@ -93,7 +94,11 @@ closeFdWith :: (Fd -> IO ()) -- ^ Action that performs the close.
-> Fd -- ^ File descriptor to close.
-> IO ()
closeFdWith close fd = do
- tableVars <- forM [0,1..numCapabilities-1] (getCallbackTableVar fd)
+ eventManagerArray <- readIORef eventManager
+ let (low, high) = boundsIOArray eventManagerArray
+ tableVars <- forM [low..high] $ \i -> do
+ Just (_,!mgr) <- readIOArray eventManagerArray i
+ return (mgr, M.callbackTableVar mgr fd)
mask_ $ do
tables <- forM tableVars (takeMVar.snd)
close fd
@@ -102,13 +107,6 @@ closeFdWith close fd = do
tableVars
tables
-getCallbackTableVar :: Fd
- -> Int
- -> IO (EventManager, MVar (IM.IntMap [M.FdData]))
-getCallbackTableVar fd cap =
- do Just (_,!mgr) <- readIOArray eventManager cap
- return (mgr, M.callbackTableVar mgr fd)
-
threadWait :: Event -> Fd -> IO ()
threadWait evt fd = mask_ $ do
m <- newEmptyMVar
@@ -168,15 +166,17 @@ getSystemEventManager :: IO EventManager
getSystemEventManager = do
t <- myThreadId
(cap, _) <- threadCapability t
- Just (_,mgr) <- readIOArray eventManager cap
+ eventManagerArray <- readIORef eventManager
+ Just (_,mgr) <- readIOArray eventManagerArray cap
return mgr
foreign import ccall unsafe "getOrSetSystemEventThreadEventManagerStore"
getOrSetSystemEventThreadEventManagerStore :: Ptr a -> IO (Ptr a)
-eventManager :: IOArray Int (Maybe (ThreadId, EventManager))
+eventManager :: IORef (IOArray Int (Maybe (ThreadId, EventManager)))
eventManager = unsafePerformIO $ do
- em <- newIOArray (0, numCapabilities - 1) Nothing
+ eventManagerArray <- newIOArray (0, numCapabilities - 1) Nothing
+ em <- newIORef eventManagerArray
sharedCAF em getOrSetSystemEventThreadEventManagerStore
{-# NOINLINE eventManager #-}
@@ -220,18 +220,21 @@ ensureIOManagerIsRunning
startTimerManagerThread
startIOManagerThreads :: IO ()
-startIOManagerThreads =
- modifyMVar_ ioManagerLock $ \_ ->
- forM_ [0,1..numCapabilities-1] startIOManagerThread
+startIOManagerThreads = do
+ eventManagerArray <- readIORef eventManager
+ let (low, high) = boundsIOArray eventManagerArray
+ withMVar ioManagerLock $ \_ ->
+ forM_ [low..high] startIOManagerThread
startIOManagerThread :: Int -> IO ()
startIOManagerThread i = do
+ eventManagerArray <- readIORef eventManager
let create = do
!mgr <- new True
!t <- forkOn i $ loop mgr
labelThread t "IOManager"
- writeIOArray eventManager i (Just (t,mgr))
- old <- readIOArray eventManager i
+ writeIOArray eventManagerArray i (Just (t,mgr))
+ old <- readIOArray eventManagerArray i
case old of
Nothing -> create
Just (t,em) -> do
@@ -277,8 +280,10 @@ startTimerManagerThread = modifyMVar_ timerManagerThreadVar $ \old -> do
shutdownManagers :: IO ()
shutdownManagers =
- do forM_ [0,1..numCapabilities-1] $ \i -> do
- mmgr <- readIOArray eventManager i
+ do eventManagerArray <- readIORef eventManager
+ let (low, high) = boundsIOArray eventManagerArray
+ forM_ [low..high] $ \i -> do
+ mmgr <- readIOArray eventManagerArray i
case mmgr of
Nothing -> return ()
Just (_,mgr) -> M.shutdown mgr