src/os/win32/ngx_wsasend.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_wsasend(ngx_connection_t *c, u_char *buf, size_t size)
  10. {
  11.     int           n;
  12.     u_long        sent;
  13.     ngx_err_t     err;
  14.     ngx_event_t  *wev;
  15.     WSABUF        wsabuf;

  16.     wev = c->write;

  17.     if (!wev->ready) {
  18.         return NGX_AGAIN;
  19.     }

  20.     /*
  21.      * WSABUF must be 4-byte aligned otherwise
  22.      * WSASend() will return undocumented WSAEINVAL error.
  23.      */

  24.     wsabuf.buf = (char *) buf;
  25.     wsabuf.len = size;

  26.     sent = 0;

  27.     n = WSASend(c->fd, &wsabuf, 1, &sent, 0, NULL, NULL);

  28.     ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
  29.                    "WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size);

  30.     if (n == 0) {
  31.         if (sent < size) {
  32.             wev->ready = 0;
  33.         }

  34.         c->sent += sent;

  35.         return sent;
  36.     }

  37.     err = ngx_socket_errno;

  38.     if (err == WSAEWOULDBLOCK) {
  39.         ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, "WSASend() not ready");
  40.         wev->ready = 0;
  41.         return NGX_AGAIN;
  42.     }

  43.     wev->error = 1;
  44.     ngx_connection_error(c, err, "WSASend() failed");

  45.     return NGX_ERROR;
  46. }


  47. ssize_t
  48. ngx_overlapped_wsasend(ngx_connection_t *c, u_char *buf, size_t size)
  49. {
  50.     int               n;
  51.     u_long            sent;
  52.     ngx_err_t         err;
  53.     ngx_event_t      *wev;
  54.     LPWSAOVERLAPPED   ovlp;
  55.     WSABUF            wsabuf;

  56.     wev = c->write;

  57.     if (!wev->ready) {
  58.         return NGX_AGAIN;
  59.     }

  60.     ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  61.                    "wev->complete: %d", wev->complete);

  62.     if (!wev->complete) {

  63.         /* post the overlapped WSASend() */

  64.         /*
  65.          * WSABUFs must be 4-byte aligned otherwise
  66.          * WSASend() will return undocumented WSAEINVAL error.
  67.          */

  68.         wsabuf.buf = (char *) buf;
  69.         wsabuf.len = size;

  70.         sent = 0;

  71.         ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
  72.         ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));

  73.         n = WSASend(c->fd, &wsabuf, 1, &sent, 0, ovlp, NULL);

  74.         ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
  75.                        "WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size);

  76.         wev->complete = 0;

  77.         if (n == 0) {
  78.             if (ngx_event_flags & NGX_USE_IOCP_EVENT) {

  79.                 /*
  80.                  * if a socket was bound with I/O completion port then
  81.                  * GetQueuedCompletionStatus() would anyway return its status
  82.                  * despite that WSASend() was already complete
  83.                  */

  84.                 wev->active = 1;
  85.                 return NGX_AGAIN;
  86.             }

  87.             if (sent < size) {
  88.                 wev->ready = 0;
  89.             }

  90.             c->sent += sent;

  91.             return sent;
  92.         }

  93.         err = ngx_socket_errno;

  94.         if (err == WSA_IO_PENDING) {
  95.             ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
  96.                            "WSASend() posted");
  97.             wev->active = 1;
  98.             return NGX_AGAIN;
  99.         }

  100.         wev->error = 1;
  101.         ngx_connection_error(c, err, "WSASend() failed");

  102.         return NGX_ERROR;
  103.     }

  104.     /* the overlapped WSASend() complete */

  105.     wev->complete = 0;
  106.     wev->active = 0;

  107.     if (ngx_event_flags & NGX_USE_IOCP_EVENT) {

  108.         if (wev->ovlp.error) {
  109.             ngx_connection_error(c, wev->ovlp.error, "WSASend() failed");
  110.             return NGX_ERROR;
  111.         }

  112.         sent = wev->available;

  113.     } else {
  114.         if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp,
  115.                                    &sent, 0, NULL)
  116.             == 0)
  117.         {
  118.             ngx_connection_error(c, ngx_socket_errno,
  119.                            "WSASend() or WSAGetOverlappedResult() failed");

  120.             return NGX_ERROR;
  121.         }
  122.     }

  123.     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
  124.                    "WSAGetOverlappedResult: fd:%d, %ul of %uz",
  125.                    c->fd, sent, size);

  126.     if (sent < size) {
  127.         wev->ready = 0;
  128.     }

  129.     c->sent += sent;

  130.     return sent;
  131. }