nginx-0.0.1-2003-11-14-10:20:34 import

This commit is contained in:
Igor Sysoev 2003-11-14 07:20:34 +00:00
parent 45890ea8c1
commit 7f9d894e10
16 changed files with 534 additions and 170 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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"

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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)
}
ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
off_t offset, ngx_pool_t *pool)
{
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)
{
ngx_err_t err;
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;
}
}

View File

@ -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)

View File

@ -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;

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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;

View File

@ -4,6 +4,149 @@
#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;
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;
@ -88,3 +231,5 @@ ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
return bytes;
}
#endif

View File

@ -4,6 +4,249 @@
#include <ngx_event.h>
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;
@ -175,7 +418,7 @@ non-block
break;
}
ngx_destroy_array(&wsabufs);
return ce;
}
#endif