diff src/os/win32/ngx_wsarecv_chain.c @ 186:c1f3a3c7c5db

nginx-0.0.1-2003-11-17-00:49:42 import
author Igor Sysoev <igor@sysoev.ru>
date Sun, 16 Nov 2003 21:49:42 +0000
parents
children 0ba4821f4460
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/os/win32/ngx_wsarecv_chain.c
@@ -0,0 +1,72 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ssize_t ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain)
+{
+    int           rc;
+    char         *prev;
+    u_int         flags;
+    size_t        bytes, size;
+    WSABUF       *wsabuf;
+    ngx_err_t     err;
+    ngx_array_t   io;
+    ngx_event_t  *rev;
+
+    prev = NULL;
+    wsabuf = NULL;
+    flags = 0;
+    size = 0;
+    bytes = 0;
+
+    ngx_init_array(io, c->pool, 10, sizeof(WSABUF), NGX_ERROR);
+
+    /* coalesce the neighbouring hunks */
+
+    while (chain) {
+        if (prev == chain->hunk->last) {
+            wsabuf->len += chain->hunk->end - chain->hunk->last;
+
+        } else {
+            ngx_test_null(wsabuf, ngx_push_array(&io), NGX_ERROR);
+            wsabuf->buf = chain->hunk->last;
+            wsabuf->len = chain->hunk->end - chain->hunk->last;
+        }
+
+        size += chain->hunk->end - chain->hunk->last;
+        prev = chain->hunk->end;
+        chain = chain->next;
+    }
+
+ngx_log_debug(c->log, "WSARecv: %d:%d" _ io.nelts _ wsabuf->len);
+
+    rc = WSARecv(c->fd, io.elts, io.nelts, &bytes, &flags, NULL, NULL);
+
+    rev = c->read;
+
+    if (rc == -1) {
+        rev->ready = 0;
+        err = ngx_socket_errno;
+
+        if (err == WSAEWOULDBLOCK) {
+            ngx_log_error(NGX_LOG_INFO, c->log, err, "WSARecv() EAGAIN");
+            return NGX_AGAIN;
+        }
+
+        rev->error = 1;
+        ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSARecv() failed");
+        return NGX_ERROR;
+    }
+
+    if (bytes < size) {
+        rev->ready = 0;
+    }
+
+    if (bytes == 0) {
+        rev->eof = 1;
+    }
+
+    return bytes;
+}