Ejemplo n.º 1
0
static void iocpdesc_fail(iocpdesc_t *iocpd, HRESULT status, const char* text)
{
  pni_win32_error(iocpd->error, text, status);
  if (iocpd->iocp->iocp_trace) {
    iocp_log("connection terminated: %s\n", pn_error_text(iocpd->error));
  }
  if (!is_listener(iocpd) && !iocpd->write_closed && !pni_write_pipeline_size(iocpd->pipeline))
    iocp_shutdown(iocpd);
  iocpd->write_closed = true;
  iocpd->read_closed = true;
  iocpd->poll_error = true;
  pni_events_update(iocpd, iocpd->events & ~(PN_READABLE | PN_WRITABLE));
}
Ejemplo n.º 2
0
/*
 * 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.
 */
static void complete_write(write_result_t *result, DWORD xfer_count, HRESULT status)
{
  iocpdesc_t *iocpd = result->base.iocpd;
  if (iocpd->closing) {
    pni_write_pipeline_return(iocpd->pipeline, result);
    if (!iocpd->write_closed && !write_in_progress(iocpd))
      iocp_shutdown(iocpd);
    reap_check(iocpd);
    return;
  }
  if (status == 0 && xfer_count > 0) {
    if (xfer_count != result->requested) {
      // Is this recoverable?  How to preserve order if multiple overlapped writes?
      pni_write_pipeline_return(iocpd->pipeline, result);
      iocpdesc_fail(iocpd, WSA_OPERATION_ABORTED, "Partial overlapped write on socket");
      return;
    } else {
      // Success.
      pni_write_pipeline_return(iocpd->pipeline, result);
      if (pni_write_pipeline_writable(iocpd->pipeline))
        pni_events_update(iocpd, iocpd->events | PN_WRITABLE);
      return;
    }
  }
  // Other error
  pni_write_pipeline_return(iocpd->pipeline, result);
  if (status == WSAECONNABORTED || status == WSAECONNRESET || status == WSAENOTCONN
      || status == ERROR_NETNAME_DELETED) {
    iocpd->write_closed = true;
    iocpd->poll_error = true;
    pni_events_update(iocpd, iocpd->events & ~PN_WRITABLE);
    pni_win32_error(iocpd->error, "Remote close or timeout", status);
  } else {
    iocpdesc_fail(iocpd, status, "IOCP async write error");
  }
}
Ejemplo n.º 3
0
void pni_iocp_begin_close(iocpdesc_t *iocpd)
{
  assert (!iocpd->closing);
  if (is_listener(iocpd)) {
    // Listening socket is easy.  Close the socket which will cancel async ops.
    pn_socket_t old_sock = iocpd->socket;
    iocpd->socket = INVALID_SOCKET;
    iocpd->closing = true;
    iocpd->read_closed = true;
    iocpd->write_closed = true;
    closesocket(old_sock);
    // Pending accepts will now complete.  Zombie can die when all consumed.
    zombie_list_add(iocpd);
    pni_iocpdesc_map_del(iocpd->iocp, old_sock);  // may pn_free *iocpd
  } else {
    // Continue async operation looking for graceful close confirmation or timeout.
    pn_socket_t old_sock = iocpd->socket;
    iocpd->closing = true;
    if (!iocpd->write_closed && !write_in_progress(iocpd))
      iocp_shutdown(iocpd);
    zombie_list_add(iocpd);
    pni_iocpdesc_map_del(iocpd->iocp, old_sock);  // may pn_free *iocpd
  }
}