threadDelay, -- :: Int -> IO ()
threadWaitRead, -- :: Int -> IO ()
threadWaitWrite, -- :: Int -> IO ()
- closeFd, -- :: (Int -> IO ()) -> Int -> IO ()
#endif
-- * Communication abstractions
-- given file descriptor (GHC only).
--
-- This will throw an 'IOError' if the file descriptor was closed
--- while this thread was blocked.
+-- while this thread was blocked. To safely close a file descriptor
+-- that has been used with 'threadWaitRead', use
+-- 'GHC.Conc.closeFdWith'.
threadWaitRead :: Fd -> IO ()
threadWaitRead fd
#ifdef mingw32_HOST_OS
-- given file descriptor (GHC only).
--
-- This will throw an 'IOError' if the file descriptor was closed
--- while this thread was blocked.
+-- while this thread was blocked. To safely close a file descriptor
+-- that has been used with 'threadWaitWrite', use
+-- 'GHC.Conc.closeFdWith'.
threadWaitWrite :: Fd -> IO ()
threadWaitWrite fd
#ifdef mingw32_HOST_OS
= GHC.Conc.threadWaitWrite fd
#endif
--- | Close a file descriptor in a concurrency-safe way (GHC only). If
--- you are using 'threadWaitRead' or 'threadWaitWrite' to perform
--- blocking I\/O, you /must/ use this function to close file
--- descriptors, or blocked threads may not be woken.
---
--- Any threads that are blocked on the file descriptor via
--- 'threadWaitRead' or 'threadWaitWrite' will be unblocked by having
--- IO exceptions thrown.
-closeFd :: (Fd -> IO ()) -- ^ Low-level action that performs the real close.
- -> Fd -- ^ File descriptor to close.
- -> IO ()
-closeFd close fd
-#ifdef mingw32_HOST_OS
- = close fd
-#else
- = GHC.Conc.closeFd close fd
-#endif
-
#ifdef mingw32_HOST_OS
foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool
, registerDelay -- :: Int -> IO (TVar Bool)
, threadWaitRead -- :: Int -> IO ()
, threadWaitWrite -- :: Int -> IO ()
- , closeFd -- :: (Int -> IO ()) -> Int -> IO ()
+ , closeFdWith -- :: (Fd -> IO ()) -> Fd -> IO ()
-- * TVars
, STM(..)
, registerDelay -- :: Int -> IO (TVar Bool)
, threadWaitRead -- :: Int -> IO ()
, threadWaitWrite -- :: Int -> IO ()
- , closeFd -- :: (Int -> IO ()) -> Int -> IO ()
+ , closeFdWith -- :: (Fd -> IO ()) -> Fd -> IO ()
#ifdef mingw32_HOST_OS
, asyncRead -- :: Int -> Int -> Int -> Ptr a -> IO (Int, Int)
-- | Block the current thread until data is available to read on the
-- given file descriptor (GHC only).
+--
+-- This will throw an 'IOError' if the file descriptor was closed
+-- while this thread was blocked. To safely close a file descriptor
+-- that has been used with 'threadWaitRead', use 'closeFdWith'.
threadWaitRead :: Fd -> IO ()
threadWaitRead fd
#ifndef mingw32_HOST_OS
-- given file descriptor (GHC only).
--
-- This will throw an 'IOError' if the file descriptor was closed
--- while this thread was blocked.
+-- while this thread was blocked. To safely close a file descriptor
+-- that has been used with 'threadWaitWrite', use 'closeFdWith'.
threadWaitWrite :: Fd -> IO ()
threadWaitWrite fd
#ifndef mingw32_HOST_OS
-- Any threads that are blocked on the file descriptor via
-- 'threadWaitRead' or 'threadWaitWrite' will be unblocked by having
-- IO exceptions thrown.
-closeFd :: (Fd -> IO ()) -- ^ Low-level action that performs the real close.
- -> Fd -- ^ File descriptor to close.
- -> IO ()
-closeFd close fd
+closeFdWith :: (Fd -> IO ()) -- ^ Low-level action that performs the real close.
+ -> Fd -- ^ File descriptor to close.
+ -> IO ()
+closeFdWith close fd
#ifndef mingw32_HOST_OS
- | threaded = Event.closeFd close fd
+ | threaded = Event.closeFdWith close fd
#endif
| otherwise = close fd
else
#endif
c_close (fromIntegral realFd)
- closeFd closer (fromIntegral (fdFD fd))
+ closeFdWith closer (fromIntegral (fdFD fd))
release :: FD -> IO ()
#ifdef mingw32_HOST_OS
ensureIOManagerIsRunning
, threadWaitRead
, threadWaitWrite
- , closeFd
+ , closeFdWith
, threadDelay
, registerDelay
) where
-- given file descriptor.
--
-- This will throw an 'IOError' if the file descriptor was closed
--- while this thread is blocked.
+-- while this thread was blocked. To safely close a file descriptor
+-- that has been used with 'threadWaitRead', use 'closeFdWith'.
threadWaitRead :: Fd -> IO ()
threadWaitRead = threadWait evtRead
{-# INLINE threadWaitRead #-}
-- accept data to write.
--
-- This will throw an 'IOError' if the file descriptor was closed
--- while this thread is blocked.
+-- while this thread was blocked. To safely close a file descriptor
+-- that has been used with 'threadWaitWrite', use 'closeFdWith'.
threadWaitWrite :: Fd -> IO ()
threadWaitWrite = threadWait evtWrite
{-# INLINE threadWaitWrite #-}
-- Any threads that are blocked on the file descriptor via
-- 'threadWaitRead' or 'threadWaitWrite' will be unblocked by having
-- IO exceptions thrown.
-closeFd :: (Fd -> IO ()) -- ^ Action that performs the close.
- -> Fd -- ^ File descriptor to close.
- -> IO ()
-closeFd close fd = do
+closeFdWith :: (Fd -> IO ()) -- ^ Action that performs the close.
+ -> Fd -- ^ File descriptor to close.
+ -> IO ()
+closeFdWith close fd = do
Just mgr <- readIORef eventManager
M.closeFd mgr close fd