{-# LINE 1 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DoAndIfThenElse #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ScopedTypeVariables #-}
module GHC.Internal.Event.Windows (
Manager,
getSystemManager,
interruptSystemManager,
wakeupIOManager,
processRemoteCompletion,
associateHandle,
associateHandle',
withOverlapped,
withOverlappedEx,
StartCallback,
StartIOCallback,
CbResult(..),
CompletionCallback,
LPOVERLAPPED,
TimeoutCallback,
TimeoutKey,
Seconds,
registerTimeout,
updateTimeout,
unregisterTimeout,
withException,
ioSuccess,
ioFailed,
ioFailedAny,
getLastError,
IOResult(..),
HandleData (..),
HandleKey (handleValue),
registerHandle,
unregisterHandle,
module GHC.Internal.Event.Windows.ConsoleEvent
) where
import GHC.Internal.Control.Concurrent.MVar (modifyMVar)
import GHC.Internal.Data.Semigroup.Internal (stimesMonoid)
import GHC.Internal.Data.Foldable (mapM_, length, forM_)
import GHC.Internal.Data.Maybe (isJust, maybe)
import GHC.Internal.Event.Windows.Clock (Clock, Seconds, getClock, getTime)
import GHC.Internal.Event.Windows.FFI (LPOVERLAPPED, OVERLAPPED_ENTRY(..),
CompletionData(..), CompletionCallback,
withRequest)
import GHC.Internal.Event.Windows.ManagedThreadPool
import GHC.Internal.Event.Internal.Types
import GHC.Internal.Event.Unique
import GHC.Internal.Event.TimeOut
import GHC.Internal.Event.Windows.ConsoleEvent
import qualified GHC.Internal.Event.Windows.FFI as FFI
import qualified GHC.Internal.Event.PSQ as Q
import qualified GHC.Internal.Event.IntTable as IT
import qualified GHC.Internal.Event.Internal as I
import GHC.Internal.MVar
import GHC.Internal.Exception as E
import GHC.Internal.IORef
import GHC.Internal.Maybe
import GHC.Internal.Ptr
import GHC.Internal.Word
import GHC.Internal.Data.OldList (deleteBy)
import qualified GHC.Internal.Event.Array as A
import GHC.Internal.Base
import GHC.Internal.Conc.Bound
import GHC.Internal.Conc.Sync
import GHC.Internal.IO
import GHC.Internal.Num
import GHC.Internal.Real
import GHC.Internal.Bits
import GHC.Internal.Stable
import GHC.Internal.Enum (maxBound)
import GHC.Internal.Windows
import GHC.Internal.List (null)
import GHC.Internal.Text.Show
import GHC.Internal.Foreign.Ptr
import GHC.Internal.Foreign.Marshal.Utils
import GHC.Internal.Foreign.Storable
import GHC.Internal.Foreign.Marshal.Alloc
import GHC.Internal.Foreign.Marshal.Array
{-# LINE 131 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
import qualified GHC.Internal.Windows as Win32
{-# LINE 137 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
{-# NOINLINE ioManagerThread #-}
ioManagerThread :: MVar (Maybe ThreadId)
ioManagerThread :: MVar (Maybe ThreadId)
ioManagerThread = IO (MVar (Maybe ThreadId)) -> MVar (Maybe ThreadId)
forall a. IO a -> a
unsafePerformIO (IO (MVar (Maybe ThreadId)) -> MVar (Maybe ThreadId))
-> IO (MVar (Maybe ThreadId)) -> MVar (Maybe ThreadId)
forall a b. (a -> b) -> a -> b
$ do
m <- Maybe ThreadId -> IO (MVar (Maybe ThreadId))
forall a. a -> IO (MVar a)
newMVar Maybe ThreadId
forall a. Maybe a
Nothing
sharedCAF m getOrSetGHCConcWindowsIOManagerThreadStore
foreign import ccall unsafe "getOrSetGHCConcWindowsIOManagerThreadStore"
getOrSetGHCConcWindowsIOManagerThreadStore :: Ptr a -> IO (Ptr a)
foreign import ccall safe "registerIOCPHandle"
registerIOCPHandle :: FFI.IOCP -> IO ()
foreign import ccall safe "registerAlertableWait"
c_registerAlertableWait :: Bool -> DWORD -> IO ()
foreign import ccall safe "getOverlappedEntries"
getOverlappedEntries :: Ptr DWORD -> IO (Ptr OVERLAPPED_ENTRY)
foreign import ccall safe "completeSynchronousRequest"
completeSynchronousRequest :: IO ()
cdOffset :: Int
cdOffset :: Int
cdOffset = Int
32
{-# LINE 312 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
nullReq :: Ptr CompletionData
nullReq :: Ptr CompletionData
nullReq = Ptr Int -> Ptr CompletionData
forall a b. Ptr a -> Ptr b
castPtr (Ptr Int -> Ptr CompletionData) -> Ptr Int -> Ptr CompletionData
forall a b. (a -> b) -> a -> b
$ IO (Ptr Int) -> Ptr Int
forall a. IO a -> a
unsafePerformIO (IO (Ptr Int) -> Ptr Int) -> IO (Ptr Int) -> Ptr Int
forall a b. (a -> b) -> a -> b
$ Int -> IO (Ptr Int)
forall a. Storable a => a -> IO (Ptr a)
new (Int
0 :: Int)
{-# NOINLINE nullReq #-}
type EventElements = [(Event, HandleData)]
data EventData = EventData { EventData -> Event
evtTopLevel :: !Event, EventData -> EventElements
evtElems :: !EventElements }
instance Monoid EventData where
mempty :: EventData
mempty = Event -> EventElements -> EventData
EventData Event
evtNothing []
mappend :: EventData -> EventData -> EventData
mappend = EventData -> EventData -> EventData
forall a. Semigroup a => a -> a -> a
(<>)
instance Semigroup EventData where
<> :: EventData -> EventData -> EventData
(<>) = \EventData
a EventData
b -> Event -> EventElements -> EventData
EventData (EventData -> Event
evtTopLevel EventData
a Event -> Event -> Event
forall a. Semigroup a => a -> a -> a
<> EventData -> Event
evtTopLevel EventData
b)
(EventData -> EventElements
evtElems EventData
a EventElements -> EventElements -> EventElements
forall a. [a] -> [a] -> [a]
++ EventData -> EventElements
evtElems EventData
b)
stimes :: forall b. Integral b => b -> EventData -> EventData
stimes = b -> EventData -> EventData
forall b a. (Integral b, Monoid a) => b -> a -> a
stimesMonoid
data IOResult a
= IOSuccess { forall a. IOResult a -> a
ioValue :: a }
| IOFailed { forall a. IOResult a -> Maybe Int
ioErrCode :: Maybe Int }
data Manager = Manager
{ Manager -> IOCP
mgrIOCP :: {-# UNPACK #-} !FFI.IOCP
, Manager -> Clock
mgrClock :: !Clock
, Manager -> UniqueSource
mgrUniqueSource :: {-# UNPACK #-} !UniqueSource
, Manager -> IORef TimeoutQueue
mgrTimeouts :: {-# UNPACK #-} !(IORef TimeoutQueue)
, Manager -> MVar (IntTable EventData)
mgrEvntHandlers :: {-# UNPACK #-}
!(MVar (IT.IntTable EventData))
, Manager -> Array OVERLAPPED_ENTRY
mgrOverlappedEntries
:: {-#UNPACK #-} !(A.Array OVERLAPPED_ENTRY)
, Manager -> Maybe ThreadPool
mgrThreadPool :: Maybe ThreadPool
}
{-# INLINE startIOManagerThread #-}
startIOManagerThread :: IO () -> IO ()
startIOManagerThread :: IO () -> IO ()
startIOManagerThread IO ()
loop
| Bool -> Bool
not Bool
threadedIOMgr
= String -> IO ()
debugIO String
"startIOManagerThread:NonThreaded" IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
IO ()
interruptSystemManager
| Bool
otherwise = do
MVar (Maybe ThreadId)
-> (Maybe ThreadId -> IO (Maybe ThreadId)) -> IO ()
forall a. MVar a -> (a -> IO a) -> IO ()
modifyMVar_ MVar (Maybe ThreadId)
ioManagerThread ((Maybe ThreadId -> IO (Maybe ThreadId)) -> IO ())
-> (Maybe ThreadId -> IO (Maybe ThreadId)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Maybe ThreadId
old -> do
let create :: IO (Maybe ThreadId)
create = do String -> IO ()
debugIO String
"spawning worker threads.."
t <- IO () -> IO ThreadId
forkOS IO ()
loop
debugIO $ "created io-manager threads."
labelThread t "IOManagerThread"
return (Just t)
String -> IO ()
debugIO (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"startIOManagerThread old=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Maybe ThreadId -> String
forall a. Show a => a -> String
show Maybe ThreadId
old
case Maybe ThreadId
old of
Maybe ThreadId
Nothing -> IO (Maybe ThreadId)
create
Just ThreadId
t -> do
s <- ThreadId -> IO ThreadStatus
threadStatus ThreadId
t
case s of
ThreadStatus
ThreadFinished -> IO (Maybe ThreadId)
create
ThreadStatus
ThreadDied -> IO (Maybe ThreadId)
create
ThreadStatus
_other -> do IO ()
interruptSystemManager
Maybe ThreadId -> IO (Maybe ThreadId)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ThreadId -> Maybe ThreadId
forall a. a -> Maybe a
Just ThreadId
t)
requests :: MVar Word64
requests :: MVar CompletionKey
requests = IO (MVar CompletionKey) -> MVar CompletionKey
forall a. IO a -> a
unsafePerformIO (IO (MVar CompletionKey) -> MVar CompletionKey)
-> IO (MVar CompletionKey) -> MVar CompletionKey
forall a b. (a -> b) -> a -> b
$ CompletionKey -> IO (MVar CompletionKey)
forall a. a -> IO (MVar a)
newMVar CompletionKey
0
addRequest :: IO Word64
addRequest :: IO CompletionKey
addRequest = MVar CompletionKey
-> (CompletionKey -> IO (CompletionKey, CompletionKey))
-> IO CompletionKey
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar MVar CompletionKey
requests (\CompletionKey
x -> (CompletionKey, CompletionKey) -> IO (CompletionKey, CompletionKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CompletionKey
x CompletionKey -> CompletionKey -> CompletionKey
forall a. Num a => a -> a -> a
+ CompletionKey
1, CompletionKey
x CompletionKey -> CompletionKey -> CompletionKey
forall a. Num a => a -> a -> a
+ CompletionKey
1))
removeRequest :: IO Word64
removeRequest :: IO CompletionKey
removeRequest = MVar CompletionKey
-> (CompletionKey -> IO (CompletionKey, CompletionKey))
-> IO CompletionKey
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
modifyMVar MVar CompletionKey
requests (\CompletionKey
x -> (CompletionKey, CompletionKey) -> IO (CompletionKey, CompletionKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CompletionKey
x CompletionKey -> CompletionKey -> CompletionKey
forall a. Num a => a -> a -> a
- CompletionKey
1, CompletionKey
x CompletionKey -> CompletionKey -> CompletionKey
forall a. Num a => a -> a -> a
- CompletionKey
1))
outstandingRequests :: IO Word64
outstandingRequests :: IO CompletionKey
outstandingRequests = MVar CompletionKey
-> (CompletionKey -> IO CompletionKey) -> IO CompletionKey
forall a b. MVar a -> (a -> IO b) -> IO b
withMVar MVar CompletionKey
requests CompletionKey -> IO CompletionKey
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return
getSystemManager :: IO Manager
getSystemManager :: IO Manager
getSystemManager = MVar Manager -> IO Manager
forall a. MVar a -> IO a
readMVar MVar Manager
managerRef
managerRef :: MVar Manager
managerRef :: MVar Manager
managerRef = IO (MVar Manager) -> MVar Manager
forall a. IO a -> a
unsafePerformIO (IO (MVar Manager) -> MVar Manager)
-> IO (MVar Manager) -> MVar Manager
forall a b. (a -> b) -> a -> b
$ IO Manager
createManager IO Manager -> (Manager -> IO (MVar Manager)) -> IO (MVar Manager)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Manager -> IO (MVar Manager)
forall a. a -> IO (MVar a)
newMVar
where
createManager :: IO Manager
createManager :: IO Manager
createManager = do
String -> IO ()
debugIO String
"Starting io-manager..."
mgrIOCP <- IO IOCP
FFI.newIOCP
when (not threadedIOMgr) $
registerIOCPHandle mgrIOCP
debugIO $ "iocp: " ++ show mgrIOCP
mgrClock <- getClock
mgrUniqueSource <- newSource
mgrTimeouts <- newIORef Q.empty
mgrOverlappedEntries <- A.new 64
mgrEvntHandlers <- newMVar =<< IT.new callbackArraySize
let mgrThreadPool = Maybe a
forall a. Maybe a
Nothing
let !mgr = Manager{Maybe ThreadPool
UniqueSource
MVar (IntTable EventData)
IORef TimeoutQueue
Array OVERLAPPED_ENTRY
IOCP
Clock
forall a. Maybe a
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrEvntHandlers :: MVar (IntTable EventData)
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrThreadPool :: Maybe ThreadPool
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrEvntHandlers :: MVar (IntTable EventData)
mgrThreadPool :: forall a. Maybe a
..}
return mgr
{-# NOINLINE managerRef #-}
interruptSystemManager :: IO ()
interruptSystemManager :: IO ()
interruptSystemManager = do
mgr <- IO Manager
getSystemManager
debugIO "interrupt received.."
FFI.postQueuedCompletionStatus (mgrIOCP mgr) 0 0 nullPtr
callbackArraySize :: Int
callbackArraySize :: Int
callbackArraySize = Int
32
secondsToNanoSeconds :: Seconds -> Q.Prio
secondsToNanoSeconds :: Double -> CompletionKey
secondsToNanoSeconds Double
s = Double -> CompletionKey
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> CompletionKey) -> Double -> CompletionKey
forall a b. (a -> b) -> a -> b
$ Double
s Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1000000000
secondsToMilliSeconds :: Seconds -> Word32
secondsToMilliSeconds :: Double -> Word32
secondsToMilliSeconds Double
s = Double -> Word32
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Word32) -> Double -> Word32
forall a b. (a -> b) -> a -> b
$ Double
s Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1000
nanoSecondsToSeconds :: Q.Prio -> Seconds
nanoSecondsToSeconds :: CompletionKey -> Double
nanoSecondsToSeconds CompletionKey
n = CompletionKey -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral CompletionKey
n Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
1000000000.0
type StartCallback a = LPOVERLAPPED -> IO a
type StartIOCallback a = StartCallback (CbResult a)
data CbResult a
= CbDone (Maybe DWORD)
| CbPending
| CbIncomplete
| CbError a
| CbNone Bool
deriving Int -> CbResult a -> String -> String
[CbResult a] -> String -> String
CbResult a -> String
(Int -> CbResult a -> String -> String)
-> (CbResult a -> String)
-> ([CbResult a] -> String -> String)
-> Show (CbResult a)
forall a. Show a => Int -> CbResult a -> String -> String
forall a. Show a => [CbResult a] -> String -> String
forall a. Show a => CbResult a -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall a. Show a => Int -> CbResult a -> String -> String
showsPrec :: Int -> CbResult a -> String -> String
$cshow :: forall a. Show a => CbResult a -> String
show :: CbResult a -> String
$cshowList :: forall a. Show a => [CbResult a] -> String -> String
showList :: [CbResult a] -> String -> String
Show
associateHandle' :: HANDLE -> IO ()
associateHandle' :: Ptr () -> IO ()
associateHandle' Ptr ()
hwnd
= do mngr <- IO Manager
getSystemManager
associateHandle mngr hwnd
invalidHandle :: HANDLE
invalidHandle :: Ptr ()
invalidHandle = Ptr ()
iNVALID_HANDLE_VALUE
associateHandle :: Manager -> HANDLE -> IO ()
associateHandle :: Manager -> Ptr () -> IO ()
associateHandle Manager{Maybe ThreadPool
UniqueSource
MVar (IntTable EventData)
IORef TimeoutQueue
Array OVERLAPPED_ENTRY
IOCP
Clock
mgrIOCP :: Manager -> IOCP
mgrClock :: Manager -> Clock
mgrUniqueSource :: Manager -> UniqueSource
mgrTimeouts :: Manager -> IORef TimeoutQueue
mgrEvntHandlers :: Manager -> MVar (IntTable EventData)
mgrOverlappedEntries :: Manager -> Array OVERLAPPED_ENTRY
mgrThreadPool :: Manager -> Maybe ThreadPool
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrEvntHandlers :: MVar (IntTable EventData)
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrThreadPool :: Maybe ThreadPool
..} Ptr ()
h =
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Ptr ()
h Ptr () -> Ptr () -> Bool
forall a. Eq a => a -> a -> Bool
/= Ptr ()
invalidHandle) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
IOCP -> Ptr () -> CompletionKey -> IO ()
FFI.associateHandleWithIOCP IOCP
mgrIOCP Ptr ()
h (WordPtr -> CompletionKey
forall a b. (Integral a, Num b) => a -> b
fromIntegral (WordPtr -> CompletionKey) -> WordPtr -> CompletionKey
forall a b. (a -> b) -> a -> b
$ Ptr () -> WordPtr
forall a. Ptr a -> WordPtr
ptrToWordPtr Ptr ()
h)
withOverlappedEx :: forall a.
Manager
-> String
-> HANDLE
-> Bool
-> Word64
-> StartIOCallback Int
-> CompletionCallback (IOResult a)
-> IO (IOResult a)
withOverlappedEx :: forall a.
Manager
-> String
-> Ptr ()
-> Bool
-> CompletionKey
-> StartIOCallback Int
-> CompletionCallback (IOResult a)
-> IO (IOResult a)
withOverlappedEx Manager
mgr String
fname Ptr ()
h Bool
async CompletionKey
offset StartIOCallback Int
startCB CompletionCallback (IOResult a)
completionCB = do
signal <- IO (MVar (IOResult a))
forall a. IO (MVar a)
newEmptyMVar :: IO (MVar (IOResult a))
let signalReturn a
a = MVar (IOResult a) -> IOResult a -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (IOResult a)
signal (a -> IOResult a
forall a. a -> IOResult a
IOSuccess a
a)
signalThrow Maybe Int
ex = MVar (IOResult a) -> IOResult a -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (IOResult a)
signal (Maybe Int -> IOResult a
forall a. Maybe Int -> IOResult a
IOFailed Maybe Int
ex)
mask_ $ do
let completionCB' Word32
e Word32
b = do
result <- CompletionCallback (IOResult a)
completionCB Word32
e Word32
b
case result of
IOSuccess a
val -> a -> IO ()
signalReturn a
val
IOFailed Maybe Int
err -> Maybe Int -> IO ()
signalThrow Maybe Int
err
withRequest async offset h completionCB' $ \Ptr HASKELL_OVERLAPPED
hs_lpol Ptr CompletionData
cdData -> do
let ptr_lpol :: Ptr b
ptr_lpol = Ptr HASKELL_OVERLAPPED
hs_lpol Ptr HASKELL_OVERLAPPED -> Int -> Ptr b
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
cdOffset
let lpol :: Ptr b
lpol = Ptr HASKELL_OVERLAPPED -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr HASKELL_OVERLAPPED
hs_lpol
Ptr (Ptr CompletionData) -> Ptr CompletionData -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr (Ptr CompletionData)
forall a. Ptr a
ptr_lpol Ptr CompletionData
cdData
reqs <- IO CompletionKey
addRequest
debugIO $ "+1.. " ++ show reqs ++ " requests queued. | " ++ show lpol
cdDataCheck <- peek ptr_lpol :: IO (Ptr CompletionData)
debugIO $ "hs_lpol:" ++ show hs_lpol
++ " cdData:" ++ show cdData
++ " ptr_lpol:" ++ show ptr_lpol
++ " *ptr_lpol:" ++ show cdDataCheck
startCBResult <- startCB lpol `onException`
(CbError `fmap` Win32.getLastError) >>= \CbResult Int
result -> do
success <- Ptr OVERLAPPED -> IO Int32
FFI.overlappedIOStatus Ptr OVERLAPPED
forall a. Ptr a
lpol
err <- getLastError
let result' =
case CbResult Int
result of
CbNone Bool
ret
| Int32
success Int32 -> Int32 -> Bool
forall a. Eq a => a -> a -> Bool
== Int32
0 -> Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
forall a. Maybe a
Nothing
{-# LINE 598 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Int32
success Int32 -> Int32 -> Bool
forall a. Eq a => a -> a -> Bool
== -Int32
1073741807 -> Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
forall a. Maybe a
Nothing
{-# LINE 599 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Word32
err Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
234 -> Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
forall a. Maybe a
Nothing
{-# LINE 602 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Word32
err Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
0 -> Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
forall a. Maybe a
Nothing
{-# LINE 603 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Word32
err Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
997 -> CbResult Int
forall a. CbResult a
CbPending
{-# LINE 604 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Word32
err Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
996 -> CbResult Int
forall a. CbResult a
CbIncomplete
{-# LINE 605 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Word32
err Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
38 -> Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
forall a. Maybe a
Nothing
{-# LINE 606 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Word32
err Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
109 -> Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
forall a. Maybe a
Nothing
{-# LINE 607 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Word32
err Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
259 -> Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
forall a. Maybe a
Nothing
{-# LINE 608 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Word32
err Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
995 -> Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
forall a. Maybe a
Nothing
{-# LINE 609 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Bool -> Bool
not Bool
ret -> Int -> CbResult Int
forall a. a -> CbResult a
CbError (Int -> CbResult Int) -> Int -> CbResult Int
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
err
| Int32
success Int32 -> Int32 -> Bool
forall a. Eq a => a -> a -> Bool
== Int32
259 -> CbResult Int
forall a. CbResult a
CbPending
{-# LINE 615 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
| Bool
otherwise -> CbResult Int
forall a. CbResult a
CbPending
CbResult Int
_ -> CbResult Int
result
case result' of
CbNone Bool
_ -> String -> IO (CbResult Int)
forall a. HasCallStack => String -> a
error String
"withOverlappedEx: CbNone shouldn't happen."
CbResult Int
CbIncomplete -> do
String -> IO ()
debugIO (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"handling incomplete request synchronously " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Ptr (), Ptr (ZonkAny 2)) -> String
forall a. Show a => a -> String
show (Ptr ()
h, Ptr (ZonkAny 2)
forall a. Ptr a
lpol)
res <- Ptr () -> StartIOCallback Int
waitForCompletion Ptr ()
h Ptr OVERLAPPED
forall a. Ptr a
lpol
debugIO $ "done blocking request 2: " ++ show (h, lpol) ++ " - " ++ show res
return res
CbResult Int
CbPending -> do
finished <- Ptr () -> Ptr OVERLAPPED -> Bool -> IO (Maybe Word32)
FFI.getOverlappedResult Ptr ()
h Ptr OVERLAPPED
forall a. Ptr a
lpol (Bool -> Bool
not Bool
async)
lasterr <- getLastError
debugIO $ "== " ++ show (finished)
status <- FFI.overlappedIOStatus lpol
debugIO $ "== >< " ++ show (status)
let done_early = Int32
status Int32 -> Int32 -> Bool
forall a. Eq a => a -> a -> Bool
== Int32
0
{-# LINE 641 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
Bool -> Bool -> Bool
|| Int32
status Int32 -> Int32 -> Bool
forall a. Eq a => a -> a -> Bool
== -Int32
1073741807
{-# LINE 642 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
Bool -> Bool -> Bool
|| Word32 -> Bool
errorIsCompleted Word32
lasterr
let will_finish_sync = Word32
lasterr Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
996
{-# LINE 650 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
debugIO $ "== >*< " ++ show (finished, done_early, will_finish_sync, h, lpol, lasterr)
case (finished, done_early, will_finish_sync) of
(Just Word32
_, Bool
_, Bool
_) -> do
String -> IO ()
debugIO String
"request handled immediately (o/b), not queued."
CbResult Int -> IO (CbResult Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CbResult Int -> IO (CbResult Int))
-> CbResult Int -> IO (CbResult Int)
forall a b. (a -> b) -> a -> b
$ Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
finished
(Maybe Word32
Nothing, Bool
_, Bool
_) -> do
CbResult Int -> IO (CbResult Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return CbResult Int
result'
CbError Int
err' -> Maybe Int -> IO ()
signalThrow (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
err') IO () -> IO (CbResult Int) -> IO (CbResult Int)
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CbResult Int -> IO (CbResult Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return CbResult Int
result'
CbDone Maybe Word32
_ -> do
String -> IO ()
debugIO String
"request handled immediately (o), not queued." IO () -> IO (CbResult Int) -> IO (CbResult Int)
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CbResult Int -> IO (CbResult Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return CbResult Int
result'
let cancel SomeException
e = do
nerr <- IO Word32
getLastError
debugIO $ "## Exception occurred. Cancelling request... "
debugIO $ show (e :: SomeException) ++ " : " ++ show nerr
_ <- uninterruptibleMask_ $ FFI.cancelIoEx' h lpol
debugIO $ "## Waiting for cancellation record... "
_ <- FFI.getOverlappedResult h lpol True
oldDataPtr <- I.exchangePtr ptr_lpol nullReq
when (oldDataPtr == cdData) $
do reqs1 <- removeRequest
debugIO $ "-1.. " ++ show reqs1 ++ " requests queued after error."
completionCB' (fromIntegral nerr) 0
when (not threadedIOMgr) $
do
delay <- runExpiredTimeouts mgr
registerAlertableWait delay
return $ IOFailed Nothing
let runner = do String -> IO ()
debugIO (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ (String -> String
dbgMsg String
":: waiting ") String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" | " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Ptr (ZonkAny 6) -> String
forall a. Show a => a -> String
show Ptr (ZonkAny 6)
forall a. Ptr a
lpol
res <- MVar (IOResult a) -> IO (IOResult a)
forall a. MVar a -> IO a
readMVar MVar (IOResult a)
signal IO (IOResult a)
-> (SomeException -> IO (IOResult a)) -> IO (IOResult a)
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` SomeException -> IO (IOResult a)
forall {a}. SomeException -> IO (IOResult a)
cancel
debugIO $ dbgMsg ":: signaled "
case res of
IOFailed Maybe Int
err -> String -> Word32 -> IO (IOResult a)
forall a. String -> Word32 -> IO a
FFI.throwWinErr String
fname (Word32 -> (Int -> Word32) -> Maybe Int -> Word32
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Word32
0 Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Maybe Int
err)
IOResult a
_ -> IOResult a -> IO (IOResult a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return IOResult a
res
case startCBResult of
CbResult Int
CbPending -> IO (IOResult a)
runner
CbDone Maybe Word32
rdata -> do
oldDataPtr <- Ptr (Ptr CompletionData)
-> Ptr CompletionData -> IO (Ptr CompletionData)
forall a. Ptr (Ptr a) -> Ptr a -> IO (Ptr a)
I.exchangePtr Ptr (Ptr CompletionData)
forall a. Ptr a
ptr_lpol Ptr CompletionData
nullReq
if (oldDataPtr == cdData)
then
do reqs2 <- removeRequest
debugIO $ "-1.. " ++ show reqs2 ++ " requests queued."
debugIO $ dbgMsg $ ":: done " ++ show lpol ++ " - " ++ show rdata
bytes <- if isJust rdata
then return rdata
else FFI.getOverlappedResult h lpol False
cdDataCheck2 <- peek ptr_lpol :: IO (Ptr CompletionData)
debugIO $ dbgMsg $ ":: exit *ptr_lpol: " ++ show cdDataCheck2
debugIO $ dbgMsg $ ":: done bytes: " ++ show bytes
case bytes of
Just Word32
res -> CompletionCallback (IOResult a)
completionCB Word32
0 Word32
res
Maybe Word32
Nothing -> do err <- Ptr OVERLAPPED -> IO Int32
FFI.overlappedIOStatus Ptr OVERLAPPED
forall a. Ptr a
lpol
numBytes <- FFI.overlappedIONumBytes lpol
let err' = Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
err
debugIO $ dbgMsg $ ":: done callback: " ++ show err' ++ " - " ++ show numBytes
completionCB err' (fromIntegral numBytes)
else readMVar signal
CbError Int
err -> do
reqs3 <- IO CompletionKey
removeRequest
debugIO $ "-1.. " ++ show reqs3 ++ " requests queued."
let err' = Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
err
completionCB err' 0
CbResult Int
_ -> do
String -> IO (IOResult a)
forall a. HasCallStack => String -> a
error String
"unexpected case in `startCBResult'"
where dbgMsg :: String -> String
dbgMsg String
s = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" (" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Ptr () -> String
forall a. Show a => a -> String
show Ptr ()
h String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":" String -> String -> String
forall a. [a] -> [a] -> [a]
++ CompletionKey -> String
forall a. Show a => a -> String
show CompletionKey
offset String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
doShortWait :: IO ()
doShortWait :: IO ()
doShortWait
| Bool
threadedIOMgr = do
let usecs :: Int
usecs = Int
250
m <- IO (MVar ())
forall a. IO (MVar a)
newEmptyMVar
reg <- registerTimeout mgr usecs $
putMVar m () >> return ()
readMVar m `onException` unregisterTimeout mgr reg
| Bool
otherwise = Int -> IO ()
sleepBlock Int
1
waitForCompletion :: HANDLE -> Ptr FFI.OVERLAPPED -> IO (CbResult Int)
waitForCompletion :: Ptr () -> StartIOCallback Int
waitForCompletion Ptr ()
fhndl Ptr OVERLAPPED
lpol = do
res <- Ptr () -> Ptr OVERLAPPED -> Bool -> IO (Maybe Word32)
FFI.getOverlappedResult Ptr ()
fhndl Ptr OVERLAPPED
lpol Bool
False
status <- FFI.overlappedIOStatus lpol
case res of
Maybe Word32
Nothing | Int32
status Int32 -> Int32 -> Bool
forall a. Eq a => a -> a -> Bool
== -Int32
1073741807
{-# LINE 761 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
-> do
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
threadedIOMgr) IO ()
completeSynchronousRequest
CbResult Int -> IO (CbResult Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CbResult Int -> IO (CbResult Int))
-> CbResult Int -> IO (CbResult Int)
forall a b. (a -> b) -> a -> b
$ Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
res
| Bool
otherwise ->
do lasterr <- IO Word32
getLastError
let done = Word32 -> Bool
errorIsCompleted Word32
lasterr
unless done doShortWait
if done
then do when (not threadedIOMgr)
completeSynchronousRequest
return $ CbDone Nothing
else waitForCompletion fhndl lpol
Just Word32
_ -> do
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
threadedIOMgr) IO ()
completeSynchronousRequest
CbResult Int -> IO (CbResult Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CbResult Int -> IO (CbResult Int))
-> CbResult Int -> IO (CbResult Int)
forall a b. (a -> b) -> a -> b
$ Maybe Word32 -> CbResult Int
forall a. Maybe Word32 -> CbResult a
CbDone Maybe Word32
res
unless :: Bool -> IO () -> IO ()
unless :: Bool -> IO () -> IO ()
unless Bool
p IO ()
a = if Bool
p then IO ()
a else () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
withOverlapped :: String
-> HANDLE
-> Word64
-> StartIOCallback Int
-> CompletionCallback (IOResult a)
-> IO (IOResult a)
withOverlapped :: forall a.
String
-> Ptr ()
-> CompletionKey
-> StartIOCallback Int
-> CompletionCallback (IOResult a)
-> IO (IOResult a)
withOverlapped String
fname Ptr ()
h CompletionKey
offset StartIOCallback Int
startCB CompletionCallback (IOResult a)
completionCB = do
mngr <- IO Manager
getSystemManager
withOverlappedEx mngr fname h True offset startCB completionCB
errorIsCompleted :: ErrCode -> Bool
errorIsCompleted :: Word32 -> Bool
errorIsCompleted Word32
lasterr =
Word32
lasterr Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
38
{-# LINE 806 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
|| lasterr == 0
{-# LINE 807 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
|| lasterr == 109
{-# LINE 808 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
|| lasterr == 259
{-# LINE 809 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
|| lasterr == 995
{-# LINE 810 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
withException :: String -> IO (IOResult a) -> IO a
withException :: forall a. String -> IO (IOResult a) -> IO a
withException String
name IO (IOResult a)
fn
= do res <- IO (IOResult a)
fn
case res of
IOSuccess a
a -> a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
IOFailed (Just Int
err) -> String -> Word32 -> IO a
forall a. String -> Word32 -> IO a
FFI.throwWinErr String
name (Word32 -> IO a) -> Word32 -> IO a
forall a b. (a -> b) -> a -> b
$ Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
err
IOFailed Maybe Int
Nothing -> String -> Word32 -> IO a
forall a. String -> Word32 -> IO a
FFI.throwWinErr String
name Word32
0
ioSuccess :: a -> IO (IOResult a)
ioSuccess :: forall a. a -> IO (IOResult a)
ioSuccess = IOResult a -> IO (IOResult a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (IOResult a -> IO (IOResult a))
-> (a -> IOResult a) -> a -> IO (IOResult a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IOResult a
forall a. a -> IOResult a
IOSuccess
ioFailed :: Integral a => a -> IO (IOResult a)
ioFailed :: forall a. Integral a => a -> IO (IOResult a)
ioFailed = IOResult a -> IO (IOResult a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (IOResult a -> IO (IOResult a))
-> (a -> IOResult a) -> a -> IO (IOResult a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Int -> IOResult a
forall a. Maybe Int -> IOResult a
IOFailed (Maybe Int -> IOResult a) -> (a -> Maybe Int) -> a -> IOResult a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> (a -> Int) -> a -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
ioFailedAny :: Integral a => a -> IO (IOResult b)
ioFailedAny :: forall a b. Integral a => a -> IO (IOResult b)
ioFailedAny = IOResult b -> IO (IOResult b)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (IOResult b -> IO (IOResult b))
-> (a -> IOResult b) -> a -> IO (IOResult b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Int -> IOResult b
forall a. Maybe Int -> IOResult a
IOFailed (Maybe Int -> IOResult b) -> (a -> Maybe Int) -> a -> IOResult b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> (a -> Int) -> a -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
expirationTime :: Clock -> Int -> IO Q.Prio
expirationTime :: Clock -> Int -> IO CompletionKey
expirationTime Clock
mgr Int
us = do
now <- Clock -> IO Double
getTime Clock
mgr :: IO Seconds
let now_ns = Double -> CompletionKey
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> CompletionKey) -> Double -> CompletionKey
forall a b. (a -> b) -> a -> b
$ Double
now Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1000 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1000 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1000 :: Word64
let expTime
| (CompletionKey
forall a. Bounded a => a
maxBound CompletionKey -> CompletionKey -> CompletionKey
forall a. Num a => a -> a -> a
- CompletionKey
now_ns) CompletionKey -> CompletionKey -> CompletionKey
forall a. Integral a => a -> a -> a
`quot` CompletionKey
1000 CompletionKey -> CompletionKey -> Bool
forall a. Ord a => a -> a -> Bool
< Int -> CompletionKey
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
us = CompletionKey
forall a. Bounded a => a
maxBound :: Q.Prio
| Bool
otherwise = CompletionKey
now_ns CompletionKey -> CompletionKey -> CompletionKey
forall a. Num a => a -> a -> a
+ CompletionKey
ns
where ns :: CompletionKey
ns = CompletionKey
1000 CompletionKey -> CompletionKey -> CompletionKey
forall a. Num a => a -> a -> a
* Int -> CompletionKey
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
us
return expTime
{-# NOINLINE registerTimeout #-}
registerTimeout :: Manager -> Int -> TimeoutCallback -> IO TimeoutKey
registerTimeout :: Manager -> Int -> IO () -> IO TimeoutKey
registerTimeout mgr :: Manager
mgr@Manager{Maybe ThreadPool
UniqueSource
MVar (IntTable EventData)
IORef TimeoutQueue
Array OVERLAPPED_ENTRY
IOCP
Clock
mgrIOCP :: Manager -> IOCP
mgrClock :: Manager -> Clock
mgrUniqueSource :: Manager -> UniqueSource
mgrTimeouts :: Manager -> IORef TimeoutQueue
mgrEvntHandlers :: Manager -> MVar (IntTable EventData)
mgrOverlappedEntries :: Manager -> Array OVERLAPPED_ENTRY
mgrThreadPool :: Manager -> Maybe ThreadPool
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrEvntHandlers :: MVar (IntTable EventData)
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrThreadPool :: Maybe ThreadPool
..} Int
uSrelTime IO ()
cb = do
key <- UniqueSource -> IO Unique
newUnique UniqueSource
mgrUniqueSource
if uSrelTime <= 0 then cb
else do
!expTime <- expirationTime mgrClock uSrelTime :: IO Q.Prio
editTimeouts mgr (Q.unsafeInsertNew key expTime cb)
return $ TK key
updateTimeout :: Manager -> TimeoutKey -> Seconds -> IO ()
updateTimeout :: Manager -> TimeoutKey -> Double -> IO ()
updateTimeout Manager
mgr (TK Unique
key) Double
relTime = do
now <- Clock -> IO Double
getTime (Manager -> Clock
mgrClock Manager
mgr)
let !expTime = Double -> CompletionKey
secondsToNanoSeconds (Double -> CompletionKey) -> Double -> CompletionKey
forall a b. (a -> b) -> a -> b
$ Double
now Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
relTime
editTimeouts mgr (Q.adjust (const expTime) key)
unregisterTimeout :: Manager -> TimeoutKey -> IO ()
unregisterTimeout :: Manager -> TimeoutKey -> IO ()
unregisterTimeout Manager
mgr (TK Unique
key) = do
Manager -> TimeoutEdit -> IO ()
editTimeouts Manager
mgr (Unique -> TimeoutEdit
forall v. Unique -> IntPSQ v -> IntPSQ v
Q.delete Unique
key)
editTimeouts :: Manager -> TimeoutEdit -> IO ()
editTimeouts :: Manager -> TimeoutEdit -> IO ()
editTimeouts Manager
mgr TimeoutEdit
g = do
IORef TimeoutQueue -> (TimeoutQueue -> (TimeoutQueue, ())) -> IO ()
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' (Manager -> IORef TimeoutQueue
mgrTimeouts Manager
mgr) ((TimeoutQueue -> (TimeoutQueue, ())) -> IO ())
-> (TimeoutQueue -> (TimeoutQueue, ())) -> IO ()
forall a b. (a -> b) -> a -> b
$ \TimeoutQueue
tq -> (TimeoutEdit
g TimeoutQueue
tq, ())
IO ()
interruptSystemManager
runExpiredTimeouts :: Manager -> IO (Maybe Seconds)
runExpiredTimeouts :: Manager -> IO (Maybe Double)
runExpiredTimeouts Manager{Maybe ThreadPool
UniqueSource
MVar (IntTable EventData)
IORef TimeoutQueue
Array OVERLAPPED_ENTRY
IOCP
Clock
mgrIOCP :: Manager -> IOCP
mgrClock :: Manager -> Clock
mgrUniqueSource :: Manager -> UniqueSource
mgrTimeouts :: Manager -> IORef TimeoutQueue
mgrEvntHandlers :: Manager -> MVar (IntTable EventData)
mgrOverlappedEntries :: Manager -> Array OVERLAPPED_ENTRY
mgrThreadPool :: Manager -> Maybe ThreadPool
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrEvntHandlers :: MVar (IntTable EventData)
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrThreadPool :: Maybe ThreadPool
..} = do
now <- Clock -> IO Double
getTime Clock
mgrClock
(expired, delay) <- atomicModifyIORef' mgrTimeouts (mkTimeout now)
mapM_ Q.value expired
when (not threadedIOMgr && not (null expired))
completeSynchronousRequest
debugIO $ "expired calls: " ++ show (length expired)
return delay
where
mkTimeout :: Seconds -> TimeoutQueue ->
(TimeoutQueue, ([Q.Elem TimeoutCallback], Maybe Seconds))
mkTimeout :: Double
-> TimeoutQueue -> (TimeoutQueue, ([Elem (IO ())], Maybe Double))
mkTimeout Double
now TimeoutQueue
tq =
let (TimeoutQueue
tq', ([Elem (IO ())]
expired, Maybe CompletionKey
sec)) = CompletionKey
-> TimeoutQueue
-> (TimeoutQueue, ([Elem (IO ())], Maybe CompletionKey))
mkTimeout' (Double -> CompletionKey
secondsToNanoSeconds Double
now) TimeoutQueue
tq
in (TimeoutQueue
tq', ([Elem (IO ())]
expired, (CompletionKey -> Double) -> Maybe CompletionKey -> Maybe Double
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CompletionKey -> Double
nanoSecondsToSeconds Maybe CompletionKey
sec))
mkTimeout' :: Q.Prio -> TimeoutQueue ->
(TimeoutQueue, ([Q.Elem TimeoutCallback], Maybe Q.Prio))
mkTimeout' :: CompletionKey
-> TimeoutQueue
-> (TimeoutQueue, ([Elem (IO ())], Maybe CompletionKey))
mkTimeout' CompletionKey
now TimeoutQueue
tq =
let ([Elem (IO ())]
expired, TimeoutQueue
tq') = CompletionKey -> TimeoutQueue -> ([Elem (IO ())], TimeoutQueue)
forall v. CompletionKey -> IntPSQ v -> ([Elem v], IntPSQ v)
Q.atMost CompletionKey
now TimeoutQueue
tq in
case Elem (IO ()) -> CompletionKey
forall a. Elem a -> CompletionKey
Q.prio (Elem (IO ()) -> CompletionKey)
-> Maybe (Elem (IO ())) -> Maybe CompletionKey
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` TimeoutQueue -> Maybe (Elem (IO ()))
forall v. IntPSQ v -> Maybe (Elem v)
Q.findMin TimeoutQueue
tq' of
Maybe CompletionKey
Nothing ->
(TimeoutQueue
tq', ([Elem (IO ())]
expired, Maybe CompletionKey
forall a. Maybe a
Nothing))
Just CompletionKey
t ->
let !t' :: CompletionKey
t' = CompletionKey
t CompletionKey -> CompletionKey -> CompletionKey
forall a. Num a => a -> a -> a
- CompletionKey
now
in (TimeoutQueue
tq', ([Elem (IO ())]
expired, CompletionKey -> Maybe CompletionKey
forall a. a -> Maybe a
Just CompletionKey
t'))
fromTimeout :: Maybe Seconds -> Word32
fromTimeout :: Maybe Double -> Word32
fromTimeout Maybe Double
Nothing = Word32
120000
fromTimeout (Just Double
sec) | Double
sec Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
120 = Word32
120000
| Double
sec Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0 = Double -> Word32
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double
sec Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1000)
| Bool
otherwise = Word32
0
step :: Bool -> Manager -> IO (Bool, Maybe Seconds)
step :: Bool -> Manager -> IO (Bool, Maybe Double)
step Bool
maxDelay mgr :: Manager
mgr@Manager{Maybe ThreadPool
UniqueSource
MVar (IntTable EventData)
IORef TimeoutQueue
Array OVERLAPPED_ENTRY
IOCP
Clock
mgrIOCP :: Manager -> IOCP
mgrClock :: Manager -> Clock
mgrUniqueSource :: Manager -> UniqueSource
mgrTimeouts :: Manager -> IORef TimeoutQueue
mgrEvntHandlers :: Manager -> MVar (IntTable EventData)
mgrOverlappedEntries :: Manager -> Array OVERLAPPED_ENTRY
mgrThreadPool :: Manager -> Maybe ThreadPool
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrEvntHandlers :: MVar (IntTable EventData)
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrThreadPool :: Maybe ThreadPool
..} = do
delay <- Manager -> IO (Maybe Double)
runExpiredTimeouts Manager
mgr
let !timer = if Bool
maxDelay Bool -> Bool -> Bool
&& Maybe Double
delay Maybe Double -> Maybe Double -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe Double
forall a. Maybe a
Nothing
then Word32
4294967295
{-# LINE 966 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
else Maybe Double -> Word32
fromTimeout Maybe Double
delay
debugIO $ "next timer: " ++ show timer
if isJust delay
then debugIO $ "I/O manager waiting: delay=" ++ show delay
else debugIO $ "I/O manager pausing: maxDelay=" ++ show maxDelay
notifyWaiting mgrThreadPool
n <- FFI.getQueuedCompletionStatusEx mgrIOCP mgrOverlappedEntries timer
debugIO "WinIORunning"
notifyRunning mgrThreadPool
processCompletion mgr n delay
processCompletion :: Manager -> Int -> Maybe Seconds -> IO (Bool, Maybe Seconds)
processCompletion :: Manager -> Int -> Maybe Double -> IO (Bool, Maybe Double)
processCompletion Manager{Maybe ThreadPool
UniqueSource
MVar (IntTable EventData)
IORef TimeoutQueue
Array OVERLAPPED_ENTRY
IOCP
Clock
mgrIOCP :: Manager -> IOCP
mgrClock :: Manager -> Clock
mgrUniqueSource :: Manager -> UniqueSource
mgrTimeouts :: Manager -> IORef TimeoutQueue
mgrEvntHandlers :: Manager -> MVar (IntTable EventData)
mgrOverlappedEntries :: Manager -> Array OVERLAPPED_ENTRY
mgrThreadPool :: Manager -> Maybe ThreadPool
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrEvntHandlers :: MVar (IntTable EventData)
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrThreadPool :: Maybe ThreadPool
..} Int
n Maybe Double
delay = do
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
[Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..(Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
idx -> do
oe <- Array OVERLAPPED_ENTRY -> Int -> IO OVERLAPPED_ENTRY
forall a. Storable a => Array a -> Int -> IO a
A.unsafeRead Array OVERLAPPED_ENTRY
mgrOverlappedEntries Int
idx :: IO OVERLAPPED_ENTRY
let lpol = OVERLAPPED_ENTRY -> Ptr OVERLAPPED
lpOverlapped OVERLAPPED_ENTRY
oe
when (lpol /= nullPtr) $ do
let hs_lpol = Ptr OVERLAPPED -> Ptr HASKELL_OVERLAPPED
forall a b. Ptr a -> Ptr b
castPtr Ptr OVERLAPPED
lpol :: Ptr FFI.HASKELL_OVERLAPPED
let ptr_lpol = Ptr (ZonkAny 7) -> Ptr (Ptr CompletionData)
forall a b. Ptr a -> Ptr b
castPtr (Ptr HASKELL_OVERLAPPED
hs_lpol Ptr HASKELL_OVERLAPPED -> Int -> Ptr (ZonkAny 7)
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
cdOffset) :: Ptr (Ptr CompletionData)
cdDataCheck <- peek ptr_lpol
oldDataPtr <- I.exchangePtr ptr_lpol nullReq :: IO (Ptr CompletionData)
debugIO $ " $ checking " ++ show lpol
++ " -en ptr_lpol: " ++ show ptr_lpol
++ " offset: " ++ show cdOffset
++ " cdData: " ++ show cdDataCheck
++ " at idx " ++ show idx
ptrd <- peek ptr_lpol
debugIO $ ":: nullReq " ++ show nullReq
debugIO $ ":: oldDataPtr " ++ show oldDataPtr
debugIO $ ":: oldDataPtr (ptr)" ++ show ptrd
when (oldDataPtr /= nullPtr && oldDataPtr /= castPtr nullReq) $
do debugIO $ "exchanged: " ++ show oldDataPtr
payload <- peek oldDataPtr :: IO CompletionData
cb <- deRefStablePtr (cdCallback payload)
reqs <- removeRequest
debugIO $ "-1.. " ++ show reqs ++ " requests queued."
status <- FFI.overlappedIOStatus (lpOverlapped oe)
let status' = Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
status
let bytes = OVERLAPPED_ENTRY -> Word32
dwNumberOfBytesTransferred OVERLAPPED_ENTRY
oe
debugIO $ "?: status " ++ show status' ++ " - " ++ show bytes ++ " bytes return."
cb status' bytes
Array OVERLAPPED_ENTRY -> IO ()
forall a. Array a -> IO ()
A.clear Array OVERLAPPED_ENTRY
mgrOverlappedEntries
cap <- Array OVERLAPPED_ENTRY -> IO Int
forall a. Array a -> IO Int
A.capacity Array OVERLAPPED_ENTRY
mgrOverlappedEntries
when (cap == n) $ A.ensureCapacity mgrOverlappedEntries (2*cap)
reqs <- IO CompletionKey
outstandingRequests
debugIO $ "outstanding requests: " ++ show reqs
let more = CompletionKey
reqs CompletionKey -> CompletionKey -> Bool
forall a. Ord a => a -> a -> Bool
> CompletionKey
0
debugIO $ "has more: " ++ show more ++ " - removed: " ++ show n
return (more || (isJust delay && threadedIOMgr), delay)
processRemoteCompletion :: IO ()
processRemoteCompletion :: IO ()
processRemoteCompletion = do
{-# LINE 1125 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
(Ptr Word32 -> IO ()) -> IO ()
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Word32 -> IO ()) -> IO ()) -> (Ptr Word32 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr Word32
ptr_n -> do
String -> IO ()
debugIO String
"processRemoteCompletion :: start ()"
entries <- Ptr Word32 -> IO (Ptr OVERLAPPED_ENTRY)
getOverlappedEntries Ptr Word32
ptr_n
n <- fromIntegral `fmap` peek ptr_n
_ <- peekArray n entries
mngr <- getSystemManager
let arr = Manager -> Array OVERLAPPED_ENTRY
mgrOverlappedEntries Manager
mngr
A.unsafeCopyFromBuffer arr entries n
delay <- runExpiredTimeouts mngr :: IO (Maybe Seconds)
_ <- processCompletion mngr n delay
registerAlertableWait delay
debugIO "processRemoteCompletion :: done ()"
return ()
registerAlertableWait :: Maybe Seconds -> IO ()
registerAlertableWait :: Maybe Double -> IO ()
registerAlertableWait Maybe Double
Nothing =
Bool -> Word32 -> IO ()
c_registerAlertableWait Bool
False Word32
0
registerAlertableWait (Just Double
delay) =
Bool -> Word32 -> IO ()
c_registerAlertableWait Bool
True (Double -> Word32
secondsToMilliSeconds Double
delay)
io_mngr_loop :: HANDLE -> Manager -> IO ()
io_mngr_loop :: Ptr () -> Manager -> IO ()
io_mngr_loop Ptr ()
_event Manager
_mgr
| Bool -> Bool
not Bool
threadedIOMgr
= do String -> IO ()
debugIO String
"io_mngr_loop:no-op:called in non-threaded case"
() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
io_mngr_loop Ptr ()
_event Manager
mgr = Bool -> IO ()
go Bool
False
where
go :: Bool -> IO ()
go Bool
maxDelay =
do String -> IO ()
debugIO String
"io_mngr_loop:WinIORunning"
(more, delay) <- Bool -> Manager -> IO (Bool, Maybe Double)
step Bool
maxDelay Manager
mgr
let !use_max_delay = Bool -> Bool
not (Maybe Double -> Bool
forall a. Maybe a -> Bool
isJust Maybe Double
delay Bool -> Bool -> Bool
|| Bool
more)
debugIO "I/O manager stepping."
event_id <- c_readIOManagerEvent
exit <-
case event_id of
Word32
_ | Word32
event_id Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
io_MANAGER_WAKEUP -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Word32
_ | Word32
event_id Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
io_MANAGER_DIE -> IO ()
c_ioManagerFinished IO () -> IO Bool -> IO Bool
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
Word32
0 -> Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
Word32
_ -> do String -> IO ()
debugIO (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"handling console event: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Word32 -> String
forall a. Show a => a -> String
show (Word32
event_id Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
1)
Word32 -> IO ()
start_console_handler (Word32
event_id Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
1)
Bool -> IO Bool
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
case () of
()
_ | Bool
exit -> String -> IO ()
debugIO String
"I/O manager shutting down."
()
_ -> Bool -> IO ()
go Bool
use_max_delay
io_MANAGER_WAKEUP, io_MANAGER_DIE :: Word32
io_MANAGER_WAKEUP :: Word32
io_MANAGER_WAKEUP = Word32
4294967295
{-# LINE 1193 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
io_MANAGER_DIE = 4294967294
{-# LINE 1194 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
wakeupIOManager :: IO ()
wakeupIOManager :: IO ()
wakeupIOManager
= do mngr <- IO Manager
getSystemManager
_event <- c_getIOManagerEvent
debugIO "waking up I/O manager."
startIOManagerThread (io_mngr_loop (error "IOManagerEvent used") mngr)
foreign import ccall unsafe "getIOManagerEvent"
c_getIOManagerEvent :: IO HANDLE
foreign import ccall unsafe "readIOManagerEvent"
c_readIOManagerEvent :: IO Word32
foreign import ccall unsafe "ioManagerFinished"
c_ioManagerFinished :: IO ()
foreign import ccall unsafe "rtsSupportsBoundThreads" threadedIOMgr :: Bool
foreign import ccall unsafe "Sleep" sleepBlock :: Int -> IO ()
data HandleData = HandleData {
HandleData -> HandleKey
tokenKey :: {-# UNPACK #-} !HandleKey
, HandleData -> EventLifetime
tokenEvents :: {-# UNPACK #-} !EventLifetime
, HandleData -> EventCallback
_handleCallback :: !EventCallback
}
data HandleKey = HandleKey {
HandleKey -> Ptr ()
handleValue :: {-# UNPACK #-} !HANDLE
, HandleKey -> Unique
handleUnique :: {-# UNPACK #-} !Unique
} deriving ( HandleKey -> HandleKey -> Bool
(HandleKey -> HandleKey -> Bool)
-> (HandleKey -> HandleKey -> Bool) -> Eq HandleKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: HandleKey -> HandleKey -> Bool
== :: HandleKey -> HandleKey -> Bool
$c/= :: HandleKey -> HandleKey -> Bool
/= :: HandleKey -> HandleKey -> Bool
Eq
, Int -> HandleKey -> String -> String
[HandleKey] -> String -> String
HandleKey -> String
(Int -> HandleKey -> String -> String)
-> (HandleKey -> String)
-> ([HandleKey] -> String -> String)
-> Show HandleKey
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> HandleKey -> String -> String
showsPrec :: Int -> HandleKey -> String -> String
$cshow :: HandleKey -> String
show :: HandleKey -> String
$cshowList :: [HandleKey] -> String -> String
showList :: [HandleKey] -> String -> String
Show
)
type EventCallback = HandleKey -> Event -> IO ()
registerHandle :: Manager -> EventCallback -> HANDLE -> Event -> Lifetime
-> IO HandleKey
registerHandle :: Manager
-> EventCallback -> Ptr () -> Event -> Lifetime -> IO HandleKey
registerHandle (Manager{Maybe ThreadPool
UniqueSource
MVar (IntTable EventData)
IORef TimeoutQueue
Array OVERLAPPED_ENTRY
IOCP
Clock
mgrIOCP :: Manager -> IOCP
mgrClock :: Manager -> Clock
mgrUniqueSource :: Manager -> UniqueSource
mgrTimeouts :: Manager -> IORef TimeoutQueue
mgrEvntHandlers :: Manager -> MVar (IntTable EventData)
mgrOverlappedEntries :: Manager -> Array OVERLAPPED_ENTRY
mgrThreadPool :: Manager -> Maybe ThreadPool
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrEvntHandlers :: MVar (IntTable EventData)
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrThreadPool :: Maybe ThreadPool
..}) EventCallback
cb Ptr ()
hwnd Event
evs Lifetime
lt = do
u <- UniqueSource -> IO Unique
newUnique UniqueSource
mgrUniqueSource
let reg = Ptr () -> Unique -> HandleKey
HandleKey Ptr ()
hwnd Unique
u
hwnd' = IntPtr -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IntPtr -> Int) -> IntPtr -> Int
forall a b. (a -> b) -> a -> b
$ Ptr () -> IntPtr
forall a. Ptr a -> IntPtr
ptrToIntPtr Ptr ()
hwnd
el = Event -> Lifetime -> EventLifetime
I.eventLifetime Event
evs Lifetime
lt
!hwdd = HandleKey -> EventLifetime -> EventCallback -> HandleData
HandleData HandleKey
reg EventLifetime
el EventCallback
cb
event = Event -> EventElements -> EventData
EventData Event
evs [(Event
evs, HandleData
hwdd)]
_ <- withMVar mgrEvntHandlers $ \IntTable EventData
evts -> do
(EventData -> EventData -> EventData)
-> Int -> EventData -> IntTable EventData -> IO (Maybe EventData)
forall a. (a -> a -> a) -> Int -> a -> IntTable a -> IO (Maybe a)
IT.insertWith EventData -> EventData -> EventData
forall a. Monoid a => a -> a -> a
mappend Int
hwnd' EventData
event IntTable EventData
evts
wakeupIOManager
return reg
unregisterHandle :: Manager -> HandleKey -> IO ()
unregisterHandle :: Manager -> HandleKey -> IO ()
unregisterHandle (Manager{Maybe ThreadPool
UniqueSource
MVar (IntTable EventData)
IORef TimeoutQueue
Array OVERLAPPED_ENTRY
IOCP
Clock
mgrIOCP :: Manager -> IOCP
mgrClock :: Manager -> Clock
mgrUniqueSource :: Manager -> UniqueSource
mgrTimeouts :: Manager -> IORef TimeoutQueue
mgrEvntHandlers :: Manager -> MVar (IntTable EventData)
mgrOverlappedEntries :: Manager -> Array OVERLAPPED_ENTRY
mgrThreadPool :: Manager -> Maybe ThreadPool
mgrIOCP :: IOCP
mgrClock :: Clock
mgrUniqueSource :: UniqueSource
mgrTimeouts :: IORef TimeoutQueue
mgrEvntHandlers :: MVar (IntTable EventData)
mgrOverlappedEntries :: Array OVERLAPPED_ENTRY
mgrThreadPool :: Maybe ThreadPool
..}) key :: HandleKey
key@HandleKey{Ptr ()
Unique
handleValue :: HandleKey -> Ptr ()
handleUnique :: HandleKey -> Unique
handleValue :: Ptr ()
handleUnique :: Unique
..} = do
MVar (IntTable EventData) -> (IntTable EventData -> IO ()) -> IO ()
forall a b. MVar a -> (a -> IO b) -> IO b
withMVar MVar (IntTable EventData)
mgrEvntHandlers ((IntTable EventData -> IO ()) -> IO ())
-> (IntTable EventData -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \IntTable EventData
evts -> do
let hwnd' :: Int
hwnd' = IntPtr -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IntPtr -> Int) -> IntPtr -> Int
forall a b. (a -> b) -> a -> b
$ Ptr () -> IntPtr
forall a. Ptr a -> IntPtr
ptrToIntPtr Ptr ()
handleValue
val <- Int -> IntTable EventData -> IO (Maybe EventData)
forall a. Int -> IntTable a -> IO (Maybe a)
IT.lookup Int
hwnd' IntTable EventData
evts
case val of
Maybe EventData
Nothing -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just (EventData Event
evs EventElements
lst) -> do
let cmp :: (a, HandleData) -> (a, HandleData) -> Bool
cmp (a
_, HandleData
a) (a
_, HandleData
b) = HandleData -> HandleKey
tokenKey HandleData
a HandleKey -> HandleKey -> Bool
forall a. Eq a => a -> a -> Bool
== HandleData -> HandleKey
tokenKey HandleData
b
key' :: (a, HandleData)
key' = (a
forall a. HasCallStack => a
undefined, HandleKey -> EventLifetime -> EventCallback -> HandleData
HandleData HandleKey
key EventLifetime
forall a. HasCallStack => a
undefined EventCallback
forall a. HasCallStack => a
undefined)
updated :: EventElements
updated = ((Event, HandleData) -> (Event, HandleData) -> Bool)
-> (Event, HandleData) -> EventElements -> EventElements
forall a. (a -> a -> Bool) -> a -> [a] -> [a]
deleteBy (Event, HandleData) -> (Event, HandleData) -> Bool
forall {a} {a}. (a, HandleData) -> (a, HandleData) -> Bool
cmp (Event, HandleData)
forall {a}. (a, HandleData)
key' EventElements
lst
new_lst :: EventData
new_lst = Event -> EventElements -> EventData
EventData Event
evs EventElements
updated
_ <- (EventData -> Maybe EventData)
-> Int -> IntTable EventData -> IO (Maybe EventData)
forall a. (a -> Maybe a) -> Int -> IntTable a -> IO (Maybe a)
IT.updateWith (\EventData
_ -> EventData -> Maybe EventData
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return EventData
new_lst) Int
hwnd' IntTable EventData
evts
return ()
{-# LINE 1283 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
debugIO :: String -> IO ()
{-# LINE 1299 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}
debugIO :: String -> IO ()
debugIO String
_ = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# LINE 1301 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows.hsc" #-}