{-# LINE 1 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DoAndIfThenElse #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoImplicitPrelude #-}
module GHC.Internal.Event.Windows.FFI (
IOCP(..),
CompletionKey,
newIOCP,
associateHandleWithIOCP,
getQueuedCompletionStatusEx,
postQueuedCompletionStatus,
getOverlappedResult,
CompletionData(..),
CompletionCallback,
withRequest,
OVERLAPPED,
LPOVERLAPPED,
OVERLAPPED_ENTRY(..),
LPOVERLAPPED_ENTRY,
HASKELL_OVERLAPPED,
LPHASKELL_OVERLAPPED,
allocOverlapped,
zeroOverlapped,
pokeOffsetOverlapped,
overlappedIOStatus,
overlappedIONumBytes,
cancelIoEx,
cancelIoEx',
getTickCount64,
queryPerformanceCounter,
queryPerformanceFrequency,
throwWinErr,
setLastError
) where
import GHC.Internal.Data.Maybe
import GHC.Internal.Base
import GHC.Internal.Num ((*))
import GHC.Internal.Foreign.Marshal.Alloc
import GHC.Internal.Foreign.Marshal.Utils
import GHC.Internal.Foreign.Storable
import GHC.Internal.Int
import GHC.Internal.Ptr
import GHC.Internal.Word
import GHC.Internal.Stable
import GHC.Internal.Real (fromIntegral)
import GHC.Internal.Show
import GHC.Internal.Windows
import qualified GHC.Internal.Event.Array as A
import qualified GHC.Internal.Windows as Win32
import GHC.Internal.IO.Handle.Internals (debugIO)
newtype IOCP = IOCP HANDLE
deriving (IOCP -> IOCP -> Bool
(IOCP -> IOCP -> Bool) -> (IOCP -> IOCP -> Bool) -> Eq IOCP
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IOCP -> IOCP -> Bool
== :: IOCP -> IOCP -> Bool
$c/= :: IOCP -> IOCP -> Bool
/= :: IOCP -> IOCP -> Bool
Eq, Eq IOCP
Eq IOCP =>
(IOCP -> IOCP -> Ordering)
-> (IOCP -> IOCP -> Bool)
-> (IOCP -> IOCP -> Bool)
-> (IOCP -> IOCP -> Bool)
-> (IOCP -> IOCP -> Bool)
-> (IOCP -> IOCP -> IOCP)
-> (IOCP -> IOCP -> IOCP)
-> Ord IOCP
IOCP -> IOCP -> Bool
IOCP -> IOCP -> Ordering
IOCP -> IOCP -> IOCP
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IOCP -> IOCP -> Ordering
compare :: IOCP -> IOCP -> Ordering
$c< :: IOCP -> IOCP -> Bool
< :: IOCP -> IOCP -> Bool
$c<= :: IOCP -> IOCP -> Bool
<= :: IOCP -> IOCP -> Bool
$c> :: IOCP -> IOCP -> Bool
> :: IOCP -> IOCP -> Bool
$c>= :: IOCP -> IOCP -> Bool
>= :: IOCP -> IOCP -> Bool
$cmax :: IOCP -> IOCP -> IOCP
max :: IOCP -> IOCP -> IOCP
$cmin :: IOCP -> IOCP -> IOCP
min :: IOCP -> IOCP -> IOCP
Ord, Int -> IOCP -> ShowS
[IOCP] -> ShowS
IOCP -> String
(Int -> IOCP -> ShowS)
-> (IOCP -> String) -> ([IOCP] -> ShowS) -> Show IOCP
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IOCP -> ShowS
showsPrec :: Int -> IOCP -> ShowS
$cshow :: IOCP -> String
show :: IOCP -> String
$cshowList :: [IOCP] -> ShowS
showList :: [IOCP] -> ShowS
Show)
type CompletionKey = ULONG_PTR
foreign import ccall unsafe "windows.h CreateIoCompletionPort"
c_CreateIoCompletionPort :: HANDLE -> IOCP -> ULONG_PTR -> DWORD
-> IO IOCP
newIOCP :: IO IOCP
newIOCP :: IO IOCP
newIOCP = (IOCP -> Bool) -> String -> IO IOCP -> IO IOCP
forall a. (a -> Bool) -> String -> IO a -> IO a
failIf (IOCP -> IOCP -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr () -> IOCP
IOCP Ptr ()
forall a. Ptr a
nullPtr) String
"newIOCP" (IO IOCP -> IO IOCP) -> IO IOCP -> IO IOCP
forall a b. (a -> b) -> a -> b
$
Ptr () -> IOCP -> Word64 -> Word32 -> IO IOCP
c_CreateIoCompletionPort Ptr ()
iNVALID_HANDLE_VALUE (Ptr () -> IOCP
IOCP Ptr ()
forall a. Ptr a
nullPtr) Word64
0 Word32
0
associateHandleWithIOCP :: IOCP -> HANDLE -> CompletionKey -> IO ()
associateHandleWithIOCP :: IOCP -> Ptr () -> Word64 -> IO ()
associateHandleWithIOCP IOCP
iocp Ptr ()
handle Word64
completionKey =
(IOCP -> Bool) -> String -> IO IOCP -> IO ()
forall a. (a -> Bool) -> String -> IO a -> IO ()
failIf_ (IOCP -> IOCP -> Bool
forall a. Eq a => a -> a -> Bool
/= IOCP
iocp) String
"associateHandleWithIOCP" (IO IOCP -> IO ()) -> IO IOCP -> IO ()
forall a b. (a -> b) -> a -> b
$
Ptr () -> IOCP -> Word64 -> Word32 -> IO IOCP
c_CreateIoCompletionPort Ptr ()
handle IOCP
iocp Word64
completionKey Word32
0
foreign import ccall safe "windows.h GetOverlappedResult"
c_GetOverlappedResult :: HANDLE -> LPOVERLAPPED -> Ptr DWORD -> BOOL
-> IO BOOL
getOverlappedResult :: HANDLE -> Ptr OVERLAPPED -> BOOL -> IO (Maybe DWORD)
getOverlappedResult :: Ptr () -> Ptr OVERLAPPED -> Bool -> IO (Maybe Word32)
getOverlappedResult Ptr ()
handle Ptr OVERLAPPED
lp Bool
block
= (Ptr Word32 -> IO (Maybe Word32)) -> IO (Maybe Word32)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Word32 -> IO (Maybe Word32)) -> IO (Maybe Word32))
-> (Ptr Word32 -> IO (Maybe Word32)) -> IO (Maybe Word32)
forall a b. (a -> b) -> a -> b
$ \Ptr Word32
bytes ->
do res <- Ptr () -> Ptr OVERLAPPED -> Ptr Word32 -> Bool -> IO Bool
c_GetOverlappedResult Ptr ()
handle Ptr OVERLAPPED
lp Ptr Word32
bytes Bool
block
if res
then fmap Just $ peek bytes
else return Nothing
foreign import ccall safe "windows.h GetQueuedCompletionStatusEx"
c_GetQueuedCompletionStatusEx :: IOCP -> LPOVERLAPPED_ENTRY -> Word32
-> Ptr ULONG -> DWORD -> BOOL -> IO BOOL
getQueuedCompletionStatusEx :: IOCP
-> A.Array OVERLAPPED_ENTRY
-> DWORD
-> IO Int
getQueuedCompletionStatusEx :: IOCP -> Array OVERLAPPED_ENTRY -> Word32 -> IO Int
getQueuedCompletionStatusEx IOCP
iocp Array OVERLAPPED_ENTRY
arr Word32
timeout =
(Ptr Word32 -> IO Int) -> IO Int
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Word32 -> IO Int) -> IO Int)
-> (Ptr Word32 -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ \Ptr Word32
num_removed_ptr ->do
Array OVERLAPPED_ENTRY
-> (Ptr OVERLAPPED_ENTRY -> Int -> IO Int) -> IO Int
forall a. Array a -> (Ptr a -> Int -> IO Int) -> IO Int
A.unsafeLoad Array OVERLAPPED_ENTRY
arr ((Ptr OVERLAPPED_ENTRY -> Int -> IO Int) -> IO Int)
-> (Ptr OVERLAPPED_ENTRY -> Int -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ \Ptr OVERLAPPED_ENTRY
oes Int
cap -> do
Ptr OVERLAPPED_ENTRY -> Word8 -> Int -> IO ()
forall a. Ptr a -> Word8 -> Int -> IO ()
fillBytes Ptr OVERLAPPED_ENTRY
oes Word8
0 (Int
cap Int -> Int -> Int
forall a. Num a => a -> a -> a
* (OVERLAPPED_ENTRY -> Int
forall a. Storable a => a -> Int
sizeOf (OVERLAPPED_ENTRY
forall a. HasCallStack => a
undefined :: OVERLAPPED_ENTRY)))
String -> IO ()
debugIO (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"-- call getQueuedCompletionStatusEx "
let alertable :: Bool
alertable = Bool
False
ok <- IOCP
-> Ptr OVERLAPPED_ENTRY
-> Word32
-> Ptr Word32
-> Word32
-> Bool
-> IO Bool
c_GetQueuedCompletionStatusEx IOCP
iocp Ptr OVERLAPPED_ENTRY
oes (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
cap)
Ptr Word32
num_removed_ptr Word32
timeout Bool
alertable
debugIO $ "-- call getQueuedCompletionStatusEx: " ++ show ok
err <- getLastError
nc <- (peek num_removed_ptr)
debugIO $ "-- getQueuedCompletionStatusEx: n=" ++ show nc ++ " ,err=" ++ show err
if ok then fromIntegral `fmap` peek num_removed_ptr
else do debugIO $ "failed getQueuedCompletionStatusEx: " ++ show err
if err == 258 || alertable then return 0
{-# LINE 200 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
else failWith "GetQueuedCompletionStatusEx" err
overlappedIOStatus :: LPOVERLAPPED -> IO NTSTATUS
overlappedIOStatus :: Ptr OVERLAPPED -> IO Int32
overlappedIOStatus Ptr OVERLAPPED
lpol = do
status <- (\Ptr OVERLAPPED
hsc_ptr -> Ptr OVERLAPPED -> Int -> IO Int32
forall b. Ptr b -> Int -> IO Int32
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr OVERLAPPED
hsc_ptr Int
0) Ptr OVERLAPPED
lpol
{-# LINE 205 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
return status
{-# INLINE overlappedIOStatus #-}
overlappedIONumBytes :: LPOVERLAPPED -> IO ULONG_PTR
overlappedIONumBytes :: Ptr OVERLAPPED -> IO Word64
overlappedIONumBytes Ptr OVERLAPPED
lpol = do
bytes <- (\Ptr OVERLAPPED
hsc_ptr -> Ptr OVERLAPPED -> Int -> IO Word64
forall b. Ptr b -> Int -> IO Word64
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr OVERLAPPED
hsc_ptr Int
8) Ptr OVERLAPPED
lpol
{-# LINE 213 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
return bytes
{-# INLINE overlappedIONumBytes #-}
foreign import ccall unsafe "windows.h PostQueuedCompletionStatus"
c_PostQueuedCompletionStatus :: IOCP -> DWORD -> ULONG_PTR -> LPOVERLAPPED
-> IO BOOL
postQueuedCompletionStatus :: IOCP -> DWORD -> CompletionKey -> LPOVERLAPPED
-> IO ()
postQueuedCompletionStatus :: IOCP -> Word32 -> Word64 -> Ptr OVERLAPPED -> IO ()
postQueuedCompletionStatus IOCP
iocp Word32
numBytes Word64
completionKey Ptr OVERLAPPED
lpol =
String -> IO Bool -> IO ()
failIfFalse_ String
"PostQueuedCompletionStatus" (IO Bool -> IO ()) -> IO Bool -> IO ()
forall a b. (a -> b) -> a -> b
$
IOCP -> Word32 -> Word64 -> Ptr OVERLAPPED -> IO Bool
c_PostQueuedCompletionStatus IOCP
iocp Word32
numBytes Word64
completionKey Ptr OVERLAPPED
lpol
type CompletionCallback a = ErrCode
-> DWORD
-> IO a
type IOCallback = CompletionCallback ()
data CompletionData = CompletionData { CompletionData -> Ptr ()
cdHandle :: !HANDLE
, CompletionData -> StablePtr IOCallback
cdCallback :: !(StablePtr IOCallback)
}
instance Storable CompletionData where
sizeOf :: CompletionData -> Int
sizeOf CompletionData
_ = (Int
16)
{-# LINE 252 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
alignment _ = 8
{-# LINE 253 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
peek :: Ptr CompletionData -> IO CompletionData
peek Ptr CompletionData
ptr = do
cdCallback <- (\Ptr CompletionData
hsc_ptr -> Ptr CompletionData -> Int -> IO (StablePtr IOCallback)
forall b. Ptr b -> Int -> IO (StablePtr IOCallback)
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr CompletionData
hsc_ptr Int
8) Ptr CompletionData
ptr
{-# LINE 256 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
cdHandle <- (\hsc_ptr -> peekByteOff hsc_ptr 0) ptr
{-# LINE 257 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
let !cd = CompletionData{..}
return cd
poke :: Ptr CompletionData -> CompletionData -> IO ()
poke Ptr CompletionData
ptr CompletionData{StablePtr IOCallback
Ptr ()
cdHandle :: CompletionData -> Ptr ()
cdCallback :: CompletionData -> StablePtr IOCallback
cdHandle :: Ptr ()
cdCallback :: StablePtr IOCallback
..} = do
(\Ptr CompletionData
hsc_ptr -> Ptr CompletionData -> Int -> StablePtr IOCallback -> IO ()
forall b. Ptr b -> Int -> StablePtr IOCallback -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr CompletionData
hsc_ptr Int
8) Ptr CompletionData
ptr StablePtr IOCallback
cdCallback
{-# LINE 262 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
(\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr cdHandle
{-# LINE 263 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
data OVERLAPPED
data HASKELL_OVERLAPPED
type LPOVERLAPPED = Ptr OVERLAPPED
type LPHASKELL_OVERLAPPED = Ptr HASKELL_OVERLAPPED
data OVERLAPPED_ENTRY = OVERLAPPED_ENTRY {
OVERLAPPED_ENTRY -> Word64
lpCompletionKey :: ULONG_PTR,
OVERLAPPED_ENTRY -> Ptr OVERLAPPED
lpOverlapped :: LPOVERLAPPED,
OVERLAPPED_ENTRY -> Word32
dwNumberOfBytesTransferred :: DWORD
}
type LPOVERLAPPED_ENTRY = Ptr OVERLAPPED_ENTRY
instance Storable OVERLAPPED_ENTRY where
sizeOf :: OVERLAPPED_ENTRY -> Int
sizeOf OVERLAPPED_ENTRY
_ = (Int
32)
{-# LINE 293 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
alignment _ = 8
{-# LINE 294 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
peek :: Ptr OVERLAPPED_ENTRY -> IO OVERLAPPED_ENTRY
peek Ptr OVERLAPPED_ENTRY
ptr = do
lpCompletionKey <- (\Ptr OVERLAPPED_ENTRY
hsc_ptr -> Ptr OVERLAPPED_ENTRY -> Int -> IO Word64
forall b. Ptr b -> Int -> IO Word64
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr OVERLAPPED_ENTRY
hsc_ptr Int
0) Ptr OVERLAPPED_ENTRY
ptr
{-# LINE 297 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
lpOverlapped <- (\hsc_ptr -> peekByteOff hsc_ptr 8) ptr
{-# LINE 298 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
dwNumberOfBytesTransferred <-
(\hsc_ptr -> peekByteOff hsc_ptr 24) ptr
{-# LINE 300 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
let !oe = OVERLAPPED_ENTRY{..}
return oe
poke :: Ptr OVERLAPPED_ENTRY -> OVERLAPPED_ENTRY -> IO ()
poke Ptr OVERLAPPED_ENTRY
ptr OVERLAPPED_ENTRY{Word32
Word64
Ptr OVERLAPPED
lpCompletionKey :: OVERLAPPED_ENTRY -> Word64
lpOverlapped :: OVERLAPPED_ENTRY -> Ptr OVERLAPPED
dwNumberOfBytesTransferred :: OVERLAPPED_ENTRY -> Word32
lpCompletionKey :: Word64
lpOverlapped :: Ptr OVERLAPPED
dwNumberOfBytesTransferred :: Word32
..} = do
(\Ptr OVERLAPPED_ENTRY
hsc_ptr -> Ptr OVERLAPPED_ENTRY -> Int -> Word64 -> IO ()
forall b. Ptr b -> Int -> Word64 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr OVERLAPPED_ENTRY
hsc_ptr Int
0) Ptr OVERLAPPED_ENTRY
ptr Word64
lpCompletionKey
{-# LINE 305 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
(\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr lpOverlapped
{-# LINE 306 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
(\hsc_ptr -> pokeByteOff hsc_ptr 24)
{-# LINE 307 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
ptr dwNumberOfBytesTransferred
allocOverlapped :: Word64
-> IO (Ptr HASKELL_OVERLAPPED)
allocOverlapped :: Word64 -> IO (Ptr HASKELL_OVERLAPPED)
allocOverlapped Word64
offset = do
lpol <- Int -> IO (Ptr HASKELL_OVERLAPPED)
forall a. Int -> IO (Ptr a)
mallocBytes (Int
40)
{-# LINE 325 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
zeroOverlapped lpol
pokeOffsetOverlapped (castPtr lpol) offset
return lpol
zeroOverlapped :: LPHASKELL_OVERLAPPED -> IO ()
zeroOverlapped :: Ptr HASKELL_OVERLAPPED -> IO ()
zeroOverlapped Ptr HASKELL_OVERLAPPED
lpol = Ptr HASKELL_OVERLAPPED -> Word8 -> Int -> IO ()
forall a. Ptr a -> Word8 -> Int -> IO ()
fillBytes Ptr HASKELL_OVERLAPPED
lpol Word8
0 (Int
40)
{-# LINE 332 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
{-# INLINE zeroOverlapped #-}
pokeOffsetOverlapped :: LPOVERLAPPED -> Word64 -> IO ()
pokeOffsetOverlapped :: Ptr OVERLAPPED -> Word64 -> IO ()
pokeOffsetOverlapped Ptr OVERLAPPED
lpol Word64
offset = do
let (Word32
offsetHigh, Word32
offsetLow) = Word64 -> (Word32, Word32)
Win32.ddwordToDwords Word64
offset
(\Ptr OVERLAPPED
hsc_ptr -> Ptr OVERLAPPED -> Int -> Word32 -> IO ()
forall b. Ptr b -> Int -> Word32 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr OVERLAPPED
hsc_ptr Int
16) Ptr OVERLAPPED
lpol Word32
offsetLow
{-# LINE 339 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
(\hsc_ptr -> pokeByteOff hsc_ptr 20) lpol offsetHigh
{-# LINE 340 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
{-# INLINE pokeOffsetOverlapped #-}
pokeEventOverlapped :: LPOVERLAPPED -> HANDLE -> IO ()
pokeEventOverlapped :: Ptr OVERLAPPED -> Ptr () -> IO ()
pokeEventOverlapped Ptr OVERLAPPED
lpol Ptr ()
event = do
(\Ptr OVERLAPPED
hsc_ptr -> Ptr OVERLAPPED -> Int -> Ptr () -> IO ()
forall b. Ptr b -> Int -> Ptr () -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr OVERLAPPED
hsc_ptr Int
24) Ptr OVERLAPPED
lpol Ptr ()
event
{-# LINE 346 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
{-# INLINE pokeEventOverlapped #-}
withRequest :: Bool -> Word64 -> HANDLE -> IOCallback
-> (Ptr HASKELL_OVERLAPPED -> Ptr CompletionData -> IO a)
-> IO a
withRequest :: forall a.
Bool
-> Word64
-> Ptr ()
-> IOCallback
-> (Ptr HASKELL_OVERLAPPED -> Ptr CompletionData -> IO a)
-> IO a
withRequest Bool
async Word64
offset Ptr ()
hdl IOCallback
cb Ptr HASKELL_OVERLAPPED -> Ptr CompletionData -> IO a
f = do
cb_sptr <- IOCallback -> IO (StablePtr IOCallback)
forall a. a -> IO (StablePtr a)
newStablePtr IOCallback
cb
let cbData :: CompletionData
cbData = Ptr () -> StablePtr IOCallback -> CompletionData
CompletionData Ptr ()
hdl StablePtr IOCallback
cb_sptr
r <- allocaBytes (40) $ \Ptr HASKELL_OVERLAPPED
hs_lpol ->
{-# LINE 421 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
with cbData $ \cdData -> do
zeroOverlapped hs_lpol
let lpol = castPtr hs_lpol
pokeOffsetOverlapped lpol offset
case async of
True -> f hs_lpol cdData
False -> do
event <- failIfNull "withRequest (create)" $
c_CreateEvent nullPtr True False nullPtr
debugIO $ "{{ event " ++ show event ++ " for " ++ show hs_lpol
pokeEventOverlapped lpol event
res <- f hs_lpol cdData
failIfFalse_ "withRequest (free)" $ c_CloseHandle event
return res
freeStablePtr cb_sptr
return r
foreign import ccall unsafe "windows.h CreateEventW"
c_CreateEvent :: Ptr () -> Bool -> Bool -> LPCWSTR -> IO HANDLE
foreign import ccall unsafe "windows.h CloseHandle"
c_CloseHandle :: HANDLE -> IO Bool
foreign import ccall unsafe "windows.h CancelIoEx"
c_CancelIoEx :: HANDLE -> LPOVERLAPPED -> IO BOOL
cancelIoEx :: HANDLE -> LPOVERLAPPED -> IO ()
cancelIoEx :: Ptr () -> Ptr OVERLAPPED -> IO ()
cancelIoEx Ptr ()
h Ptr OVERLAPPED
o = String -> IO Bool -> IO ()
failIfFalse_ String
"CancelIoEx" (IO Bool -> IO ())
-> (Ptr OVERLAPPED -> IO Bool) -> Ptr OVERLAPPED -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr () -> Ptr OVERLAPPED -> IO Bool
c_CancelIoEx Ptr ()
h (Ptr OVERLAPPED -> IO ()) -> Ptr OVERLAPPED -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr OVERLAPPED
o
cancelIoEx' :: HANDLE -> LPOVERLAPPED -> IO Bool
cancelIoEx' :: Ptr () -> Ptr OVERLAPPED -> IO Bool
cancelIoEx' = Ptr () -> Ptr OVERLAPPED -> IO Bool
c_CancelIoEx
foreign import ccall "windows.h GetTickCount64"
c_GetTickCount64 :: IO Word64
{-# LINE 474 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
getTickCount64 :: IO Word64
getTickCount64 :: IO Word64
getTickCount64 = IO Word64
c_GetTickCount64
queryPerformanceCounter :: IO Int64
queryPerformanceCounter :: IO Int64
queryPerformanceCounter =
QPFunc -> IO (Maybe Int64)
callQP QPFunc
c_QueryPerformanceCounter
IO (Maybe Int64) -> (Maybe Int64 -> IO Int64) -> IO Int64
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO Int64 -> (Int64 -> IO Int64) -> Maybe Int64 -> IO Int64
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> IO Int64
forall a. String -> IO a
throwGetLastError String
"QueryPerformanceCounter") Int64 -> IO Int64
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return
queryPerformanceFrequency :: IO (Maybe Int64)
queryPerformanceFrequency :: IO (Maybe Int64)
queryPerformanceFrequency = do
m <- QPFunc -> IO (Maybe Int64)
callQP QPFunc
c_QueryPerformanceFrequency
case m of
Maybe Int64
Nothing -> Maybe Int64 -> IO (Maybe Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int64
forall a. Maybe a
Nothing
Just Int64
0 -> Maybe Int64 -> IO (Maybe Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int64
forall a. Maybe a
Nothing
Just Int64
freq -> Maybe Int64 -> IO (Maybe Int64)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int64 -> Maybe Int64
forall a. a -> Maybe a
Just Int64
freq)
type QPFunc = Ptr Int64 -> IO BOOL
foreign import ccall "Windows.h QueryPerformanceCounter"
c_QueryPerformanceCounter :: QPFunc
foreign import ccall "Windows.h QueryPerformanceFrequency"
c_QueryPerformanceFrequency :: QPFunc
callQP :: QPFunc -> IO (Maybe Int64)
callQP :: QPFunc -> IO (Maybe Int64)
callQP QPFunc
qpfunc =
Int -> (Ptr Int64 -> IO (Maybe Int64)) -> IO (Maybe Int64)
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (Int
8) ((Ptr Int64 -> IO (Maybe Int64)) -> IO (Maybe Int64))
-> (Ptr Int64 -> IO (Maybe Int64)) -> IO (Maybe Int64)
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
ptr -> do
{-# LINE 529 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
ok <- QPFunc
qpfunc Ptr Int64
ptr
if ok then do
n <- (\Ptr Int64
hsc_ptr -> Ptr Int64 -> Int -> IO Int64
forall b. Ptr b -> Int -> IO Int64
forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff Ptr Int64
hsc_ptr Int
0) ptr
{-# LINE 532 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
return (Just n)
else
return Nothing
type ULONG_PTR = Word64
{-# LINE 540 "libraries\\ghc-internal\\src\\GHC\\Internal\\Event\\Windows\\FFI.hsc" #-}
throwWinErr :: String -> ErrCode -> IO a
throwWinErr :: forall a. String -> Word32 -> IO a
throwWinErr String
loc Word32
err = do
Word32 -> IO ()
c_SetLastError Word32
err
String -> Word32 -> IO a
forall a. String -> Word32 -> IO a
Win32.failWith String
loc Word32
err
setLastError :: ErrCode -> IO ()
setLastError :: Word32 -> IO ()
setLastError = Word32 -> IO ()
c_SetLastError
foreign import ccall unsafe "windows.h SetLastError"
c_SetLastError :: ErrCode -> IO ()