src/os/win32/ngx_udp_wsarecv.c - nginx source code

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_event.h>


  8. ssize_t
  9. ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
  10. {
  11.     int           rc;
  12.     u_long        bytes, flags;
  13.     WSABUF        wsabuf[1];
  14.     ngx_err_t     err;
  15.     ngx_event_t  *rev;

  16.     wsabuf[0].buf = (char *) buf;
  17.     wsabuf[0].len = size;
  18.     flags = 0;
  19.     bytes = 0;

  20.     rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL);

  21.     ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
  22.                    "WSARecv: fd:%d rc:%d %ul of %z", c->fd, rc, bytes, size);

  23.     rev = c->read;

  24.     if (rc == -1) {
  25.         rev->ready = 0;
  26.         err = ngx_socket_errno;

  27.         if (err == WSAEWOULDBLOCK) {
  28.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
  29.                            "WSARecv() not ready");
  30.             return NGX_AGAIN;
  31.         }

  32.         rev->error = 1;
  33.         ngx_connection_error(c, err, "WSARecv() failed");

  34.         return NGX_ERROR;
  35.     }

  36.     return bytes;
  37. }


  38. ssize_t
  39. ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
  40. {
  41.     int               rc;
  42.     u_long            bytes, flags;
  43.     WSABUF            wsabuf[1];
  44.     ngx_err_t         err;
  45.     ngx_event_t      *rev;
  46.     LPWSAOVERLAPPED   ovlp;

  47.     rev = c->read;

  48.     if (!rev->ready) {
  49.         ngx_log_error(NGX_LOG_ALERT, c->log, 0, "second wsa post");
  50.         return NGX_AGAIN;
  51.     }

  52.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  53.                    "rev->complete: %d", rev->complete);

  54.     if (rev->complete) {
  55.         rev->complete = 0;

  56.         if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
  57.             if (rev->ovlp.error) {
  58.                 ngx_connection_error(c, rev->ovlp.error, "WSARecv() failed");
  59.                 return NGX_ERROR;
  60.             }

  61.             ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  62.                            "WSARecv ovlp: fd:%d %ul of %z",
  63.                            c->fd, rev->available, size);

  64.             return rev->available;
  65.         }

  66.         if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
  67.                                    &bytes, 0, NULL)
  68.             == 0)
  69.         {
  70.             ngx_connection_error(c, ngx_socket_errno,
  71.                                "WSARecv() or WSAGetOverlappedResult() failed");
  72.             return NGX_ERROR;
  73.         }

  74.         ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  75.                        "WSARecv: fd:%d %ul of %z", c->fd, bytes, size);

  76.         return bytes;
  77.     }

  78.     ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
  79.     ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
  80.     wsabuf[0].buf = (char *) buf;
  81.     wsabuf[0].len = size;
  82.     flags = 0;
  83.     bytes = 0;

  84.     rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);

  85.     rev->complete = 0;

  86.     ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
  87.                    "WSARecv ovlp: fd:%d rc:%d %ul of %z",
  88.                    c->fd, rc, bytes, size);

  89.     if (rc == -1) {
  90.         err = ngx_socket_errno;
  91.         if (err == WSA_IO_PENDING) {
  92.             rev->active = 1;
  93.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
  94.                            "WSARecv() posted");
  95.             return NGX_AGAIN;
  96.         }

  97.         rev->error = 1;
  98.         ngx_connection_error(c, err, "WSARecv() failed");
  99.         return NGX_ERROR;
  100.     }

  101.     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {

  102.         /*
  103.          * if a socket was bound with I/O completion port
  104.          * then GetQueuedCompletionStatus() would anyway return its status
  105.          * despite that WSARecv() was already complete
  106.          */

  107.         rev->active = 1;
  108.         return NGX_AGAIN;
  109.     }

  110.     rev->active = 0;

  111.     return bytes;
  112. }