Ticket #4514: base-4514-1.patch

File base-4514-1.patch, 11.8 KB (added by bos, 2 years ago)

Updated base patch

  • base.cabal

    diff -rN -u old-base/base.cabal new-base/base.cabal
    old new  
    11name:           base 
    2 version:        4.3.0.0 
     2version:        4.3.1.0 
    33license:        BSD3 
    44license-file:   LICENSE 
    55maintainer:     libraries@haskell.org 
  • Control/Concurrent.hs

    diff -rN -u old-base/Control/Concurrent.hs new-base/Control/Concurrent.hs
    old new  
    4747        threadDelay,            -- :: Int -> IO () 
    4848        threadWaitRead,         -- :: Int -> IO () 
    4949        threadWaitWrite,        -- :: Int -> IO () 
     50        closeFd,                -- :: (Int -> IO ()) -> Int -> IO () 
    5051#endif 
    5152 
    5253        -- * Communication abstractions 
     
    450451 
    451452-- | Block the current thread until data is available to read on the 
    452453-- given file descriptor (GHC only). 
     454-- 
     455-- This will throw an 'IOError' if the file descriptor was closed 
     456-- while this thread was blocked. 
    453457threadWaitRead :: Fd -> IO () 
    454458threadWaitRead fd 
    455459#ifdef mingw32_HOST_OS 
     
    470474 
    471475-- | Block the current thread until data can be written to the 
    472476-- given file descriptor (GHC only). 
     477-- 
     478-- This will throw an 'IOError' if the file descriptor was closed 
     479-- while this thread was blocked. 
    473480threadWaitWrite :: Fd -> IO () 
    474481threadWaitWrite fd 
    475482#ifdef mingw32_HOST_OS 
     
    479486  = GHC.Conc.threadWaitWrite fd 
    480487#endif 
    481488 
     489-- | Close a file descriptor in a concurrency-safe way (GHC only).  If 
     490-- you are using 'threadWaitRead' or 'threadWaitWrite' to perform 
     491-- blocking I\/O, you /must/ use this function to close file 
     492-- descriptors, or blocked threads may not be woken. 
     493-- 
     494-- Any threads that are blocked on the file descriptor via 
     495-- 'threadWaitRead' or 'threadWaitWrite' will be unblocked by having 
     496-- IO exceptions thrown. 
     497closeFd :: (Fd -> IO ())        -- ^ Low-level action that performs the real close. 
     498        -> Fd                   -- ^ File descriptor to close. 
     499        -> IO () 
     500closeFd close fd 
     501#ifdef mingw32_HOST_OS 
     502  = close fd 
     503#else 
     504  = GHC.Conc.closeFd close fd 
     505#endif 
     506 
    482507#ifdef mingw32_HOST_OS 
    483508foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool 
    484509 
  • GHC/Conc/IO.hs

    diff -rN -u old-base/GHC/Conc/IO.hs new-base/GHC/Conc/IO.hs
    old new  
    3131        , registerDelay         -- :: Int -> IO (TVar Bool) 
    3232        , threadWaitRead        -- :: Int -> IO () 
    3333        , threadWaitWrite       -- :: Int -> IO () 
     34        , closeFd               -- :: (Int -> IO ()) -> Int -> IO () 
    3435 
    3536#ifdef mingw32_HOST_OS 
    3637        , asyncRead     -- :: Int -> Int -> Int -> Ptr a -> IO (Int, Int) 
     
    8283 
    8384-- | Block the current thread until data can be written to the 
    8485-- given file descriptor (GHC only). 
     86-- 
     87-- This will throw an 'IOError' if the file descriptor was closed 
     88-- while this thread was blocked. 
    8589threadWaitWrite :: Fd -> IO () 
    8690threadWaitWrite fd 
    8791#ifndef mingw32_HOST_OS 
     
    9296        case waitWrite# fd# s of { s' -> (# s', () #) 
    9397        }} 
    9498 
     99-- | Close a file descriptor in a concurrency-safe way (GHC only).  If 
     100-- you are using 'threadWaitRead' or 'threadWaitWrite' to perform 
     101-- blocking I\/O, you /must/ use this function to close file 
     102-- descriptors, or blocked threads may not be woken. 
     103-- 
     104-- Any threads that are blocked on the file descriptor via 
     105-- 'threadWaitRead' or 'threadWaitWrite' will be unblocked by having 
     106-- IO exceptions thrown. 
     107closeFd :: (Fd -> IO ())        -- ^ Low-level action that performs the real close. 
     108        -> Fd                   -- ^ File descriptor to close. 
     109        -> IO () 
     110closeFd close fd 
     111#ifndef mingw32_HOST_OS 
     112  | threaded  = Event.closeFd close fd 
     113#endif 
     114  | otherwise = close fd 
     115 
    95116-- | Suspends the current thread for a given number of microseconds 
    96117-- (GHC only). 
    97118-- 
  • GHC/Conc.lhs

    diff -rN -u old-base/GHC/Conc.lhs new-base/GHC/Conc.lhs
    old new  
    5252        , registerDelay         -- :: Int -> IO (TVar Bool) 
    5353        , threadWaitRead        -- :: Int -> IO () 
    5454        , threadWaitWrite       -- :: Int -> IO () 
     55        , closeFd               -- :: (Int -> IO ()) -> Int -> IO () 
    5556 
    5657        -- * TVars 
    5758        , STM(..) 
  • GHC/IO/FD.hs

    diff -rN -u old-base/GHC/IO/FD.hs new-base/GHC/IO/FD.hs
    old new  
    280280#ifndef mingw32_HOST_OS 
    281281  (flip finally) (release fd) $ do 
    282282#endif 
    283   throwErrnoIfMinus1Retry_ "GHC.IO.FD.close" $ 
     283  let closer realFd = 
     284        throwErrnoIfMinus1Retry_ "GHC.IO.FD.close" $ 
    284285#ifdef mingw32_HOST_OS 
    285     if fdIsSocket fd then 
    286        c_closesocket (fdFD fd) 
    287     else 
     286        if fdIsSocket fd then 
     287          c_closesocket (fromIntegral realFd) 
     288        else 
    288289#endif 
    289        c_close (fdFD fd) 
     290          c_close (fromIntegral realFd) 
     291  closeFd closer (fromIntegral (fdFD fd)) 
    290292 
    291293release :: FD -> IO () 
    292294#ifdef mingw32_HOST_OS 
  • System/Event/Internal.hs

    diff -rN -u old-base/System/Event/Internal.hs new-base/System/Event/Internal.hs
    old new  
    1212    , Event 
    1313    , evtRead 
    1414    , evtWrite 
     15    , evtClose 
    1516    , eventIs 
    1617    -- * Timeout type 
    1718    , Timeout(..) 
     
    2930import GHC.Show (Show(..)) 
    3031import GHC.List (filter, null) 
    3132 
    32 -- | An I/O event. 
     33-- | An I\/O event. 
    3334newtype Event = Event Int 
    3435    deriving (Eq) 
    3536 
     
    3738evtNothing = Event 0 
    3839{-# INLINE evtNothing #-} 
    3940 
     41-- | Data is available to be read. 
    4042evtRead :: Event 
    4143evtRead = Event 1 
    4244{-# INLINE evtRead #-} 
    4345 
     46-- | The file descriptor is ready to accept a write. 
    4447evtWrite :: Event 
    4548evtWrite = Event 2 
    4649{-# INLINE evtWrite #-} 
    4750 
     51-- | Another thread closed the file descriptor. 
     52evtClose :: Event 
     53evtClose = Event 4 
     54{-# INLINE evtClose #-} 
     55 
    4856eventIs :: Event -> Event -> Bool 
    4957eventIs (Event a) (Event b) = a .&. b /= 0 
    5058 
    5159instance Show Event where 
    5260    show e = '[' : (intercalate "," . filter (not . null) $ 
    53                     [evtRead `so` "evtRead", evtWrite `so` "evtWrite"]) ++ "]" 
     61                    [evtRead `so` "evtRead", 
     62                     evtWrite `so` "evtWrite", 
     63                     evtClose `so` "evtClose"]) ++ "]" 
    5464        where ev `so` disp | e `eventIs` ev = disp 
    5565                           | otherwise      = "" 
    5666 
  • System/Event/Manager.hs

    diff -rN -u old-base/System/Event/Manager.hs new-base/System/Event/Manager.hs
    old new  
    2626    , registerFd 
    2727    , unregisterFd_ 
    2828    , unregisterFd 
    29     , fdWasClosed 
     29    , closeFd 
    3030 
    3131      -- * Registering interest in timeout events 
    3232    , TimeoutCallback 
     
    4848import Data.IORef (IORef, atomicModifyIORef, mkWeakIORef, newIORef, readIORef, 
    4949                   writeIORef) 
    5050import Data.Maybe (Maybe(..)) 
    51 import Data.Monoid (mconcat, mempty) 
     51import Data.Monoid (mappend, mconcat, mempty) 
    5252import GHC.Base 
    5353import GHC.Conc.Signal (runHandlers) 
    5454import GHC.List (filter) 
     
    5757import GHC.Show (Show(..)) 
    5858import System.Event.Clock (getCurrentTime) 
    5959import System.Event.Control 
    60 import System.Event.Internal (Backend, Event, evtRead, evtWrite, Timeout(..)) 
     60import System.Event.Internal (Backend, Event, evtClose, evtRead, evtWrite, 
     61                              Timeout(..)) 
    6162import System.Event.Unique (Unique, UniqueSource, newSource, newUnique) 
    6263import System.Posix.Types (Fd) 
    6364 
     
    331332  wake <- unregisterFd_ mgr reg 
    332333  when wake $ wakeManager mgr 
    333334 
    334 -- | Notify the event manager that a file descriptor has been closed. 
    335 fdWasClosed :: EventManager -> Fd -> IO () 
    336 fdWasClosed mgr fd = 
    337   modifyMVar_ (emFds mgr) $ \oldMap -> 
     335-- | Close a file descriptor in a race-safe way. 
     336closeFd :: EventManager -> (Fd -> IO ()) -> Fd -> IO () 
     337closeFd mgr close fd = do 
     338  fds <- modifyMVar (emFds mgr) $ \oldMap -> do 
     339    close fd 
    338340    case IM.delete (fromIntegral fd) oldMap of 
    339       (Nothing,  _)       -> return oldMap 
     341      (Nothing,  _)       -> return (oldMap, []) 
    340342      (Just fds, !newMap) -> do 
    341343        when (eventsOf fds /= mempty) $ wakeManager mgr 
    342         return newMap 
     344        return (newMap, fds) 
     345  forM_ fds $ \(FdData reg ev cb) -> cb reg (ev `mappend` evtClose) 
    343346 
    344347------------------------------------------------------------------------ 
    345348-- Registering interest in timeout events 
  • System/Event/Thread.hs

    diff -rN -u old-base/System/Event/Thread.hs new-base/System/Event/Thread.hs
    old new  
    55      ensureIOManagerIsRunning 
    66    , threadWaitRead 
    77    , threadWaitWrite 
     8    , closeFd 
    89    , threadDelay 
    910    , registerDelay 
    1011    ) where 
    1112 
    1213import Data.IORef (IORef, newIORef, readIORef, writeIORef) 
    1314import Data.Maybe (Maybe(..)) 
     15import Foreign.C.Error (eBADF, errnoToIOError) 
    1416import Foreign.Ptr (Ptr) 
    1517import GHC.Base 
    1618import GHC.Conc.Sync (TVar, ThreadId, ThreadStatus(..), atomically, forkIO, 
    1719                      labelThread, modifyMVar_, newTVar, sharedCAF, 
    1820                      threadStatus, writeTVar) 
     21import GHC.IO.Exception (ioError) 
    1922import GHC.MVar (MVar, newEmptyMVar, newMVar, putMVar, takeMVar) 
     23import GHC.Real (fromIntegral) 
     24import System.Event.Internal (eventIs, evtClose) 
    2025import System.Event.Manager (Event, EventManager, evtRead, evtWrite, loop, 
    2126                             new, registerFd, unregisterFd_, registerTimeout) 
     27import qualified System.Event.Manager as M 
    2228import System.IO.Unsafe (unsafePerformIO) 
    2329import System.Posix.Types (Fd) 
    2430 
     
    4753 
    4854-- | Block the current thread until data is available to read from the 
    4955-- given file descriptor. 
     56-- 
     57-- This will throw an 'IOError' if the file descriptor was closed 
     58-- while this thread is blocked. 
    5059threadWaitRead :: Fd -> IO () 
    5160threadWaitRead = threadWait evtRead 
    5261{-# INLINE threadWaitRead #-} 
    5362 
    5463-- | Block the current thread until the given file descriptor can 
    5564-- accept data to write. 
     65-- 
     66-- This will throw an 'IOError' if the file descriptor was closed 
     67-- while this thread is blocked. 
    5668threadWaitWrite :: Fd -> IO () 
    5769threadWaitWrite = threadWait evtWrite 
    5870{-# INLINE threadWaitWrite #-} 
    5971 
     72-- | Close a file descriptor in a concurrency-safe way. 
     73-- 
     74-- Any threads that are blocked on the file descriptor via 
     75-- 'threadWaitRead' or 'threadWaitWrite' will be unblocked by having 
     76-- IO exceptions thrown. 
     77closeFd :: (Fd -> IO ())        -- ^ Action that performs the close. 
     78        -> Fd                   -- ^ File descriptor to close. 
     79        -> IO () 
     80closeFd close fd = do 
     81  Just mgr <- readIORef eventManager 
     82  M.closeFd mgr close fd 
     83 
    6084threadWait :: Event -> Fd -> IO () 
    6185threadWait evt fd = do 
    6286  m <- newEmptyMVar 
    6387  Just mgr <- readIORef eventManager 
    64   _ <- registerFd mgr (\reg _ -> unregisterFd_ mgr reg >> putMVar m ()) fd evt 
    65   takeMVar m 
     88  _ <- registerFd mgr (\reg e -> unregisterFd_ mgr reg >> putMVar m e) fd evt 
     89  evt' <- takeMVar m 
     90  if evt' `eventIs` evtClose 
     91    then ioError $ errnoToIOError "threadWait" eBADF Nothing Nothing 
     92    else return () 
    6693 
    6794foreign import ccall unsafe "getOrSetSystemEventThreadEventManagerStore" 
    6895    getOrSetSystemEventThreadEventManagerStore :: Ptr a -> IO (Ptr a) 
  • System/Event.hs

    diff -rN -u old-base/System/Event.hs new-base/System/Event.hs
    old new  
    2222    , registerFd_ 
    2323    , unregisterFd 
    2424    , unregisterFd_ 
    25     , fdWasClosed 
     25    , closeFd 
    2626 
    2727      -- * Registering interest in timeout events 
    2828    , TimeoutCallback