| Copyright | (c) Tamar Christina 2019 |
|---|---|
| License | BSD-style (see the file libraries/base/LICENSE) |
| Maintainer | libraries@haskell.org |
| Stability | stable |
| Portability | non-portable |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
GHC.Event.Windows.FFI
Description
WinIO Windows API Foreign Function imports
Synopsis
- newtype IOCP = IOCP HANDLE
- type CompletionKey = ULONG_PTR
- newIOCP :: IO IOCP
- associateHandleWithIOCP :: IOCP -> HANDLE -> CompletionKey -> IO ()
- getQueuedCompletionStatusEx :: IOCP -> Array OVERLAPPED_ENTRY -> DWORD -> IO Int
- postQueuedCompletionStatus :: IOCP -> DWORD -> CompletionKey -> LPOVERLAPPED -> IO ()
- getOverlappedResult :: HANDLE -> Ptr OVERLAPPED -> BOOL -> IO (Maybe DWORD)
- data CompletionData = CompletionData {
- cdHandle :: !HANDLE
- cdCallback :: !(StablePtr IOCallback)
- type CompletionCallback a = ErrCode -> DWORD -> IO a
- withRequest :: Bool -> Word64 -> HANDLE -> IOCallback -> (Ptr HASKELL_OVERLAPPED -> Ptr CompletionData -> IO a) -> IO a
- data OVERLAPPED
- type LPOVERLAPPED = Ptr OVERLAPPED
- data OVERLAPPED_ENTRY = OVERLAPPED_ENTRY {
- lpCompletionKey :: ULONG_PTR
- lpOverlapped :: LPOVERLAPPED
- dwNumberOfBytesTransferred :: DWORD
- type LPOVERLAPPED_ENTRY = Ptr OVERLAPPED_ENTRY
- data HASKELL_OVERLAPPED
- type LPHASKELL_OVERLAPPED = Ptr HASKELL_OVERLAPPED
- allocOverlapped :: Word64 -> IO (Ptr HASKELL_OVERLAPPED)
- zeroOverlapped :: LPHASKELL_OVERLAPPED -> IO ()
- pokeOffsetOverlapped :: LPOVERLAPPED -> Word64 -> IO ()
- overlappedIOStatus :: LPOVERLAPPED -> IO NTSTATUS
- overlappedIONumBytes :: LPOVERLAPPED -> IO ULONG_PTR
- cancelIoEx :: HANDLE -> LPOVERLAPPED -> IO ()
- cancelIoEx' :: HANDLE -> LPOVERLAPPED -> IO Bool
- getTickCount64 :: IO Word64
- queryPerformanceCounter :: IO Int64
- queryPerformanceFrequency :: IO (Maybe Int64)
- throwWinErr :: String -> ErrCode -> IO a
- setLastError :: ErrCode -> IO ()
IOCP
An I/O completion port.
type CompletionKey = ULONG_PTR Source #
associateHandleWithIOCP :: IOCP -> HANDLE -> CompletionKey -> IO () Source #
Associate a HANDLE with an I/O completion port.
getQueuedCompletionStatusEx Source #
Note [Completion Ports] ~~~~~~~~~~~~~~~~~~~~~~~ When an I/O operation has been queued by an operation (ReadFileWriteFileetc) it is placed in a queue that the driver uses when servicing IRQs. This queue has some important properties:
- ) It is not an ordered queue. Requests may be performed out of order as as the OS's native I/O manager may try to re-order requests such that as few random seeks as possible are needed to complete the pending operations. As such do not assume a fixed order between something being queued and dequeued.
- ) Operations may skip the queue entirely. In which case they do not end in
in this function. (This is an optimization flag we have turned on. See
openFile.) - ) Across this call the specified OVERLAPPED_ENTRY buffer MUST remain live,
and the buffer for an I/O operation cannot be freed or moved until
getOverlappedResultsays it's done. The reason is the kernel may not have fully released the buffer, or finished writing to it when this operation returns. Failure to adhere to this will cause your IRQs to be silently dropped and your program will never receive a completion for it. This means that the OVERLAPPED buffer must also remain valid for the duration of the call and as such must be allocated on the unmanaged heap. - ) When a thread calls this method it is associated with the I/O manager's worker threads pool. You should always use dedicated threads for this since the OS I/O manager will now monitor the threads. If the thread becomes blocked for whatever reason, the Haskell I/O manager will wake up another threads from it's pool to service the remaining results. A new thread will also be woken up from the pool when the previous thread is busy servicing requests and new requests have finished. For this reason the Haskell IO manager multiplexes IO operations from N haskell threads into 1 completion port, which is serviced by M native threads in an asynchronous method. This allows it to scale efficiently.
postQueuedCompletionStatus :: IOCP -> DWORD -> CompletionKey -> LPOVERLAPPED -> IO () Source #
Manually post a completion to the specified I/O port. This will wake up
a thread waiting GetQueuedCompletionStatusEx.
getOverlappedResult :: HANDLE -> Ptr OVERLAPPED -> BOOL -> IO (Maybe DWORD) Source #
Get the result of a single overlap operation without the IO manager
Completion Data
data CompletionData Source #
Structure that the I/O manager uses to associate callbacks with additional payload such as their OVERLAPPED structure and Win32 handle etc. *Must* be kept in sync with that in `winio_structs.h` or horrible things happen.
We keep the handle around for the benefit of ghc-external libraries making use of the manager.
Constructors
| CompletionData | |
Fields
| |
Instances
| Storable CompletionData Source # | |
Defined in GHC.Event.Windows.FFI Methods sizeOf :: CompletionData -> Int Source # alignment :: CompletionData -> Int Source # peekElemOff :: Ptr CompletionData -> Int -> IO CompletionData Source # pokeElemOff :: Ptr CompletionData -> Int -> CompletionData -> IO () Source # peekByteOff :: Ptr b -> Int -> IO CompletionData Source # pokeByteOff :: Ptr b -> Int -> CompletionData -> IO () Source # peek :: Ptr CompletionData -> IO CompletionData Source # poke :: Ptr CompletionData -> CompletionData -> IO () Source # | |
type CompletionCallback a Source #
Called when the completion is delivered.
withRequest :: Bool -> Word64 -> HANDLE -> IOCallback -> (Ptr HASKELL_OVERLAPPED -> Ptr CompletionData -> IO a) -> IO a Source #
Overlapped
data OVERLAPPED Source #
Tag type for LPOVERLAPPED.
type LPOVERLAPPED = Ptr OVERLAPPED Source #
Identifies an I/O operation. Used as the LPOVERLAPPED parameter
for overlapped I/O functions (e.g. ReadFile, WSASend).
data OVERLAPPED_ENTRY Source #
An array of these is passed to GetQueuedCompletionStatusEx as an output argument.
Constructors
| OVERLAPPED_ENTRY | |
Fields
| |
Instances
| Storable OVERLAPPED_ENTRY Source # | |
Defined in GHC.Event.Windows.FFI Methods sizeOf :: OVERLAPPED_ENTRY -> Int Source # alignment :: OVERLAPPED_ENTRY -> Int Source # peekElemOff :: Ptr OVERLAPPED_ENTRY -> Int -> IO OVERLAPPED_ENTRY Source # pokeElemOff :: Ptr OVERLAPPED_ENTRY -> Int -> OVERLAPPED_ENTRY -> IO () Source # peekByteOff :: Ptr b -> Int -> IO OVERLAPPED_ENTRY Source # pokeByteOff :: Ptr b -> Int -> OVERLAPPED_ENTRY -> IO () Source # peek :: Ptr OVERLAPPED_ENTRY -> IO OVERLAPPED_ENTRY Source # poke :: Ptr OVERLAPPED_ENTRY -> OVERLAPPED_ENTRY -> IO () Source # | |
type LPOVERLAPPED_ENTRY = Ptr OVERLAPPED_ENTRY Source #
data HASKELL_OVERLAPPED Source #
Tag type for the extended version of OVERLAPPED containing some book
keeping information.
type LPHASKELL_OVERLAPPED = Ptr HASKELL_OVERLAPPED Source #
Pointer to the extended HASKELL_OVERLAPPED function.
Arguments
| :: Word64 | Offset/OffsetHigh |
| -> IO (Ptr HASKELL_OVERLAPPED) |
Allocate a new <http://msdn.microsoft.com/en-us/library/windows/desktop/ms684342%28v=vs.85%29.aspx OVERLAPPED> structure on the unmanaged heap. This also zeros the memory to prevent the values inside the struct to be incorrectly interpreted as data payload.
We extend the overlapped structure with some extra book keeping information such that we don't have to do a lookup on the Haskell side.
Future: We can gain some performance here by using a pool instead of calling malloc for each request. A simple block allocator would be very useful here, especially when we implement sockets support.
zeroOverlapped :: LPHASKELL_OVERLAPPED -> IO () Source #
Zero-fill an HASKELL_OVERLAPPED structure.
pokeOffsetOverlapped :: LPOVERLAPPED -> Word64 -> IO () Source #
Set the offset field in an OVERLAPPED structure.
overlappedIONumBytes :: LPOVERLAPPED -> IO ULONG_PTR Source #
Cancel pending I/O
cancelIoEx :: HANDLE -> LPOVERLAPPED -> IO () Source #
Cancel all pending overlapped I/O for the given file that was initiated by
the current OS thread. Cancelling is just a request for cancellation and
before the OVERLAPPED struct is freed we must make sure that the IRQ has been
removed from the queue. See getOverlappedResult.
cancelIoEx' :: HANDLE -> LPOVERLAPPED -> IO Bool Source #
Monotonic time
GetTickCount
getTickCount64 :: IO Word64 Source #
Call the GetTickCount64 function, which returns a monotonic time in
milliseconds.
Problems:
- Low resolution (10 to 16 milliseconds).
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724408%28v=vs.85%29.aspx
QueryPerformanceCounter
queryPerformanceCounter :: IO Int64 Source #
Call the QueryPerformanceCounter function.
Problems:
- Might not be available on some hardware. Use
queryPerformanceFrequencyto test for availability before calling this function. - On a multiprocessor computer, may produce different results on different processors due to hardware bugs.
To get a monotonic time in seconds, divide the result of
queryPerformanceCounter by that of queryPerformanceFrequency.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904%28v=vs.85%29.aspx
queryPerformanceFrequency :: IO (Maybe Int64) Source #
Call the QueryPerformanceFrequency function. Return Nothing if the
hardware does not provide a high-resolution performance counter.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644905%28v=vs.85%29.aspx
Miscellaneous
setLastError :: ErrCode -> IO () Source #