-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CancelIoEx and overal review of Win32-network #1627
Conversation
964d6ab
to
8cc6a81
Compare
affb6ea
to
3806a47
Compare
8cc6a81
to
b22cd03
Compare
3806a47
to
9c20430
Compare
b22cd03
to
e6d8867
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments so far, for first 2 patches.
e6d8867
to
14cd1ac
Compare
9c20430
to
085c24a
Compare
67fcc3f
to
935dfb3
Compare
085c24a
to
7c582b7
Compare
Closed by bors, it wasn't ment to be closed. |
935dfb3
to
cf8290a
Compare
For Win32 >=2.7 import it directly.
Allocation and deallocation of 'IOData' associated with each async requests is done in Haskell. We use `System.Win32` api to allocate / deallocate from windows process heap (as we did in C). We can now use `ReadFile` and `WriteFile` syscalls without C wrappers. We are not using the ones from `Win32` package only beacuse we support Win32<2.7 which did not defined OVERLAPPED data type. This can be changed later on. 'IOData' data type is holds 'OVERLAPPED' passed to system calls and the stable pointer. As previously, this allows 'HsGetQueuedCompletionStatus' to use 'CONTAINING_RECORD' macro to recover it just from 'OVERLAPPED' member. 'withIODataPtr' is introduced which allocats 'IOData' on process heap. It takes most of responsibilities of 'waitForCompletion' function, which has been removed. This will allow us to add a 'CacnelIoEx' call in case the async I/O was interrupted by a GHC'c async exception.
If the 'IOManger' threads throws an 'IOException' and dies, there is no point on continuing running the application (any I/O would deadlock). The 'IOException' most likely signifies a bug in 'dequeueCompletionPackets'. The IOException is warpped in a newtype wrapper: 'IOManagerError'. This is all done to make it easier to debug (and test) problems that may arrise in the 'IOManager' thread.
If a thread which is blocked on reading or writing is cancelled with an 'AsyncException' use 'CancelIoEx' to cancel the IO action. When 'CancelIoEx' is used the 'IOManager' thread is notified and it will deallocate 'ioDataPtr' which was allocated on process heap. In such a case 'GetQueuedCompletionStatus' returns 'False' and sets 'ERROR_OPERATION_ABORTED' error.
- Add some haddocs to ErrCode - Fixed haddocs in 'connectnamedPipe'
Trigger conditions mentioned in MSDN `connectNamedPipe` doc https://docs.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-connectnamedpipe#remarks - ERROR_PIPE_CONNECTED - done - ERROR_NO_DATA - done - ERROR_PIPE_LISTENING - failed
* 'ERROR_INVALID_HANDLE' * 'ERROR_BROKEN_PIPE'
It takes ~20s - not good, but we can afford that.
WSAOVERLAPPED is used in winsock2 inplace of OVERLAPPED.
This is a perparatory work to support winsock2 io. Winsock2 is using WSAOVERLAPPED pointer unlike the rest of windows which is using OVERLAPPED. This patch provides type level distintion and various safe pointer casts. GADTs ensure that one will use the right overlapped struct / error codes (e.g. 'getLastError' vs 'wsaGetLastError') and sockets ('HANDLE' vs 'SOCKET'). Types also enforce that the `dequeueCompletionPackets` (IOManager thread) when dereferencing the shared stable pointer it will use the same type as the function that executes the async IO (e.g. 'readHandle', etc.). This is done by limiting unecessary polymorphism. Interestingly one can use 'DerivingVia' (combined with 'StandaloneDeriving') to derive instances for GADTs (see 'Overlapped' 'Storable' instances in 'System.Win32.Async.IOData').
This PR removes Win32Socket.c source file. We can just use the winsock2 functions through ffi directly without any C level wrappers.
742b3be
to
71f6279
Compare
* Excluding Win32-network library, PR #1627 fixes that.
* Excluding Win32-network library, PR #1627 fixes that.
2cdb19a
to
4fdac57
Compare
This unitest (or experiment) checks how the `dequeueCompletionPackets` (IOMananger thread) behaves when closing a handle which is blocked on reading data. This either raises 'ResourceVanished` or `InvalidArgument` io exception in the thread that initiated the operation, but most importantly there is no exception in the IOManager thread.
The only safe call in Win32-network is 'GetQueuedCompletionStatus': it is the only blocking call; For that reason the library should be used with `-threaded` option, though this is not enforced in the `cabal` file.
4fdac57
to
ec390db
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking very good. It is a lot simpler than before. Not too many remaining comments.
I see I had a pending stale review, so some of my early comments may be a bit out of date. If so, ignore them.
poke bufsPtr WSABuf {buf, len = fromIntegral size} | ||
sendResult <- c_WSASend fd bufsPtr 1 nullPtr 0 lpOverlapped nullPtr | ||
errorCode <- wsaGetLastError | ||
if sendResult == 0 || errorCode == wSA_IO_PENDING |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same Q as elsehwhere about whether this is the simplest condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe so. Tracing these values prints two cases (the first one is sendResult
the other one is errorCode
- 997
, except being the police telephone number in Poland :D, is WSA_IO_PENDING
) :
recvBuf -1, 997
recvBuf -1, 997
recvBuf -1, 997
recvBuf -1, 997
recvBuf 0, 0
recvBuf 0, 0
recvBuf -1, 997
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ this output was generated for recvBuf
rather than sendBuf
; for sendBuf
it's similar (just 0, 0
is much more common):
sendBuf 0, 0
sendBuf 0, 0
sendBuf 0, 0
sendBuf 0, 0
sendBuf 0, 0
sendBuf -1, 997
sendBuf 0, 0
sendBuf 0, 0
sendBuf 0, 0
sendBuf 0, 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok but in these examples the result being zero or non-zero always agrees with the error code. So we would be able to base our condition on either of them rather than both.
This is not a blocker, and I suggest we merge without addressing this now, but it certainly looks odd and we could clean this up later. File a low priority ticket.
* use intPtrToPtr * provide castOverlappedPtr - and document why it works
It is important that it is a tail recursive function. The analysis of results must be done inside `alloca` since as the result of this analysis we either can or cannot accesses `numberOfBytesPtr` (allocated by `alloca`).
Removed that the winio license applies to * ./cbits/Win32Async.c * ./src/System/Win32/Async.hs cbits were removed, and Async.hs file heavily rewritten.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes since last review looks great. Did we address everything? If so lets merge.
bors r+ |
1627: CancelIoEx and overal review of Win32-network r=coot a=coot The primary goal of this PR was to add `CancelIoEx` to fix #1574. In doing so I changed the interface and the end result is that: * we don't use C type level wrappers for windows syscalls any more (apart from `GetQueuedCompletionStatus` where we need to use a windwo kernel C macro. * using `GADTs` to ensure that we use the right combination of `OVERLAPPED` / `WSAOVERLAPPED`, `HANDLE` / `SOCKET` and `ErrCode` / `WsaErrCode`. * there is a closed type family which ensures that some of the `castPtr` usage is actually safe, it is not exposed. It could be removed, but then using `castPtr` would leak out to various modules - so I preferred the more elegant and local, though type havier approach. * more tests, especially for error conditions in which we need to assure that we are not deallocating the stable pointer twice 💣 This PR is done on top of `coot/windows-vectored-io` (and it merges into that branch) - this makes the scope of this PR adequate for the proposed changes. For the moment the windows stuff is stacked on CI, but when devops will help with it I will be able to merge all the PRs in turn. 1840: Update dependency on cardano-ledger-specs r=mrBliss a=mrBliss Co-authored-by: Marcin Szamotulski <[email protected]> Co-authored-by: Thomas Winant <[email protected]>
Build failed (retrying...) |
bors: merge |
Already running a review |
* Excluding Win32-network library, PR #1627 fixes that.
The primary goal of this PR was to add
CancelIoEx
to fix #1574. In doing so I changed the interface and the end result is that:GetQueuedCompletionStatus
where we need to use a windwo kernel C macro.GADTs
to ensure that we use the right combination ofOVERLAPPED
/WSAOVERLAPPED
,HANDLE
/SOCKET
andErrCode
/WsaErrCode
.castPtr
usage is actually safe, it is not exposed. It could be removed, but then usingcastPtr
would leak out to various modules - so I preferred the more elegant and local, though type havier approach.This PR is done on top of
coot/windows-vectored-io
(and it merges into that branch) - this makes the scope of this PR adequate for the proposed changes. For the moment the windows stuff is stacked on CI, but when devops will help with it I will be able to merge all the PRs in turn.