aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-11-14 07:20:34 +0000
committerIgor Sysoev <igor@sysoev.ru>2003-11-14 07:20:34 +0000
commit7f9d894e1069306f7361201a77efbe7b866024ff (patch)
tree9779ce5dd7d38af4c8039047768cedc92c31ec1f /src
parent45890ea8c13a561fe3fd66bf639ad429f3c18846 (diff)
downloadnginx-7f9d894e1069306f7361201a77efbe7b866024ff.tar.gz
nginx-7f9d894e1069306f7361201a77efbe7b866024ff.zip
nginx-0.0.1-2003-11-14-10:20:34 import
Diffstat (limited to 'src')
-rw-r--r--src/event/modules/ngx_iocp_module.c10
-rw-r--r--src/http/ngx_http_cache.c4
-rw-r--r--src/os/unix/ngx_aio_read.c16
-rw-r--r--src/os/unix/ngx_files.h2
-rw-r--r--src/os/unix/ngx_os.h2
-rw-r--r--src/os/unix/ngx_recv.c14
-rw-r--r--src/os/unix/ngx_unix_init.c4
-rw-r--r--src/os/unix/ngx_writev_chain.c15
-rw-r--r--src/os/win32/ngx_files.c123
-rw-r--r--src/os/win32/ngx_files.h3
-rw-r--r--src/os/win32/ngx_os.h7
-rw-r--r--src/os/win32/ngx_os_init.h14
-rw-r--r--src/os/win32/ngx_recv.c93
-rw-r--r--src/os/win32/ngx_win32_init.c5
-rw-r--r--src/os/win32/ngx_wsarecv.c145
-rw-r--r--src/os/win32/ngx_wsasend_chain.c247
16 files changed, 534 insertions, 170 deletions
diff --git a/src/event/modules/ngx_iocp_module.c b/src/event/modules/ngx_iocp_module.c
index 0fc7a7153..7b89227a3 100644
--- a/src/event/modules/ngx_iocp_module.c
+++ b/src/event/modules/ngx_iocp_module.c
@@ -77,6 +77,15 @@ ngx_module_t ngx_iocp_module = {
};
+ngx_os_io_t ngx_iocp_io = {
+ ngx_overlapped_wsarecv,
+ NULL,
+ NULL,
+ ngx_wsasend_chain,
+ 0
+};
+
+
static HANDLE iocp;
@@ -225,6 +234,7 @@ ngx_log_debug(log, "iocp ev: %08x" _ ev);
switch (key) {
case NGX_IOCP_IO:
+ ev->complete = 1;
ev->ready = 1;
break;
diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c
index 299455ba3..6e64af140 100644
--- a/src/http/ngx_http_cache.c
+++ b/src/http/ngx_http_cache.c
@@ -140,9 +140,7 @@ int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
retry = 0;
for ( ;; ) {
- if (ngx_rename_file(temp_file->data, ctx->file.name.data)
- != NGX_FILE_ERROR)
- {
+ if (ngx_rename_file(temp_file, (&ctx->file.name), r->pool) == NGX_OK) {
return NGX_OK;
}
diff --git a/src/os/unix/ngx_aio_read.c b/src/os/unix/ngx_aio_read.c
index 28deac6d2..c5fb4a55f 100644
--- a/src/os/unix/ngx_aio_read.c
+++ b/src/os/unix/ngx_aio_read.c
@@ -25,12 +25,12 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
rev = c->read;
if (!rev->ready) {
- ngx_log_error(NGX_LOG_ALERT, rev->log, 0, "SECOND AIO POST");
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0, "SECOND AIO POST");
return NGX_AGAIN;
}
- ngx_log_debug(rev->log, "rev->complete: %d" _ rev->complete);
- ngx_log_debug(rev->log, "aio size: %d" _ size);
+ ngx_log_debug(c->log, "rev->complete: %d" _ rev->complete);
+ ngx_log_debug(c->log, "aio size: %d" _ size);
if (!rev->complete) {
ngx_memzero(&rev->aiocb, sizeof(struct aiocb));
@@ -52,7 +52,7 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
return NGX_ERROR;
}
- ngx_log_debug(rev->log, "aio_read: #%d OK" _ c->fd);
+ ngx_log_debug(c->log, "aio_read: #%d OK" _ c->fd);
rev->active = 1;
rev->ready = 0;
@@ -62,7 +62,7 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
n = aio_error(&rev->aiocb);
if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, rev->log, ngx_errno, "aio_error() failed");
+ ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "aio_error() failed");
rev->error = 1;
return NGX_ERROR;
}
@@ -70,14 +70,14 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
if (n != 0) {
if (n == NGX_EINPROGRESS) {
if (rev->ready) {
- ngx_log_error(NGX_LOG_ALERT, rev->log, n,
+ ngx_log_error(NGX_LOG_ALERT, c->log, n,
"aio_read() still in progress");
rev->ready = 0;
}
return NGX_AGAIN;
}
- ngx_log_error(NGX_LOG_CRIT, rev->log, n, "aio_read() failed");
+ ngx_log_error(NGX_LOG_CRIT, c->log, n, "aio_read() failed");
rev->error = 1;
rev->ready = 0;
return NGX_ERROR;
@@ -85,7 +85,7 @@ ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
n = aio_return(&rev->aiocb);
if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, rev->log, ngx_errno,
+ ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"aio_return() failed");
rev->error = 1;
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 9990ae8c3..369c3ad5d 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -45,7 +45,7 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
off_t offset, ngx_pool_t *pool);
-#define ngx_rename_file rename
+#define ngx_rename_file(from, to, pool) rename(from->data, to->data)
#define ngx_rename_file_n "rename"
diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h
index 33e394319..658c0a400 100644
--- a/src/os/unix/ngx_os.h
+++ b/src/os/unix/ngx_os.h
@@ -35,6 +35,8 @@ typedef struct {
int ngx_os_init(ngx_log_t *log);
int ngx_daemon(ngx_log_t *log);
int ngx_posix_init(ngx_log_t *log);
+int ngx_posix_post_conf_init(ngx_log_t *log);
+
ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c
index 1a14fd963..e75937957 100644
--- a/src/os/unix/ngx_recv.c
+++ b/src/os/unix/ngx_recv.c
@@ -40,6 +40,8 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
}
do {
+ rev->ready = 1;
+
n = recv(c->fd, buf, size, 0);
ngx_log_debug(c->log, "recv: %d:%d" _ n _ size);
@@ -78,11 +80,14 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
}
rev->ready = 0;
- rev->error = 1;
n = ngx_unix_recv_error(rev, ngx_socket_errno);
} while (n == NGX_EINTR);
+ if (n == NGX_ERROR){
+ rev->error = 1;
+ }
+
return n;
}
@@ -96,6 +101,8 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
rev = c->read;
do {
+ rev->ready = 1;
+
n = recv(c->fd, buf, size, 0);
ngx_log_debug(c->log, "recv: %d:%d" _ n _ size);
@@ -113,11 +120,14 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
}
rev->ready = 0;
- rev->error = 1;
n = ngx_unix_recv_error(rev, ngx_socket_errno);
} while (n == NGX_EINTR);
+ if (n == NGX_ERROR){
+ rev->error = 1;
+ }
+
return n;
}
diff --git a/src/os/unix/ngx_unix_init.c b/src/os/unix/ngx_unix_init.c
index 95741642b..ab33979ec 100644
--- a/src/os/unix/ngx_unix_init.c
+++ b/src/os/unix/ngx_unix_init.c
@@ -3,17 +3,19 @@
#include <ngx_core.h>
+#if 0
/* STUB */
ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in);
int ngx_posix_init(ngx_log_t *log);
int ngx_posix_post_conf_init(ngx_log_t *log);
/* */
+#endif
ngx_os_io_t ngx_os_io = {
ngx_unix_recv,
- NULL,
+ ngx_readv_chain,
NULL,
ngx_writev_chain,
NGX_HAVE_ZEROCOPY
diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c
index 6ead65f3a..9b9e62939 100644
--- a/src/os/unix/ngx_writev_chain.c
+++ b/src/os/unix/ngx_writev_chain.c
@@ -24,6 +24,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
iov = NULL;
/* create the iovec and coalesce the neighbouring hunks */
+
for (cl = in; cl; cl = cl->next) {
if (prev == cl->hunk->pos) {
@@ -57,7 +58,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
sent = n > 0 ? n : 0;
#if (NGX_DEBUG_WRITE_CHAIN)
- ngx_log_debug(c->log, "writev: %qd" _ sent);
+ ngx_log_debug(c->log, "writev: " OFF_FMT _ sent);
#endif
c->sent += sent;
@@ -75,12 +76,6 @@ ngx_log_debug(c->log, "SIZE: %d" _ size);
cl->hunk->pos = cl->hunk->last;
}
-#if 0
- if (cl->hunk->type & NGX_HUNK_FILE) {
- cl->hunk->file_pos = cl->hunk->file_last;
- }
-#endif
-
continue;
}
@@ -88,12 +83,6 @@ ngx_log_debug(c->log, "SIZE: %d" _ size);
cl->hunk->pos += sent;
}
-#if 0
- if (cl->hunk->type & NGX_HUNK_FILE) {
- cl->hunk->file_pos += sent;
- }
-#endif
-
break;
}
diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c
index 139d141cb..35e83bfd6 100644
--- a/src/os/win32/ngx_files.c
+++ b/src/os/win32/ngx_files.c
@@ -6,13 +6,11 @@
ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
{
size_t n;
+ long high_offset;
+ ngx_err_t err;
OVERLAPPED ovlp, *povlp;
-#if (WIN9X)
-
if (ngx_win32_version < NGX_WIN_NT) {
- long high_offset;
- ngx_err_t err;
/*
* in Win9X the overlapped pointer must be NULL
@@ -47,8 +45,6 @@ ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
povlp = NULL;
} else {
-
-#endif
ovlp.Internal = 0;
ovlp.InternalHigh = 0;
ovlp.Offset = (DWORD) offset;
@@ -56,10 +52,7 @@ ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
ovlp.hEvent = NULL;
povlp = &ovlp;
-
-#if (WIN9X)
}
-#endif
if (ReadFile(file->fd, buf, size, &n, povlp) == 0) {
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "ReadFile() failed");
@@ -75,13 +68,11 @@ ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
{
size_t n;
+ long high_offset;
+ ngx_err_t err;
OVERLAPPED ovlp, *povlp;
-#if (WIN9X)
-
if (ngx_win32_version < NGX_WIN_NT) {
- long high_offset;
- ngx_err_t err;
/*
* in Win9X the overlapped pointer must be NULL
@@ -116,9 +107,6 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
povlp = NULL;
} else {
-
-#endif
-
ovlp.Internal = 0;
ovlp.InternalHigh = 0;
ovlp.Offset = (DWORD) offset;
@@ -126,10 +114,7 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
ovlp.hEvent = NULL;
povlp = &ovlp;
-
-#if (WIN9X)
}
-#endif
if (WriteFile(file->fd, buf, size, &n, povlp) == 0) {
ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "WriteFile() failed");
@@ -142,15 +127,103 @@ ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
}
-int ngx_file_append_mode(ngx_fd_t fd)
+ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
+ off_t offset, ngx_pool_t *pool)
{
- ngx_err_t err;
+ char *buf, *prev;
+ size_t size;
+ ssize_t total, n;
+
+ total = 0;
+
+ while (cl) {
+ buf = cl->hunk->pos;
+ prev = buf;
+ size = 0;
+
+ /* coalesce the neighbouring hunks */
+
+ while (cl && prev == cl->hunk->pos) {
+ size += cl->hunk->last - cl->hunk->pos;
+ prev = cl->hunk->last;
+ cl = cl->next;
+ }
+
+ n = ngx_write_file(file, buf, size, offset);
+
+ if (n == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ total += n;
+ offset += n;
+ }
+
+ return total;
+}
+
+
+int ngx_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool)
+{
+ int rc, collision;
+ u_int num;
+ char *name;
+ ngx_err_t err;
+
+ name = ngx_palloc(pool, to->len + 1 + 10 + 1 + sizeof("DELETE"));
+ ngx_memcpy(name, to->data, to->len);
+ collision = 0;
+
+ /* mutex_lock() (per cache or single ?) */
+
+ do {
+ num = ngx_next_temp_number(collision);
+
+ ngx_snprintf(name + to->len, 1 + 10 + 1 + sizeof("DELETE"),
+ ".%010u.DELETE", num);
+
+ if (MoveFile(to->data, name) == 0) {
+ err = ngx_errno;
+ if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
+ return NGX_ERROR;
+ }
+
+ collision = 1;
+ ngx_log_error(NGX_LOG_ERR, pool->log, ngx_errno,
+ "MoveFile() failed");
+ }
+
+ } while (collision);
+
+ if (ngx_win32_version >= NGX_WIN_NT) {
+ if (DeleteFile(name) == 0) {
+ ngx_log_error(NGX_LOG_ERR, pool->log, ngx_errno,
+ "DeleteFile() failed");
+ }
+ }
+
+ if (MoveFile(from->data, to->data) == 0) {
+ rc = NGX_ERROR;
+
+ } else {
+ rc = NGX_OK;
+ }
+
+ if (rc == NGX_ERROR) {
+ ngx_log_error(NGX_LOG_ERR, pool->log, ngx_errno, "MoveFile() failed");
+ }
+
+ /* mutex_unlock() */
+
+ return rc;
+}
+
+
+int ngx_file_append_mode(ngx_fd_t fd)
+{
if (SetFilePointer(fd, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) {
- err = ngx_errno;
- if (err != NO_ERROR) {
- ngx_log_error(NGX_LOG_ERR, file->log, err,
- "SeekFilePointer() failed");
+ if (ngx_errno != NO_ERROR) {
return NGX_ERROR;
}
}
diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h
index 8e386e8ca..9885c5f78 100644
--- a/src/os/win32/ngx_files.h
+++ b/src/os/win32/ngx_files.h
@@ -58,8 +58,7 @@ int ngx_file_append_mode(ngx_fd_t fd);
#define ngx_close_file CloseHandle
#define ngx_close_file_n "CloseHandle()"
-/* STUB */
-#define ngx_rename_file MoveFile
+int ngx_rename_file(ngx_str_t *from, ngx_str_t *to, ngx_pool_t *pool);
#define ngx_rename_file_n "MoveFile()"
#define ngx_mkdir(name) CreateDirectory(name, NULL)
diff --git a/src/os/win32/ngx_os.h b/src/os/win32/ngx_os.h
index 96f1c2d1f..52a7c05a8 100644
--- a/src/os/win32/ngx_os.h
+++ b/src/os/win32/ngx_os.h
@@ -1,4 +1,4 @@
-ifndef _NGX_OS_H_INCLUDED_
+#ifndef _NGX_OS_H_INCLUDED_
#define _NGX_OS_H_INCLUDED_
@@ -33,6 +33,11 @@ typedef struct {
int ngx_os_init(ngx_log_t *log);
+ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size);
+ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, char *buf, size_t size);
+ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in);
+ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in);
+
extern ngx_os_io_t ngx_os_io;
extern int ngx_max_sockets;
diff --git a/src/os/win32/ngx_os_init.h b/src/os/win32/ngx_os_init.h
deleted file mode 100644
index 8ab820694..000000000
--- a/src/os/win32/ngx_os_init.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _NGX_OS_INIT_H_INCLUDED_
-#define _NGX_OS_INIT_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-int ngx_os_init(ngx_log_t *log);
-
-ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size);
-
-
-#endif /* _NGX_OS_INIT_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_recv.c b/src/os/win32/ngx_recv.c
deleted file mode 100644
index ad2232c21..000000000
--- a/src/os/win32/ngx_recv.c
+++ /dev/null
@@ -1,93 +0,0 @@
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
-{
- int rc;
- u_int flags;
- size_t bytes;
- ngx_err_t err;
- WSABUF wsabuf[1];
- ngx_event_t *ev;
- LPWSAOVERLAPPED_COMPLETION_ROUTINE handler;
-
- ev = c->read;
-
-/* DEBUG */ bytes = 0;
-
- if (ev->timedout) {
- ngx_set_socket_errno(NGX_ETIMEDOUT);
- ngx_log_error(NGX_LOG_ERR, ev->log, 0, "WSARecv() timed out");
-
- return NGX_ERROR;
- }
-
- if (ev->ready) {
- ev->ready = 0;
-
-#if (HAVE_IOCP_EVENT) /* iocp */
-
- if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
- if (ev->ovlp.error) {
- ngx_log_error(NGX_LOG_ERR, c->log, ev->ovlp.error,
- "WSARecv() failed");
- return NGX_ERROR;
- }
-
- return ev->available;
- }
-
-#endif
-
- if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &ev->ovlp,
- &bytes, 0, NULL) == 0) {
- err = ngx_socket_errno;
- ngx_log_error(NGX_LOG_CRIT, ev->log, err,
- "WSARecv() or WSAGetOverlappedResult() failed");
-
- return NGX_ERROR;
- }
-
- return bytes;
- }
-
- ngx_memzero(&ev->ovlp, sizeof(WSAOVERLAPPED));
- wsabuf[0].buf = buf;
- wsabuf[0].len = size;
- flags = 0;
-
-#if 0
- handler = ev->handler;
-#else
- handler = NULL;
-#endif
-
- rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags,
- (LPWSAOVERLAPPED) &ev->ovlp, handler);
-
- ngx_log_debug(ev->log, "WSARecv: %d:%d" _ rc _ bytes);
-
- if (rc == -1) {
- err = ngx_socket_errno;
- if (err == WSA_IO_PENDING) {
- return NGX_AGAIN;
-
- } else {
- ngx_log_error(NGX_LOG_CRIT, ev->log, err, "WSARecv() failed");
- return NGX_ERROR;
- }
- }
-
-#if (HAVE_IOCP_EVENT) /* iocp */
-
- if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
- return NGX_AGAIN;
- }
-
-#endif
-
- return bytes;
-}
diff --git a/src/os/win32/ngx_win32_init.c b/src/os/win32/ngx_win32_init.c
index c522c9e95..77e4462d0 100644
--- a/src/os/win32/ngx_win32_init.c
+++ b/src/os/win32/ngx_win32_init.c
@@ -2,11 +2,6 @@
#include <ngx_config.h>
#include <ngx_core.h>
-/* STUB */
-ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size);
-ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in);
-/* */
-
int ngx_win32_version;
int ngx_max_sockets;
diff --git a/src/os/win32/ngx_wsarecv.c b/src/os/win32/ngx_wsarecv.c
index 883bed805..2a43498ad 100644
--- a/src/os/win32/ngx_wsarecv.c
+++ b/src/os/win32/ngx_wsarecv.c
@@ -6,6 +6,149 @@
ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
{
+ int rc;
+ u_int flags;
+ size_t bytes;
+ WSABUF wsabuf[1];
+ ngx_err_t err;
+ ngx_event_t *rev;
+
+ wsabuf[0].buf = buf;
+ wsabuf[0].len = size;
+ flags = 0;
+ bytes = 0;
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, NULL, NULL);
+
+ ngx_log_debug(c->log, "WSARecv: %d:%d" _ rc _ bytes);
+
+ 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;
+}
+
+
+ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, char *buf, size_t size)
+{
+ int rc;
+ u_int flags;
+ size_t bytes;
+ WSABUF wsabuf[1];
+ ngx_err_t err;
+ ngx_event_t *rev;
+ LPWSAOVERLAPPED ovlp;
+
+ rev = c->read;
+
+ if (!rev->ready) {
+ ngx_log_error(NGX_LOG_ALERT, rev->log, 0, "SECOND WSA POST");
+ return NGX_AGAIN;
+ }
+
+ ngx_log_debug(c->log, "rev->complete: %d" _ rev->complete);
+
+ if (rev->complete) {
+ rev->complete = 0;
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+ if (rev->ovlp.error) {
+ ngx_log_error(NGX_LOG_ERR, c->log, rev->ovlp.error,
+ "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ return rev->available;
+ }
+
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
+ &bytes, 0, NULL) == 0) {
+ ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
+ "WSARecv() or WSAGetOverlappedResult() failed");
+
+ return NGX_ERROR;
+ }
+
+ return bytes;
+ }
+
+ ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+ wsabuf[0].buf = buf;
+ wsabuf[0].len = size;
+ flags = 0;
+ bytes = 0;
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
+
+ rev->complete = 0;
+
+ ngx_log_debug(c->log, "WSARecv: %d:%d" _ rc _ bytes);
+
+ if (rc == -1) {
+ err = ngx_socket_errno;
+ if (err == WSA_IO_PENDING) {
+ rev->active = 1;
+ return NGX_AGAIN;
+ }
+
+ rev->error = 1;
+ ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+
+ /*
+ * if a socket was bound with I/O completion port
+ * then GetQueuedCompletionStatus() would anyway return its status
+ * despite that WSARecv() was already complete
+ */
+
+ rev->active = 1;
+ return NGX_AGAIN;
+ }
+
+ if (bytes == 0) {
+ rev->eof = 1;
+ rev->ready = 0;
+
+ } else {
+ rev->ready = 1;
+ }
+
+ rev->active = 0;
+
+ return bytes;
+}
+
+#if 0
+
+/* DELELTE IT WHEN ABOVE FUNC WOULD BE TESTED */
+
+ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
+{
int rc;
u_int flags;
size_t bytes;
@@ -88,3 +231,5 @@ ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
return bytes;
}
+
+#endif
diff --git a/src/os/win32/ngx_wsasend_chain.c b/src/os/win32/ngx_wsasend_chain.c
index 5bfd71542..f0b5fe24c 100644
--- a/src/os/win32/ngx_wsasend_chain.c
+++ b/src/os/win32/ngx_wsasend_chain.c
@@ -6,6 +6,249 @@
ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in)
{
+ int rc;
+ char *prev;
+ size_t size, sent;
+ LPWSABUF wsabuf;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ ngx_array_t wsabufs;
+ ngx_chain_t *cl;
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return in;
+ }
+
+ /*
+ * WSABUFs must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR);
+
+ prev = NULL;
+ wsabuf = NULL;
+
+ /* create the WSABUF and coalesce the neighbouring bufs */
+
+ for (cl = in; cl; cl = cl->next) {
+
+ if (prev == cl->hunk->pos) {
+ wsabuf->len += cl->hunk->last - cl->hunk->pos;
+ prev = cl->hunk->last;
+
+ } else {
+ ngx_test_null(wsabuf, ngx_push_array(&wsabufs), NGX_CHAIN_ERROR);
+ wsabuf->buf = cl->hunk->pos;
+ wsabuf->len = cl->hunk->last - cl->hunk->pos;
+ prev = cl->hunk->last;
+ }
+ }
+
+ rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, NULL, NULL);
+
+ if (rc == -1) {
+ err = ngx_errno;
+
+ if (err == WSAEWOULDBLOCK) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() EAGAIN");
+ wev->ready = 0;
+ return in;
+
+ } else {
+ wev->error = 1;
+ ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed");
+ return NGX_CHAIN_ERROR;
+ }
+ }
+
+#if (NGX_DEBUG_WRITE_CHAIN)
+ ngx_log_debug(c->log, "WSASend(): %d" _ sent);
+#endif
+
+ c->sent += sent;
+
+ for (cl = in; cl && sent > 0; cl = cl->next) {
+
+ size = cl->hunk->last - cl->hunk->pos;
+
+ if (sent >= size) {
+ sent -= size;
+
+ if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+ cl->hunk->pos = cl->hunk->last;
+ }
+
+ continue;
+ }
+
+ if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+ cl->hunk->pos += sent;
+ }
+
+ break;
+ }
+
+ if (cl) {
+ wev->ready = 0;
+ }
+
+ return cl;
+}
+
+
+ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in)
+{
+ int rc;
+ char *prev;
+ size_t size, sent;
+ LPWSABUF wsabuf;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ ngx_array_t wsabufs;
+ ngx_chain_t *cl;
+ LPWSAOVERLAPPED ovlp;
+
+ wev = c->write;
+
+ if (!wev->ready) {
+ return in;
+ }
+
+ if (!wev->complete) {
+
+ /* post the overlapped WSASend() */
+
+ /*
+ * WSABUFs must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR);
+
+ prev = NULL;
+ wsabuf = NULL;
+
+ /* create the WSABUF and coalesce the neighbouring bufs */
+
+ for (cl = in; cl; cl = cl->next) {
+
+ if (prev == cl->hunk->pos) {
+ wsabuf->len += cl->hunk->last - cl->hunk->pos;
+ prev = cl->hunk->last;
+
+ } else {
+ ngx_test_null(wsabuf, ngx_push_array(&wsabufs),
+ NGX_CHAIN_ERROR);
+ wsabuf->buf = cl->hunk->pos;
+ wsabuf->len = cl->hunk->last - cl->hunk->pos;
+ prev = cl->hunk->last;
+ }
+ }
+
+ ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+
+ rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL);
+
+ wev->complete = 0;
+
+ if (rc == -1) {
+ err = ngx_errno;
+
+ if (err == WSA_IO_PENDING) {
+ wev->active = 1;
+ return in;
+
+ } else {
+ wev->error = 1;
+ ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed");
+ return NGX_CHAIN_ERROR;
+ }
+
+ } else if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+
+ /*
+ * if a socket was bound with I/O completion port then
+ * GetQueuedCompletionStatus() would anyway return its status
+ * despite that WSASend() was already complete
+ */
+
+ wev->active = 1;
+ return in;
+ }
+
+ } else {
+
+ /* the overlapped WSASend() complete */
+
+ wev->complete = 0;
+ wev->active = 0;
+
+ if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
+ if (wev->ovlp.error) {
+ ngx_log_error(NGX_LOG_ERR, c->log, wev->ovlp.error,
+ "WSASend() failed");
+ return NGX_CHAIN_ERROR;
+ }
+
+ sent = wev->available;
+
+ } else {
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp,
+ &sent, 0, NULL) == 0) {
+ ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
+ "WSASend() or WSAGetOverlappedResult() failed");
+
+ return NGX_CHAIN_ERROR;
+ }
+ }
+ }
+
+#if (NGX_DEBUG_WRITE_CHAIN)
+ ngx_log_debug(c->log, "WSASend(): %d" _ sent);
+#endif
+
+ c->sent += sent;
+
+ for (cl = in; cl && sent > 0; cl = cl->next) {
+
+ size = cl->hunk->last - cl->hunk->pos;
+
+ if (sent >= size) {
+ sent -= size;
+
+ if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+ cl->hunk->pos = cl->hunk->last;
+ }
+
+ continue;
+ }
+
+ if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+ cl->hunk->pos += sent;
+ }
+
+ break;
+ }
+
+ if (cl) {
+ wev->ready = 0;
+
+ } else {
+ wev->ready = 1;
+ }
+
+ return cl;
+}
+
+
+#if 0
+
+ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in)
+{
int rc;
char *prev;
size_t size, sent;
@@ -175,7 +418,7 @@ non-block
break;
}
- ngx_destroy_array(&wsabufs);
-
return ce;
}
+
+#endif