diff options
author | Austin Seipp <austin@well-typed.com> | 2014-08-22 08:51:38 -0500 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2014-08-22 08:52:13 -0500 |
commit | 4748f5936fe72d96edfa17b153dbfd84f2c4c053 (patch) | |
tree | ed5ad9f4fda46023a74010ecce38e3b47e17959b | |
parent | 22520cd7071e624cb3cbde6fdd65e872855dd6ff (diff) | |
download | haskell-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.h | 3 | ||||
-rw-r--r-- | libraries/base/GHC/Event/Control.hs | 8 | ||||
-rw-r--r-- | libraries/base/GHC/Event/Manager.hs | 1 | ||||
-rw-r--r-- | libraries/base/GHC/Event/Thread.hs | 35 | ||||
-rw-r--r-- | libraries/base/GHC/Event/TimerManager.hs | 1 | ||||
-rw-r--r-- | rts/Capability.c | 11 | ||||
-rw-r--r-- | rts/Capability.h | 3 | ||||
-rw-r--r-- | rts/Linker.c | 1 | ||||
-rw-r--r-- | rts/posix/Signals.c | 80 |
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.. |