nginx-0.0.3-2004-06-01-10:04:46 import

This commit is contained in:
Igor Sysoev 2004-06-01 06:04:46 +00:00
parent 369145cef1
commit 67f450d7bc
19 changed files with 146 additions and 299 deletions

View File

@ -142,29 +142,6 @@ typedef struct {
(ngx_buf_in_memory(b) ? (size_t) (b->last - b->pos): \
(size_t) (b->file_last - b->file_pos))
#if 0
#define ngx_hunk_in_memory_only(h) \
((h->type & (NGX_HUNK_IN_MEMORY|NGX_HUNK_FILE)) == NGX_HUNK_IN_MEMORY)
/*
((h->type & (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP|NGX_HUNK_FILE)) \
== (h->type & (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))
*/
#define ngx_hunk_special(b) \
(b->type == (b->type & (NGX_HUNK_FLUSH|NGX_HUNK_LAST)))
#define ngx_hunk_size(b) \
((b->type & NGX_HUNK_IN_MEMORY) ? (size_t) (b->last - b->pos): \
(size_t) (b->file_last - b->file_pos))
#endif
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);

View File

@ -60,6 +60,13 @@ typedef enum {
} ngx_connection_log_error_e;
typedef enum {
NGX_TCP_NOPUSH_DISABLED = -1,
NGX_TCP_NOPUSH_UNSET = 0,
NGX_TCP_NOPUSH_SET
} ngx_connection_tcp_nopush_e;
struct ngx_connection_s {
void *data;
ngx_event_t *read;

View File

@ -38,7 +38,7 @@ int ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
}
}
/* add the incoming hunk to the chain ctx->in */
/* add the incoming buf to the chain ctx->in */
if (in) {
if (ngx_chain_add_copy(ctx->pool, &ctx->in, in) == NGX_ERROR) {

View File

@ -15,10 +15,6 @@
#define SIGRTMIN 33
#define si_fd __spare__[0]
int sigtimedwait(const sigset_t *set, siginfo_t *info,
const struct timespec *timeout);
int sigtimedwait(const sigset_t *set, siginfo_t *info,
const struct timespec *timeout)
{
@ -105,6 +101,7 @@ static int ngx_rtsig_init(ngx_cycle_t *cycle)
sigemptyset(&set);
sigaddset(&set, rtscf->signo);
sigaddset(&set, rtscf->signo + 1);
sigaddset(&set, SIGIO);
if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
@ -133,12 +130,15 @@ static void ngx_rtsig_done(ngx_cycle_t *cycle)
static int ngx_rtsig_add_connection(ngx_connection_t *c)
{
int signo;
ngx_rtsig_conf_t *rtscf;
rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
signo = rtscf->signo + c->read->instance;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"rtsig add connection: fd:%d signo:%d", c->fd, rtscf->signo);
"rtsig add connection: fd:%d signo:%d", c->fd, signo);
if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
@ -146,13 +146,13 @@ static int ngx_rtsig_add_connection(ngx_connection_t *c)
return NGX_ERROR;
}
if (fcntl(c->fd, F_SETSIG, rtscf->signo) == -1) {
if (fcntl(c->fd, F_SETSIG, signo) == -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"fcntl(F_SETSIG) failed");
return NGX_ERROR;
}
if (fcntl(c->fd, F_SETOWN, ngx_getpid()) == -1) {
if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"fcntl(F_SETOWN) failed");
return NGX_ERROR;
@ -175,6 +175,9 @@ static int ngx_rtsig_add_connection(ngx_connection_t *c)
static int ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags)
{
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"rtsig del connection: fd:%d", c->fd);
if (!(flags & NGX_CLOSE_EVENT)) {
if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK) == -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
@ -273,9 +276,9 @@ int ngx_rtsig_process_events(ngx_cycle_t *cycle)
ngx_elapsed_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000 - ngx_start_msec;
if (err) {
ngx_accept_mutex_unlock();
ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
cycle->log, err, "sigtimedwait() failed");
ngx_accept_mutex_unlock();
return NGX_ERROR;
}
@ -287,17 +290,40 @@ int ngx_rtsig_process_events(ngx_cycle_t *cycle)
}
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"signo:%d fd:%d band:%X", signo, si.si_fd, si.si_band);
"rtsig signo:%d fd:%d band:%X", signo, si.si_fd, si.si_band);
rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
if (signo == rtscf->signo) {
if (signo == rtscf->signo || signo == rtscf->signo + 1) {
/* TODO: old_cycles */
c = &ngx_cycle->connections[si.si_fd];
/* TODO: stale signals */
instance = signo - rtscf->signo;
if (si.si_band & POLLIN) {
c->read->returned_instance = instance;
}
if (si.si_band & POLLOUT) {
c->write->returned_instance = instance;
}
if (c->read->instance != instance) {
/*
* the stale event from a file descriptor
* that was just closed in this iteration
*/
ngx_accept_mutex_unlock();
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"rtsig: stale event " PTR_FMT, c);
return NGX_OK;
}
if (si.si_band & (POLLIN|POLLHUP|POLLERR)) {
if (c->read->active) {
@ -307,7 +333,7 @@ int ngx_rtsig_process_events(ngx_cycle_t *cycle)
c->read->event_handler(c->read);
} else if (c->read->accept) {
if (ngx_accept_disabled > 0) {
if (ngx_accept_disabled <= 0) {
c->read->event_handler(c->read);
}
@ -371,9 +397,11 @@ int ngx_rtsig_process_events(ngx_cycle_t *cycle)
} else {
ngx_accept_mutex_unlock();
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"sigtimedwait() returned unexpected signal: %d", signo);
ngx_accept_mutex_unlock();
return NGX_ERROR;
}

View File

@ -372,9 +372,16 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
rev->event_handler = &ngx_event_accept;
if (ngx_event_flags & NGX_USE_SIGIO_EVENT) {
if (ngx_add_conn(c) == NGX_ERROR) {
return NGX_ERROR;
if (ngx_accept_mutex) {
ngx_accept_mutex_held = 0;
} else {
if (ngx_add_conn(c) == NGX_ERROR) {
return NGX_ERROR;
}
}
} else {
if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
return NGX_ERROR;

View File

@ -264,6 +264,16 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
}
}
if (ngx_add_conn) {
if (rc == -1) {
/* NGX_EINPROGRESS */
return NGX_AGAIN;
}
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected");
return NGX_OK;
}
if (ngx_event_flags & NGX_USE_AIO_EVENT) {
/* aio, iocp */
@ -294,8 +304,6 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
return NGX_OK;
}
/* TODO: epoll */
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { /* kqueue */
event = NGX_CLEAR_EVENT;

View File

@ -225,7 +225,7 @@ ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
/* if there're no bufs to read in then disable a level event */
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
"no pipe hunks to read in");
"no pipe bufs to read in");
break;
}

View File

@ -435,9 +435,9 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
/*
* We preallocate a memory for zlib in one hunk (200K-400K), this
* We preallocate a memory for zlib in one buffer (200K-400K), this
* dicreases a number of malloc() and free() calls and also probably
* dicreases a number of syscalls.
* dicreases a number of syscalls (sbrk() or so).
* Besides we free() this memory as soon as the gzipping will complete
* and do not wait while a whole response will be sent to a client.
*

View File

@ -701,7 +701,7 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
/* rc == NGX_OK */
if (c->tcp_nopush) {
if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
if (ngx_tcp_push(c->fd) == NGX_ERROR) {
ngx_log_error(NGX_LOG_CRIT, c->log,
ngx_socket_errno,
@ -710,7 +710,7 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
return;
}
c->tcp_nopush = 0;
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
return;
}
@ -1138,7 +1138,7 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
return;
}
/* TODO: preallocate event_pipe hunks, look "Content-Length" */
/* TODO: preallocate event_pipe bufs, look "Content-Length" */
rc = ngx_http_send_header(r);

View File

@ -567,7 +567,7 @@ int ngx_http_find_location_config(ngx_http_request_t *r)
if (!clcf->tcp_nopush) {
/* disable TCP_NOPUSH/TCP_CORK use */
r->connection->tcp_nopush = -1;
r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
}

View File

@ -92,7 +92,7 @@ void ngx_http_init_connection(ngx_connection_t *c)
if (rev->ready) {
/* deferred accept, aio, iocp */
if (*ngx_accept_mutex) {
if (ngx_accept_mutex) {
if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
ngx_http_close_connection(c);
return;
@ -562,10 +562,10 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
/*
* If it's a pipelined request and a request line is not complete
* then we have to copy it to the start of the r->header_in hunk.
* then we have to copy it to the start of the r->header_in buf.
* We have to copy it here only if the large client headers
* are enabled otherwise a request line had been already copied
* to the start of the r->header_in hunk in ngx_http_set_keepalive().
* to the start of the r->header_in buf in ngx_http_set_keepalive().
*/
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@ -757,8 +757,10 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
if (r->header_in->last == r->header_in->end) {
/* if the large client headers are enabled then
we need to compact r->header_in hunk */
/*
* if the large client headers are enabled then
* we need to compact r->header_in buf
*/
if (cscf->large_client_header) {
offset = r->header_name_start - r->header_in->start;
@ -1315,13 +1317,13 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r)
ctx->action = "keepalive";
if (c->tcp_nopush == 1) {
if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
if (ngx_tcp_push(c->fd) == NGX_ERROR) {
ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
ngx_http_close_connection(c);
return;
}
c->tcp_nopush = 0;
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
}
if (rev->ready) {

View File

@ -223,15 +223,6 @@ struct ngx_http_request_s {
ngx_http_request_body_t *request_body;
#if 0
ngx_temp_file_t *temp_file;
ngx_chain_t *request_hunks;
ngx_hunk_t *request_body_hunk;
size_t remaining_body_len;
void (*request_body_handler) (void *data);
void *data;
#endif
time_t lingering_time;
ngx_uint_t method;

View File

@ -129,8 +129,8 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_http_write_filter_module);
/*
* avoid the output if there is no last hunk, no flush point,
* there are the incoming hunks and the size of all hunks
* avoid the output if there is no last buf, no flush point,
* there are the incoming bufs and the size of all bufs
* is smaller than "postpone_output" directive
*/

View File

@ -125,7 +125,7 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
ngx_err_t err;
ngx_array_t io;
/* use pwrite() if there's the only hunk in a chain */
/* use pwrite() if there's the only buf in a chain */
if (cl->next == NULL) {
return ngx_write_file(file, cl->buf->pos,

View File

@ -162,7 +162,9 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
if (file) {
if (ngx_freebsd_use_tcp_nopush && c->tcp_nopush == 0) {
if (ngx_freebsd_use_tcp_nopush
&& c->tcp_nopush == NGX_TCP_NOPUSH_UNSET)
{
if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
err = ngx_errno;
@ -180,7 +182,8 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
}
} else {
c->tcp_nopush = 1;
c->tcp_nopush = NGX_TCP_NOPUSH_SET;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"tcp_nopush");
}

View File

@ -58,32 +58,32 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
/* create the iovec and coalesce the neighbouring bufs */
for (cl = in; cl && header.nelts < IOV_MAX; cl = cl->next) {
if (ngx_hunk_special(cl->hunk)) {
if (ngx_buf_special(cl->buf)) {
continue;
}
if (!ngx_hunk_in_memory_only(cl->hunk)) {
if (!ngx_buf_in_memory_only(cl->buf)) {
break;
}
if (prev == cl->hunk->pos) {
iov->iov_len += cl->hunk->last - cl->hunk->pos;
if (prev == cl->buf->pos) {
iov->iov_len += cl->buf->last - cl->buf->pos;
} else {
ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR);
iov->iov_base = (void *) cl->hunk->pos;
iov->iov_len = cl->hunk->last - cl->hunk->pos;
iov->iov_base = (void *) cl->buf->pos;
iov->iov_len = cl->buf->last - cl->buf->pos;
}
prev = cl->hunk->last;
prev = cl->buf->last;
}
/* set TCP_CORK if there is a header before a file */
if (!c->tcp_nopush == 0
if (c->tcp_nopush == NGX_TCP_NOPUSH_UNSET
&& header.nelts != 0
&& cl
&& cl->hunk->type & NGX_HUNK_FILE)
&& cl->buf->in_file)
{
if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
err = ngx_errno;
@ -100,32 +100,33 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
}
} else {
c->tcp_nopush = 1;
c->tcp_nopush = NGX_TCP_NOPUSH_SET;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
"tcp_nopush");
}
}
if (header.nelts == 0 && cl && cl->hunk->type & NGX_HUNK_FILE) {
if (header.nelts == 0 && cl && cl->buf->in_file) {
/* get the file hunk */
/* get the file buf */
file = cl->hunk;
file = cl->buf;
fsize = (size_t) (file->file_last - file->file_pos);
fprev = file->file_last;
cl = cl->next;
/* coalesce the neighbouring file hunks */
/* coalesce the neighbouring file bufs */
while (cl && (cl->hunk->type & NGX_HUNK_FILE)) {
if (file->file->fd != cl->hunk->file->fd
|| fprev != cl->hunk->file_pos)
while (cl && (cl->buf->in_file)) {
if (file->file->fd != cl->buf->file->fd
|| fprev != cl->buf->file_pos)
{
break;
}
fsize += (size_t) (cl->hunk->file_last - cl->hunk->file_pos);
fprev = cl->hunk->file_last;
fsize += (size_t) (cl->buf->file_last - cl->buf->file_pos);
fprev = cl->buf->file_last;
cl = cl->next;
}
}
@ -199,7 +200,7 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
for (cl = in; cl; cl = cl->next) {
if (ngx_hunk_special(cl->hunk)) {
if (ngx_buf_special(cl->buf)) {
continue;
}
@ -207,28 +208,28 @@ ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
break;
}
size = ngx_hunk_size(cl->hunk);
size = ngx_buf_size(cl->buf);
if (sent >= size) {
sent -= size;
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
cl->hunk->pos = cl->hunk->last;
if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos = cl->buf->last;
}
if (cl->hunk->type & NGX_HUNK_FILE) {
cl->hunk->file_pos = cl->hunk->file_last;
if (cl->buf->in_file) {
cl->buf->file_pos = cl->buf->file_last;
}
continue;
}
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
cl->hunk->pos += sent;
if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos += sent;
}
if (cl->hunk->type & NGX_HUNK_FILE) {
cl->hunk->file_pos += sent;
if (cl->buf->in_file) {
cl->buf->file_pos += sent;
}
break;

View File

@ -43,42 +43,42 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
/* create the sendfilevec and coalesce the neighbouring bufs */
for (cl = in; cl && vec.nelts < IOV_MAX; cl = cl->next) {
if (ngx_hunk_special(cl->hunk)) {
if (ngx_buf_special(cl->buf)) {
continue;
}
if (ngx_hunk_in_memory_only(cl->hunk)) {
if (ngx_buf_in_memory_only(cl->buf)) {
fd = SFV_FD_SELF;
if (prev == cl->hunk->pos) {
sfv->sfv_len += cl->hunk->last - cl->hunk->pos;
if (prev == cl->buf->pos) {
sfv->sfv_len += cl->buf->last - cl->buf->pos;
} else {
ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR);
sfv->sfv_fd = SFV_FD_SELF;
sfv->sfv_flag = 0;
sfv->sfv_off = (off_t) (uintptr_t) cl->hunk->pos;
sfv->sfv_len = cl->hunk->last - cl->hunk->pos;
sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos;
sfv->sfv_len = cl->buf->last - cl->buf->pos;
}
prev = cl->hunk->last;
prev = cl->buf->last;
} else {
prev = NULL;
if (fd == cl->hunk->file->fd && fprev == cl->hunk->file_pos) {
sfv->sfv_len += cl->hunk->file_last - cl->hunk->file_pos;
if (fd == cl->buf->file->fd && fprev == cl->buf->file_pos) {
sfv->sfv_len += cl->buf->file_last - cl->buf->file_pos;
} else {
ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR);
fd = cl->hunk->file->fd;
fd = cl->buf->file->fd;
sfv->sfv_fd = fd;
sfv->sfv_flag = 0;
sfv->sfv_off = cl->hunk->file_pos;
sfv->sfv_len = cl->hunk->file_last - cl->hunk->file_pos;
sfv->sfv_off = cl->buf->file_pos;
sfv->sfv_len = cl->buf->file_last - cl->buf->file_pos;
}
fprev = cl->hunk->file_last;
fprev = cl->buf->file_last;
}
}
@ -117,7 +117,7 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
for (cl = in; cl; cl = cl->next) {
if (ngx_hunk_special(cl->hunk)) {
if (ngx_buf_special(cl->buf)) {
continue;
}
@ -125,28 +125,28 @@ ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
break;
}
size = ngx_hunk_size(cl->hunk);
size = ngx_buf_size(cl->buf);
if (sent >= size) {
sent -= size;
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
cl->hunk->pos = cl->hunk->last;
if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos = cl->buf->last;
}
if (cl->hunk->type & NGX_HUNK_FILE) {
cl->hunk->file_pos = cl->hunk->file_last;
if (cl->buf->in_file) {
cl->buf->file_pos = cl->buf->file_last;
}
continue;
}
if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
cl->hunk->pos += sent;
if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos += sent;
}
if (cl->hunk->type & NGX_HUNK_FILE) {
cl->hunk->file_pos += sent;
if (cl->buf->in_file) {
cl->buf->file_pos += sent;
}
break;

View File

@ -143,7 +143,7 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl,
prev = buf;
size = 0;
/* coalesce the neighbouring hunks */
/* coalesce the neighbouring bufs */
while (cl && prev == cl->buf->pos) {
size += cl->buf->last - cl->buf->pos;

View File

@ -241,180 +241,3 @@ ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in)
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;
LPWSABUF wsabuf;
ngx_err_t err;
ngx_event_t *wev;
ngx_array_t wsabufs;
ngx_chain_t *ce;
LPWSAOVERLAPPED ovlp;
#if 0
iocp:
if ready
get result
update chain
return if done;
wsasend
non-block
for ( ;; ) {
wsasend
if no again
update chain
return if done;
}
for ( ;; ) {
make buffers and limit data for both ovlp and nonblocked,
configured in events module
if (iocp && ready) {
get result
} else {
if (file)
transmitfile
else
wsasend
if (iocp)
return chain
return chain if again
here is result
}
if (result)
update chain;
return chain if done
}
}
#endif
wev = c->write;
if (((ngx_event_flags & NGX_USE_AIO_EVENT) && !wev->ready)
|| ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0))
{
/*
* 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 chain entries */
for (ce = in; ce; ce = ce->next) {
if (prev == ce->hunk->pos) {
wsabuf->len += ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
} else {
ngx_test_null(wsabuf, ngx_push_array(&wsabufs),
NGX_CHAIN_ERROR);
wsabuf->buf = ce->hunk->pos;
wsabuf->len = ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
}
}
if (ngx_event_flags & NGX_USE_AIO_EVENT) {
ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
} else {
ovlp = NULL;
}
rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL);
if (rc == -1) {
err = ngx_errno;
if (err == WSA_IO_PENDING) {
sent = 0;
} else if (err == WSAEWOULDBLOCK) {
sent = 0;
ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() EAGAIN");
} else {
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 completed.
*/
sent = 0;
}
}
} else {
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
wev->ready = 0;
/* the overlapped WSASend() completed */
if (wev->ovlp.error) {
ngx_log_error(NGX_LOG_ERR, c->log, wev->ovlp.error,
"WSASend() failed");
return NGX_CHAIN_ERROR;
}
sent = wev->available;
}
}
ngx_log_debug(c->log, "WSASend(): %d" _ sent);
c->sent += sent;
for (ce = in; ce && sent > 0; ce = ce->next) {
size = ce->hunk->last - ce->hunk->pos;
if (sent >= size) {
sent -= size;
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
ce->hunk->pos = ce->hunk->last;
}
continue;
}
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
ce->hunk->pos += sent;
}
break;
}
return ce;
}
#endif