summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Seipp <austin@well-typed.com>2014-08-22 08:51:38 -0500
committerAustin Seipp <austin@well-typed.com>2014-08-22 08:52:13 -0500
commit4748f5936fe72d96edfa17b153dbfd84f2c4c053 (patch)
treeed5ad9f4fda46023a74010ecce38e3b47e17959b
parent22520cd7071e624cb3cbde6fdd65e872855dd6ff (diff)
downloadhaskell-4748f5936fe72d96edfa17b153dbfd84f2c4c053.tar.gz
Revert "rts/base: Fix #9423"
This should fix the Windows fallout, and hopefully this will be fixed once that's sorted out. This reverts commit f9f89b7884ccc8ee5047cf4fffdf2b36df6832df. Signed-off-by: Austin Seipp <austin@well-typed.com>
-rw-r--r--includes/rts/IOManager.h3
-rw-r--r--libraries/base/GHC/Event/Control.hs8
-rw-r--r--libraries/base/GHC/Event/Manager.hs1
-rw-r--r--libraries/base/GHC/Event/Thread.hs35
-rw-r--r--libraries/base/GHC/Event/TimerManager.hs1
-rw-r--r--rts/Capability.c11
-rw-r--r--rts/Capability.h3
-rw-r--r--rts/Linker.c1
-rw-r--r--rts/posix/Signals.c80
9 files changed, 51 insertions, 92 deletions
diff --git a/includes/rts/IOManager.h b/includes/rts/IOManager.h
index 7bf2cdf43c..1c331b97af 100644
--- a/includes/rts/IOManager.h
+++ b/includes/rts/IOManager.h
@@ -26,8 +26,7 @@ void sendIOManagerEvent (HsWord32 event);
#else
-void setIOManagerControlFd (nat cap_no, int fd);
-void setTimerManagerControlFd(int fd);
+void setIOManagerControlFd (int fd);
void setIOManagerWakeupFd (int fd);
#endif
diff --git a/libraries/base/GHC/Event/Control.hs b/libraries/base/GHC/Event/Control.hs
index 53a9bc86d8..2951a6a681 100644
--- a/libraries/base/GHC/Event/Control.hs
+++ b/libraries/base/GHC/Event/Control.hs
@@ -17,7 +17,6 @@ module GHC.Event.Control
, readControlMessage
-- *** File descriptors
, controlReadFd
- , controlWriteFd
, wakeupReadFd
-- ** Control message sending
, sendWakeup
@@ -92,6 +91,7 @@ newControl shouldRegister = allocaArray 2 $ \fds -> do
setCloseOnExec wr
return (rd, wr)
(ctrl_rd, ctrl_wr) <- createPipe
+ when shouldRegister $ c_setIOManagerControlFd ctrl_wr
#if defined(HAVE_EVENTFD)
ev <- throwErrnoIfMinus1 "eventfd" $ c_eventfd 0 0
setNonBlockingFD ev True
@@ -200,5 +200,9 @@ foreign import ccall unsafe "sys/eventfd.h eventfd_write"
c_eventfd_write :: CInt -> CULLong -> IO CInt
#endif
-foreign import ccall unsafe "setIOManagerWakeupFd"
+-- Used to tell the RTS how it can send messages to the I/O manager.
+foreign import ccall "setIOManagerControlFd"
+ c_setIOManagerControlFd :: CInt -> IO ()
+
+foreign import ccall "setIOManagerWakeupFd"
c_setIOManagerWakeupFd :: CInt -> IO ()
diff --git a/libraries/base/GHC/Event/Manager.hs b/libraries/base/GHC/Event/Manager.hs
index 80c05f7c0c..d55d5b1193 100644
--- a/libraries/base/GHC/Event/Manager.hs
+++ b/libraries/base/GHC/Event/Manager.hs
@@ -27,7 +27,6 @@ module GHC.Event.Manager
-- * State
, callbackTableVar
- , emControl
-- * Registering interest in I/O events
, Event
diff --git a/libraries/base/GHC/Event/Thread.hs b/libraries/base/GHC/Event/Thread.hs
index 0a82a548da..dcfa32aa28 100644
--- a/libraries/base/GHC/Event/Thread.hs
+++ b/libraries/base/GHC/Event/Thread.hs
@@ -22,7 +22,6 @@ 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,
@@ -34,14 +33,12 @@ 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)
@@ -264,11 +261,7 @@ startIOManagerThread :: IOArray Int (Maybe (ThreadId, EventManager))
startIOManagerThread eventManagerArray i = do
let create = do
!mgr <- new True
- !t <- forkOn i $ do
- c_setIOManagerControlFd
- (fromIntegral i)
- (fromIntegral $ controlWriteFd $ M.emControl mgr)
- loop mgr
+ !t <- forkOn i $ loop mgr
labelThread t ("IOManager on cap " ++ show_int i)
writeIOArray eventManagerArray i (Just (t,mgr))
old <- readIOArray eventManagerArray i
@@ -284,7 +277,6 @@ 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 ()
@@ -293,10 +285,8 @@ 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
+ !t <- forkIO $ TM.loop mgr `finally` shutdownManagers
labelThread t "TimerManager"
return $ Just t
case old of
@@ -314,11 +304,21 @@ startTimerManagerThread = modifyMVar_ timerManagerThreadVar $ \old -> do
mem <- readIORef timerManager
_ <- case mem of
Nothing -> return ()
- Just em -> do c_setTimerManagerControlFd (-1)
- TM.cleanup em
+ Just em -> 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,10 +352,3 @@ 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 ()
diff --git a/libraries/base/GHC/Event/TimerManager.hs b/libraries/base/GHC/Event/TimerManager.hs
index 63a72ef80b..f581330e25 100644
--- a/libraries/base/GHC/Event/TimerManager.hs
+++ b/libraries/base/GHC/Event/TimerManager.hs
@@ -15,7 +15,6 @@ module GHC.Event.TimerManager
, new
, newWith
, newDefaultBackend
- , emControl
-- * Running
, finished
diff --git a/rts/Capability.c b/rts/Capability.c
index 04f3a61993..fda9f4f278 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -256,7 +256,6 @@ initCapability( Capability *cap, nat i )
cap->spark_stats.converted = 0;
cap->spark_stats.gcd = 0;
cap->spark_stats.fizzled = 0;
- cap->io_manager_control_wr_fd = -1;
#endif
cap->total_allocated = 0;
@@ -1078,16 +1077,6 @@ rtsBool checkSparkCountInvariant (void)
}
#endif
-void setIOManagerControlFd(nat cap_no USED_IF_THREADS, int fd USED_IF_THREADS) {
-#if defined(THREADED_RTS)
- if (cap_no < n_capabilities) {
- capabilities[cap_no]->io_manager_control_wr_fd = fd;
- } else {
- errorBelch("warning: setIOManagerControlFd called with illegal capability number.");
- }
-#endif
-}
-
// Local Variables:
// mode: C
// fill-column: 80
diff --git a/rts/Capability.h b/rts/Capability.h
index d5f36c54bc..c7dceefe9f 100644
--- a/rts/Capability.h
+++ b/rts/Capability.h
@@ -126,9 +126,6 @@ struct Capability_ {
// Stats on spark creation/conversion
SparkCounters spark_stats;
-
- // IO manager for this cap
- int io_manager_control_wr_fd;
#endif
// Total words allocated by this cap since rts start
W_ total_allocated;
diff --git a/rts/Linker.c b/rts/Linker.c
index 76cfa8cea0..e97580d61a 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -860,7 +860,6 @@ typedef struct _RtsSymbolVal {
#if !defined(mingw32_HOST_OS)
#define RTS_USER_SIGNALS_SYMBOLS \
SymI_HasProto(setIOManagerControlFd) \
- SymI_HasProto(setTimerManagerControlFd) \
SymI_HasProto(setIOManagerWakeupFd) \
SymI_HasProto(ioManagerWakeup) \
SymI_HasProto(blockUserSignals) \
diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c
index ba4a8b75ea..d5129f0996 100644
--- a/rts/posix/Signals.c
+++ b/rts/posix/Signals.c
@@ -127,16 +127,12 @@ more_handlers(int sig)
// Here's the pipe into which we will send our signals
static int io_manager_wakeup_fd = -1;
-static int timer_manager_control_wr_fd = -1;
+static int io_manager_control_fd = -1;
#define IO_MANAGER_WAKEUP 0xff
#define IO_MANAGER_DIE 0xfe
#define IO_MANAGER_SYNC 0xfd
-void setTimerManagerControlFd(int fd) {
- timer_manager_control_wr_fd = fd;
-}
-
void
setIOManagerWakeupFd (int fd)
{
@@ -145,9 +141,14 @@ setIOManagerWakeupFd (int fd)
io_manager_wakeup_fd = fd;
}
-/* -----------------------------------------------------------------------------
- * Wake up at least one IO or timer manager HS thread.
- * -------------------------------------------------------------------------- */
+void
+setIOManagerControlFd (int fd)
+{
+ // only called when THREADED_RTS, but unconditionally
+ // compiled here because GHC.Event.Control depends on it.
+ io_manager_control_fd = fd;
+}
+
void
ioManagerWakeup (void)
{
@@ -169,24 +170,14 @@ ioManagerWakeup (void)
void
ioManagerDie (void)
{
- StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
- nat i;
- int fd;
int r;
-
- if (0 <= timer_manager_control_wr_fd) {
- r = write(timer_manager_control_wr_fd, &byte, 1);
+ // Ask the IO Manager thread to exit
+ if (io_manager_control_fd >= 0) {
+ StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
+ r = write(io_manager_control_fd, &byte, 1);
if (r == -1) { sysErrorBelch("ioManagerDie: write"); }
- timer_manager_control_wr_fd = -1;
- }
-
- for (i=0; i < n_capabilities; i++) {
- fd = capabilities[i]->io_manager_control_wr_fd;
- if (0 <= fd) {
- r = write(fd, &byte, 1);
- if (r == -1) { sysErrorBelch("ioManagerDie: write"); }
- capabilities[i]->io_manager_control_wr_fd = -1;
- }
+ io_manager_control_fd = -1;
+ io_manager_wakeup_fd = -1;
}
}
@@ -201,7 +192,7 @@ ioManagerStart (void)
{
// Make sure the IO manager thread is running
Capability *cap;
- if (timer_manager_control_wr_fd < 0 || io_manager_wakeup_fd < 0) {
+ if (io_manager_control_fd < 0 || io_manager_wakeup_fd < 0) {
cap = rts_lock();
ioManagerStartCap(&cap);
rts_unlock(cap);
@@ -232,37 +223,26 @@ generic_handler(int sig USED_IF_THREADS,
{
#if defined(THREADED_RTS)
- StgWord8 buf[sizeof(siginfo_t) + 1];
- int r;
+ if (io_manager_control_fd != -1)
+ {
+ StgWord8 buf[sizeof(siginfo_t) + 1];
+ int r;
- buf[0] = sig;
- if (info == NULL) {
- // info may be NULL on Solaris (see #3790)
- memset(buf+1, 0, sizeof(siginfo_t));
- } else {
- memcpy(buf+1, info, sizeof(siginfo_t));
- }
+ buf[0] = sig;
- if (0 <= timer_manager_control_wr_fd)
- {
- r = write(timer_manager_control_wr_fd, buf, sizeof(siginfo_t)+1);
- if (r == -1 && errno == EAGAIN) {
- errorBelch("lost signal due to full pipe: %d\n", sig);
+ if (info == NULL) {
+ // info may be NULL on Solaris (see #3790)
+ memset(buf+1, 0, sizeof(siginfo_t));
+ } else {
+ memcpy(buf+1, info, sizeof(siginfo_t));
}
- }
- nat i;
- int fd;
- for (i=0; i < n_capabilities; i++) {
- fd = capabilities[i]->io_manager_control_wr_fd;
- if (0 <= fd) {
- r = write(fd, buf, sizeof(siginfo_t)+1);
- if (r == -1 && errno == EAGAIN) {
- errorBelch("lost signal due to full pipe: %d\n", sig);
- }
+ r = write(io_manager_control_fd, buf, sizeof(siginfo_t)+1);
+ if (r == -1 && errno == EAGAIN)
+ {
+ errorBelch("lost signal due to full pipe: %d\n", sig);
}
}
-
// If the IO manager hasn't told us what the FD of the write end
// of its pipe is, there's not much we can do here, so just ignore
// the signal..