* Note: iocp write completion is not "bytes on the wire", it is "peer * acked the sent bytes". Completion can be seconds on a slow * consuming peer. */
| 987 | * consuming peer. |
| 988 | */ |
| 989 | void complete_write(write_result_t *result, DWORD xfer_count, HRESULT status) |
| 990 | { |
| 991 | iocpdesc_t *iocpd = result->base.iocpd; |
| 992 | if (iocpd->closing) { |
| 993 | pni_write_pipeline_return(iocpd->pipeline, result); |
| 994 | if (!iocpd->write_closed && !write_in_progress(iocpd)) |
| 995 | iocp_shutdown(iocpd); |
| 996 | reap_check(iocpd); |
| 997 | return; |
| 998 | } |
| 999 | if (status == 0 && xfer_count > 0) { |
| 1000 | if (xfer_count != result->requested) { |
| 1001 | // Is this recoverable? How to preserve order if multiple overlapped writes? |
| 1002 | pni_write_pipeline_return(iocpd->pipeline, result); |
| 1003 | iocpdesc_fail(iocpd, WSA_OPERATION_ABORTED, "Partial overlapped write on socket"); |
| 1004 | return; |
| 1005 | } else { |
| 1006 | // Success. |
| 1007 | pni_write_pipeline_return(iocpd->pipeline, result); |
| 1008 | if (pni_write_pipeline_writable(iocpd->pipeline)) |
| 1009 | pni_events_update(iocpd, iocpd->events | PN_WRITABLE); |
| 1010 | return; |
| 1011 | } |
| 1012 | } |
| 1013 | // Other error |
| 1014 | pni_write_pipeline_return(iocpd->pipeline, result); |
| 1015 | if (status == WSAECONNABORTED || status == WSAECONNRESET || status == WSAENOTCONN |
| 1016 | || status == ERROR_NETNAME_DELETED) { |
| 1017 | iocpd->write_closed = true; |
| 1018 | iocpd->poll_error = true; |
| 1019 | pni_events_update(iocpd, iocpd->events & ~PN_WRITABLE); |
| 1020 | pni_win32_error(iocpd->error, "Remote close or timeout", status); |
| 1021 | } else { |
| 1022 | iocpdesc_fail(iocpd, status, "IOCP async write error"); |
| 1023 | } |
| 1024 | } |
| 1025 | |
| 1026 | |
| 1027 | // === Async reads |
no test coverage detected