Win32: removed the iocp event module

The I/O completion ports event method has never been completed: the
module is compiled into Windows builds, but is not documented or
supported.

Prodded by Marek Ludha.
This commit is contained in:
Vadim Zhestikov authored and VadimZhestikov committed 2026-10-15 08:06:49 -07:00
1 parent 35a437d3d9
commit b390773fad
27 files changed
+28 -1564

No files matched your search

+1 -6
View File
@@ -7,7 +7,7 @@ have=NGX_WIN32 . auto/have_headers
CORE_INCS="$WIN32_INCS"
CORE_DEPS="$WIN32_DEPS"
CORE_SRCS="$WIN32_SRCS $IOCP_SRCS"
CORE_SRCS="$WIN32_SRCS"
OS_CONFIG="$WIN32_CONFIG"
NGX_ICONS="$NGX_WIN32_ICONS"
SELECT_SRCS=$WIN32_SELECT_SRCS
@@ -31,9 +31,4 @@ case "$NGX_CC_NAME" in
esac
EVENT_MODULES="$EVENT_MODULES $IOCP_MODULE"
#EVENT_FOUND=YES
have=NGX_HAVE_INET6 . auto/have
have=NGX_HAVE_IOCP . auto/have
+1 -5
View File
@@ -131,9 +131,6 @@ EVENTPORT_SRCS=src/event/modules/ngx_eventport_module.c
EPOLL_MODULE=ngx_epoll_module
EPOLL_SRCS=src/event/modules/ngx_epoll_module.c
IOCP_MODULE=ngx_iocp_module
IOCP_SRCS=src/event/modules/ngx_iocp_module.c
FILE_AIO_SRCS="src/os/unix/ngx_file_aio_read.c"
LINUX_AIO_SRCS="src/os/unix/ngx_linux_aio_read.c"
@@ -261,8 +258,7 @@ WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \
src/os/win32/ngx_user.c \
src/os/win32/ngx_dlopen.c \
src/os/win32/ngx_event_log.c \
src/os/win32/ngx_process_cycle.c \
src/event/ngx_event_acceptex.c"
src/os/win32/ngx_process_cycle.c"
NGX_WIN32_ICONS="src/os/win32/nginx.ico"
NGX_WIN32_RC="src/os/win32/nginx.rc"
-3
View File
@@ -121,7 +121,6 @@ syn keyword ngxDirectiveDeprecated contained http2_recv_timeout
syn keyword ngxDirective contained absolute_redirect
syn keyword ngxDirective contained accept_mutex
syn keyword ngxDirective contained accept_mutex_delay
syn keyword ngxDirective contained acceptex_read
syn keyword ngxDirective contained access_log
syn keyword ngxDirective contained add_after_body
syn keyword ngxDirective contained add_before_body
@@ -307,7 +306,6 @@ syn keyword ngxDirective contained imap_auth
syn keyword ngxDirective contained imap_capabilities
syn keyword ngxDirective contained imap_client_buffer
syn keyword ngxDirective contained index
syn keyword ngxDirective contained iocp_threads
syn keyword ngxDirective contained ip_hash
syn keyword ngxDirective contained js_access
syn keyword ngxDirective contained js_body_filter
@@ -403,7 +401,6 @@ syn keyword ngxDirective contained pid
syn keyword ngxDirective contained pop3_auth
syn keyword ngxDirective contained pop3_capabilities
syn keyword ngxDirective contained port_in_redirect
syn keyword ngxDirective contained post_acceptex
syn keyword ngxDirective contained postpone_gzipping
syn keyword ngxDirective contained postpone_output
syn keyword ngxDirective contained preread_buffer_size
+9 -15
View File
@@ -608,20 +608,18 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
#endif
/* TODO: close on exit */
if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
if (ngx_nonblocking(s) == -1) {
if (ngx_nonblocking(s) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_nonblocking_n " %V failed",
&ls[i].addr_text);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_nonblocking_n " %V failed",
ngx_close_socket_n " %V failed",
&ls[i].addr_text);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[i].addr_text);
}
return NGX_ERROR;
}
return NGX_ERROR;
}
ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
@@ -1131,10 +1129,6 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
ngx_listening_t *ls;
ngx_connection_t *c;
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
return;
}
ngx_accept_mutex_held = 0;
ngx_use_accept_mutex = 0;
-2
View File
@@ -44,8 +44,6 @@ struct ngx_listening_s {
ngx_log_t *logp;
size_t pool_size;
/* should be here because of the AcceptEx() preread */
size_t post_accept_buffer_size;
ngx_listening_t *previous;
ngx_connection_t *connection;
-4
View File
@@ -29,11 +29,7 @@
#define NGX_MODULE_SIGNATURE_1 "0"
#endif
#if (NGX_HAVE_IOCP)
#define NGX_MODULE_SIGNATURE_2 "1"
#else
#define NGX_MODULE_SIGNATURE_2 "0"
#endif
#if (NGX_HAVE_FILE_AIO || NGX_COMPAT)
#define NGX_MODULE_SIGNATURE_3 "1"
-26
View File
@@ -4508,8 +4508,6 @@ ngx_udp_connect(ngx_resolver_connection_t *rec)
rc = connect(s, rec->sockaddr, rec->socklen);
/* TODO: iocp */
if (rc == -1) {
ngx_log_error(NGX_LOG_CRIT, &rec->log, ngx_socket_errno,
"connect() failed");
@@ -4658,30 +4656,6 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec)
return NGX_OK;
}
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, ngx_socket_errno,
"connect(): %d", rc);
if (ngx_blocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno,
ngx_blocking_n " failed");
goto failed;
}
/*
* FreeBSD's aio allows to post an operation on non-connected socket.
* NT does not support it.
*
* TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT
*/
rev->ready = 1;
wev->ready = 1;
return NGX_OK;
}
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
/* kqueue */
-379
View File
@@ -1,379 +0,0 @@
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_iocp_module.h>
static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static ngx_thread_value_t __stdcall ngx_iocp_timer(void *data);
static void ngx_iocp_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t key);
static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags);
static ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
static void *ngx_iocp_create_conf(ngx_cycle_t *cycle);
static char *ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf);
static ngx_str_t iocp_name = ngx_string("iocp");
static ngx_command_t ngx_iocp_commands[] = {
{ ngx_string("iocp_threads"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
0,
offsetof(ngx_iocp_conf_t, threads),
NULL },
{ ngx_string("post_acceptex"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
0,
offsetof(ngx_iocp_conf_t, post_acceptex),
NULL },
{ ngx_string("acceptex_read"),
NGX_EVENT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_iocp_conf_t, acceptex_read),
NULL },
ngx_null_command
};
static ngx_event_module_t ngx_iocp_module_ctx = {
&iocp_name,
ngx_iocp_create_conf, /* create configuration */
ngx_iocp_init_conf, /* init configuration */
{
ngx_iocp_add_event, /* add an event */
NULL, /* delete an event */
NULL, /* enable an event */
NULL, /* disable an event */
NULL, /* add an connection */
ngx_iocp_del_connection, /* delete an connection */
NULL, /* trigger a notify */
ngx_iocp_process_events, /* process the events */
ngx_iocp_init, /* init the events */
ngx_iocp_done /* done the events */
}
};
ngx_module_t ngx_iocp_module = {
NGX_MODULE_V1,
&ngx_iocp_module_ctx, /* module context */
ngx_iocp_commands, /* module directives */
NGX_EVENT_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
ngx_os_io_t ngx_iocp_io = {
ngx_overlapped_wsarecv,
NULL,
ngx_udp_overlapped_wsarecv,
NULL,
NULL,
NULL,
ngx_overlapped_wsasend_chain,
0
};
static HANDLE iocp;
static ngx_tid_t timer_thread;
static ngx_msec_t msec;
static ngx_int_t
ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer)
{
ngx_iocp_conf_t *cf;
cf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
if (iocp == NULL) {
iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
cf->threads);
}
if (iocp == NULL) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"CreateIoCompletionPort() failed");
return NGX_ERROR;
}
ngx_io = ngx_iocp_io;
ngx_event_actions = ngx_iocp_module_ctx.actions;
ngx_event_flags = NGX_USE_IOCP_EVENT;
if (timer == 0) {
return NGX_OK;
}
/*
* The waitable timer could not be used, because
* GetQueuedCompletionStatus() does not set a thread to alertable state
*/
if (timer_thread == NULL) {
msec = timer;
if (ngx_create_thread(&timer_thread, ngx_iocp_timer, &msec, cycle->log)
!= 0)
{
return NGX_ERROR;
}
}
ngx_event_flags |= NGX_USE_TIMER_EVENT;
return NGX_OK;
}
static ngx_thread_value_t __stdcall
ngx_iocp_timer(void *data)
{
ngx_msec_t timer = *(ngx_msec_t *) data;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
"THREAD %p %p", &msec, data);
for ( ;; ) {
Sleep(timer);
ngx_time_update();
#if 1
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer");
#endif
}
#if defined(__WATCOMC__) || defined(__GNUC__)
return 0;
#endif
}
static void
ngx_iocp_done(ngx_cycle_t *cycle)
{
if (CloseHandle(iocp) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"iocp CloseHandle() failed");
}
iocp = NULL;
}
static ngx_int_t
ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t key)
{
ngx_connection_t *c;
c = (ngx_connection_t *) ev->data;
c->read->active = 1;
c->write->active = 1;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"iocp add: fd:%d k:%ui ov:%p", c->fd, key, &ev->ovlp);
if (CreateIoCompletionPort((HANDLE) c->fd, iocp, key, 0) == NULL) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"CreateIoCompletionPort() failed");
return NGX_ERROR;
}
return NGX_OK;
}
static ngx_int_t
ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags)
{
#if 0
if (flags & NGX_CLOSE_EVENT) {
return NGX_OK;
}
if (CancelIo((HANDLE) c->fd) == 0) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "CancelIo() failed");
return NGX_ERROR;
}
#endif
return NGX_OK;
}
static ngx_int_t
ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
{
int rc;
u_int key;
u_long bytes;
ngx_err_t err;
ngx_msec_t delta;
ngx_event_t *ev;
ngx_event_ovlp_t *ovlp;
if (timer == NGX_TIMER_INFINITE) {
timer = INFINITE;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "iocp timer: %M", timer);
rc = GetQueuedCompletionStatus(iocp, &bytes, (PULONG_PTR) &key,
(LPOVERLAPPED *) &ovlp, (u_long) timer);
if (rc == 0) {
err = ngx_errno;
} else {
err = 0;
}
delta = ngx_current_msec;
if (flags & NGX_UPDATE_TIME) {
ngx_time_update();
}
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"iocp: %d b:%d k:%d ov:%p", rc, bytes, key, ovlp);
if (timer != INFINITE) {
delta = ngx_current_msec - delta;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"iocp timer: %M, delta: %M", timer, delta);
}
if (err) {
if (ovlp == NULL) {
if (err != WAIT_TIMEOUT) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
"GetQueuedCompletionStatus() failed");
return NGX_ERROR;
}
return NGX_OK;
}
ovlp->error = err;
}
if (ovlp == NULL) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"GetQueuedCompletionStatus() returned no operation");
return NGX_ERROR;
}
ev = ovlp->event;
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err, "iocp event:%p", ev);
if (err == ERROR_NETNAME_DELETED /* the socket was closed */
|| err == ERROR_OPERATION_ABORTED /* the operation was canceled */)
{
/*
* the WSA_OPERATION_ABORTED completion notification
* for a file descriptor that was closed
*/
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err,
"iocp: aborted event %p", ev);
return NGX_OK;
}
if (err) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
"GetQueuedCompletionStatus() returned operation error");
}
switch (key) {
case NGX_IOCP_ACCEPT:
if (bytes) {
ev->ready = 1;
}
break;
case NGX_IOCP_IO:
ev->complete = 1;
ev->ready = 1;
break;
case NGX_IOCP_CONNECT:
ev->ready = 1;
}
ev->available = bytes;
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"iocp event handler: %p", ev->handler);
ev->handler(ev);
return NGX_OK;
}
static void *
ngx_iocp_create_conf(ngx_cycle_t *cycle)
{
ngx_iocp_conf_t *cf;
cf = ngx_palloc(cycle->pool, sizeof(ngx_iocp_conf_t));
if (cf == NULL) {
return NULL;
}
cf->threads = NGX_CONF_UNSET;
cf->post_acceptex = NGX_CONF_UNSET;
cf->acceptex_read = NGX_CONF_UNSET;
return cf;
}
static char *
ngx_iocp_init_conf(ngx_cycle_t *cycle, void *conf)
{
ngx_iocp_conf_t *cf = conf;
ngx_conf_init_value(cf->threads, 0);
ngx_conf_init_value(cf->post_acceptex, 10);
ngx_conf_init_value(cf->acceptex_read, 1);
return NGX_CONF_OK;
}
-22
View File
@@ -1,22 +0,0 @@
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#ifndef _NGX_IOCP_MODULE_H_INCLUDED_
#define _NGX_IOCP_MODULE_H_INCLUDED_
typedef struct {
int threads;
int post_acceptex;
int acceptex_read;
} ngx_iocp_conf_t;
extern ngx_module_t ngx_iocp_module;
#endif /* _NGX_IOCP_MODULE_H_INCLUDED_ */
+7 -37
View File
@@ -338,8 +338,6 @@ ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
}
}
/* iocp */
return NGX_OK;
}
@@ -423,8 +421,6 @@ ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
}
}
/* iocp */
return NGX_OK;
}
@@ -831,9 +827,7 @@ ngx_event_process_init(ngx_cycle_t *cycle)
rev->deferred_accept = ls[i].deferred_accept;
#endif
if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)
&& cycle->old_cycle)
{
if (cycle->old_cycle) {
if (ls[i].previous) {
/*
@@ -855,38 +849,14 @@ ngx_event_process_init(ngx_cycle_t *cycle)
#if (NGX_WIN32)
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
ngx_iocp_conf_t *iocpcf;
rev->handler = ngx_event_accept;
rev->handler = ngx_event_acceptex;
if (ngx_use_accept_mutex) {
continue;
}
if (ngx_use_accept_mutex) {
continue;
}
if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
return NGX_ERROR;
}
ls[i].log.handler = ngx_acceptex_log_error;
iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex)
== NGX_ERROR)
{
return NGX_ERROR;
}
} else {
rev->handler = ngx_event_accept;
if (ngx_use_accept_mutex) {
continue;
}
if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
return NGX_ERROR;
}
if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
return NGX_ERROR;
}
#else
-41
View File
@@ -16,17 +16,6 @@
#define NGX_INVALID_INDEX 0xd0d0d0d0
#if (NGX_HAVE_IOCP)
typedef struct {
WSAOVERLAPPED ovlp;
ngx_event_t *event;
int error;
} ngx_event_ovlp_t;
#endif
struct ngx_event_s {
void *data;
@@ -92,8 +81,6 @@ struct ngx_event_s {
* write: available space in buffer when event is ready
* or lowat when event is set with NGX_LOWAT_EVENT flag
*
* iocp: TODO
*
* otherwise:
* accept: 1 if accept many, 0 otherwise
* read: bytes to read when event is ready, -1 if not known
@@ -103,11 +90,6 @@ struct ngx_event_s {
ngx_event_handler_pt handler;
#if (NGX_HAVE_IOCP)
ngx_event_ovlp_t ovlp;
#endif
ngx_uint_t index;
ngx_log_t *log;
@@ -240,11 +222,6 @@ extern ngx_uint_t ngx_use_epoll_rdhup;
*/
#define NGX_USE_AIO_EVENT 0x00000100
/*
* Need to add socket or handle only once: i/o completion port.
*/
#define NGX_USE_IOCP_EVENT 0x00000200
/*
* The event filter has no opaque data and requires file descriptors table:
* poll, /dev/poll.
@@ -381,13 +358,6 @@ extern ngx_uint_t ngx_use_epoll_rdhup;
#endif /* NGX_HAVE_KQUEUE */
#if (NGX_HAVE_IOCP)
#define NGX_IOCP_ACCEPT 0
#define NGX_IOCP_IO 1
#define NGX_IOCP_CONNECT 2
#endif
#if (NGX_TEST_BUILD_EPOLL)
#define NGX_EXCLUSIVE_EVENT 0
#endif
@@ -508,13 +478,6 @@ ngx_int_t ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags);
ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat);
#if (NGX_WIN32)
void ngx_event_acceptex(ngx_event_t *ev);
ngx_int_t ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n);
u_char *ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len);
#endif
ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat);
@@ -526,9 +489,5 @@ ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat);
#include <ngx_event_posted.h>
#include <ngx_event_udp.h>
#if (NGX_WIN32)
#include <ngx_iocp_module.h>
#endif
#endif /* _NGX_EVENT_H_INCLUDED_ */
+6 -24
View File
@@ -180,26 +180,12 @@ ngx_event_accept(ngx_event_t *ev)
return;
}
/* set a blocking mode for iocp and non-blocking mode for others */
if (ngx_inherited_nonblocking) {
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
if (ngx_blocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_blocking_n " failed");
ngx_close_accepted_connection(c);
return;
}
}
} else {
if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
if (ngx_nonblocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_nonblocking_n " failed");
ngx_close_accepted_connection(c);
return;
}
if (!ngx_inherited_nonblocking) {
if (ngx_nonblocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_nonblocking_n " failed");
ngx_close_accepted_connection(c);
return;
}
}
@@ -251,10 +237,6 @@ ngx_event_accept(ngx_event_t *ev)
wev->ready = 1;
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
rev->ready = 1;
}
if (ev->deferred_accept) {
rev->ready = 1;
#if (NGX_HAVE_KQUEUE || NGX_HAVE_EPOLLRDHUP)
-229
View File
@@ -1,229 +0,0 @@
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
static void ngx_close_posted_connection(ngx_connection_t *c);
void
ngx_event_acceptex(ngx_event_t *rev)
{
ngx_listening_t *ls;
ngx_connection_t *c;
c = rev->data;
ls = c->listening;
c->log->handler = ngx_accept_log_error;
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "AcceptEx: %d", c->fd);
if (rev->ovlp.error) {
ngx_log_error(NGX_LOG_CRIT, c->log, rev->ovlp.error,
"AcceptEx() %V failed", &ls->addr_text);
return;
}
/* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */
if (setsockopt(c->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char *) &ls->fd, sizeof(ngx_socket_t))
== -1)
{
ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
"setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed for %V",
&c->addr_text);
/* TODO: close socket */
return;
}
ngx_getacceptexsockaddrs(c->buffer->pos,
ls->post_accept_buffer_size,
ls->socklen + 16,
ls->socklen + 16,
&c->local_sockaddr, &c->local_socklen,
&c->sockaddr, &c->socklen);
if (ls->post_accept_buffer_size) {
c->buffer->last += rev->available;
c->buffer->end = c->buffer->start + ls->post_accept_buffer_size;
} else {
c->buffer = NULL;
}
if (ls->addr_ntop) {
c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len);
if (c->addr_text.data == NULL) {
/* TODO: close socket */
return;
}
c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen,
c->addr_text.data,
ls->addr_text_max_len, 0);
if (c->addr_text.len == 0) {
/* TODO: close socket */
return;
}
}
ngx_event_post_acceptex(ls, 1);
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
c->start_time = ngx_current_msec;
ls->handler(c);
return;
}
ngx_int_t
ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n)
{
u_long rcvd;
ngx_err_t err;
ngx_log_t *log;
ngx_uint_t i;
ngx_event_t *rev, *wev;
ngx_socket_t s;
ngx_connection_t *c;
for (i = 0; i < n; i++) {
/* TODO: look up reused sockets */
s = ngx_socket(ls->sockaddr->sa_family, ls->type, 0);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &ls->log, 0,
ngx_socket_n " s:%d", s);
if (s == (ngx_socket_t) -1) {
ngx_log_error(NGX_LOG_ALERT, &ls->log, ngx_socket_errno,
ngx_socket_n " failed");
return NGX_ERROR;
}
c = ngx_get_connection(s, &ls->log);
if (c == NULL) {
return NGX_ERROR;
}
c->pool = ngx_create_pool(ls->pool_size, &ls->log);
if (c->pool == NULL) {
ngx_close_posted_connection(c);
return NGX_ERROR;
}
log = ngx_palloc(c->pool, sizeof(ngx_log_t));
if (log == NULL) {
ngx_close_posted_connection(c);
return NGX_ERROR;
}
c->buffer = ngx_create_temp_buf(c->pool, ls->post_accept_buffer_size
+ 2 * (ls->socklen + 16));
if (c->buffer == NULL) {
ngx_close_posted_connection(c);
return NGX_ERROR;
}
c->local_sockaddr = ngx_palloc(c->pool, ls->socklen);
if (c->local_sockaddr == NULL) {
ngx_close_posted_connection(c);
return NGX_ERROR;
}
c->sockaddr = ngx_palloc(c->pool, ls->socklen);
if (c->sockaddr == NULL) {
ngx_close_posted_connection(c);
return NGX_ERROR;
}
*log = ls->log;
c->log = log;
c->recv = ngx_recv;
c->send = ngx_send;
c->recv_chain = ngx_recv_chain;
c->send_chain = ngx_send_chain;
c->listening = ls;
rev = c->read;
wev = c->write;
rev->ovlp.event = rev;
wev->ovlp.event = wev;
rev->handler = ngx_event_acceptex;
rev->ready = 1;
wev->ready = 1;
rev->log = c->log;
wev->log = c->log;
if (ngx_add_event(rev, 0, NGX_IOCP_IO) == NGX_ERROR) {
ngx_close_posted_connection(c);
return NGX_ERROR;
}
if (ngx_acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size,
ls->socklen + 16, ls->socklen + 16,
&rcvd, (LPOVERLAPPED) &rev->ovlp)
== 0)
{
err = ngx_socket_errno;
if (err != WSA_IO_PENDING) {
ngx_log_error(NGX_LOG_ALERT, &ls->log, err,
"AcceptEx() %V failed", &ls->addr_text);
ngx_close_posted_connection(c);
return NGX_ERROR;
}
}
}
return NGX_OK;
}
static void
ngx_close_posted_connection(ngx_connection_t *c)
{
ngx_socket_t fd;
ngx_free_connection(c);
fd = c->fd;
c->fd = (ngx_socket_t) -1;
if (ngx_close_socket(fd) == -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
if (c->pool) {
ngx_destroy_pool(c->pool);
}
}
u_char *
ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len)
{
return ngx_snprintf(buf, len, " while posting AcceptEx() on %V", log->data);
}
-24
View File
@@ -276,30 +276,6 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
return NGX_OK;
}
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, ngx_socket_errno,
"connect(): %d", rc);
if (ngx_blocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
ngx_blocking_n " failed");
goto failed;
}
/*
* FreeBSD's aio allows to post an operation on non-connected socket.
* NT does not support it.
*
* TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT
*/
rev->ready = 1;
wev->ready = 1;
return NGX_OK;
}
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
/* kqueue */
-206
View File
@@ -1,206 +0,0 @@
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#define NGX_MAX_PENDING_CONN 10
static CRITICAL_SECTION connect_lock;
static int nconnects;
static ngx_connection_t pending_connects[NGX_MAX_PENDING_CONN];
static HANDLE pending_connect_event;
__declspec(thread) int nevents = 0;
__declspec(thread) WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS + 1];
__declspec(thread) ngx_connection_t *conn[WSA_MAXIMUM_WAIT_EVENTS + 1];
int ngx_iocp_wait_connect(ngx_connection_t *c)
{
for ( ;; ) {
EnterCriticalSection(&connect_lock);
if (nconnects < NGX_MAX_PENDING_CONN) {
pending_connects[--nconnects] = c;
LeaveCriticalSection(&connect_lock);
if (SetEvent(pending_connect_event) == 0) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"SetEvent() failed");
return NGX_ERROR;
break;
}
LeaveCriticalSection(&connect_lock);
ngx_log_error(NGX_LOG_NOTICE, c->log, 0,
"max number of pending connect()s is %d",
NGX_MAX_PENDING_CONN);
msleep(100);
}
if (!started) {
if (ngx_iocp_new_thread(1) == NGX_ERROR) {
return NGX_ERROR;
}
started = 1;
}
return NGX_OK;
}
int ngx_iocp_new_thread(int main)
{
u_int id;
if (main) {
pending_connect_event = CreateEvent(NULL, 0, 1, NULL);
if (pending_connect_event == INVALID_HANDLE_VALUE) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"CreateThread() failed");
return NGX_ERROR;
}
}
if (CreateThread(NULL, 0, ngx_iocp_wait_events, main, 0, &id)
== INVALID_HANDLE_VALUE)
{
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"CreateThread() failed");
return NGX_ERROR;
}
SetEvent(event) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"SetEvent() failed");
return NGX_ERROR;
}
return NGX_OK;
}
int ngx_iocp_new_connect()
{
EnterCriticalSection(&connect_lock);
c = pending_connects[--nconnects];
LeaveCriticalSection(&connect_lock);
conn[nevents] = c;
events[nevents] = WSACreateEvent();
if (events[nevents] == INVALID_HANDLE_VALUE) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
"WSACreateEvent() failed");
return NGX_ERROR;
}
if (WSAEventSelect(c->fd, events[nevents], FD_CONNECT) == -1)
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
"WSAEventSelect() failed");
return NGX_ERROR;
}
nevents++;
return NGX_OK;
}
void ngx_iocp_wait_events(int main)
{
WSANETWORKEVENTS ne;
nevents = 1;
events[0] = pending_connect_event;
conn[0] = NULL;
for ( ;; ) {
offset = (nevents == WSA_MAXIMUM_WAIT_EVENTS + 1) ? 1 : 0;
timeout = (nevents == 1 && !first) ? 60000 : INFINITE;
n = WSAWaitForMultipleEvents(nevents - offset, events[offset],
0, timeout, 0);
if (n == WAIT_FAILED) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
"WSAWaitForMultipleEvents() failed");
continue;
}
if (n == WAIT_TIMEOUT) {
if (nevents == 2 && !main) {
ExitThread(0);
}
ngx_log_error(NGX_LOG_ALERT, log, 0,
"WSAWaitForMultipleEvents() "
"returned unexpected WAIT_TIMEOUT");
continue;
}
n -= WSA_WAIT_EVENT_0;
if (events[n] == NULL) {
/* the pending_connect_event */
if (nevents == WSA_MAXIMUM_WAIT_EVENTS) {
ngx_iocp_new_thread(0);
} else {
ngx_iocp_new_connect();
}
continue;
}
if (WSAEnumNetworkEvents(c[n].fd, events[n], &ne) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
"WSAEnumNetworkEvents() failed");
continue;
}
if (ne.lNetworkEvents & FD_CONNECT) {
conn[n].write->ovlp.error = ne.iErrorCode[FD_CONNECT_BIT];
if (PostQueuedCompletionStatus(iocp, 0, NGX_IOCP_CONNECT,
&conn[n].write->ovlp) == 0)
{
ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
"PostQueuedCompletionStatus() failed");
continue;
}
if (n < nevents) {
conn[n] = conn[nevents];
events[n] = events[nevents];
}
nevents--;
continue;
}
if (ne.lNetworkEvents & FD_ACCEPT) {
/* CHECK ERROR ??? */
ngx_event_post_acceptex(conn[n].listening, 1);
continue;
}
ngx_log_error(NGX_LOG_ALERT, c[n].log, 0,
"WSAWaitForMultipleEvents() "
"returned unexpected network event %ul",
ne.lNetworkEvents);
}
}
+2 -16
View File
@@ -226,12 +226,7 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
/* use the free bufs if they exist */
chain = p->free_raw_bufs;
if (p->single_buf) {
p->free_raw_bufs = p->free_raw_bufs->next;
chain->next = NULL;
} else {
p->free_raw_bufs = NULL;
}
p->free_raw_bufs = NULL;
} else if (p->allocated < p->bufs.num) {
@@ -293,12 +288,7 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
}
chain = p->free_raw_bufs;
if (p->single_buf) {
p->free_raw_bufs = p->free_raw_bufs->next;
chain->next = NULL;
} else {
p->free_raw_bufs = NULL;
}
p->free_raw_bufs = NULL;
} else {
@@ -326,10 +316,6 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
}
if (n == NGX_AGAIN) {
if (p->single_buf) {
ngx_event_pipe_remove_shadow_links(chain->buf);
}
break;
}
-1
View File
@@ -56,7 +56,6 @@ struct ngx_event_pipe_s {
unsigned read:1;
unsigned cacheable:1;
unsigned single_buf:1;
unsigned free_bufs:1;
unsigned upstream_done:1;
unsigned upstream_error:1;
-13
View File
@@ -1890,19 +1890,6 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
ls->log.data = &ls->addr_text;
ls->log.handler = ngx_accept_log_error;
#if (NGX_WIN32)
{
ngx_iocp_conf_t *iocpcf = NULL;
if (ngx_get_conf(cf->cycle->conf_ctx, ngx_events_module)) {
iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
}
if (iocpcf && iocpcf->acceptex_read) {
ls->post_accept_buffer_size = cscf->client_header_buffer_size;
}
}
#endif
ls->type = addr->opt.type;
ls->protocol = addr->opt.protocol;
ls->backlog = addr->opt.backlog;
+1 -1
View File
@@ -350,7 +350,7 @@ ngx_http_init_connection(ngx_connection_t *c)
}
if (rev->ready) {
/* the deferred accept(), iocp */
/* the deferred accept() */
if (ngx_use_accept_mutex) {
ngx_post_event(rev, &ngx_posted_events);
-5
View File
@@ -3579,11 +3579,6 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
p->buf_to_file->temporary = 1;
}
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
/* the posted aio operation may corrupt a shadow buffer */
p->single_buf = 1;
}
/* TODO: p->free_bufs = 0 if use ngx_create_chain_of_bufs() */
p->free_bufs = 1;
-2
View File
@@ -54,8 +54,6 @@ ngx_mail_init_connection(ngx_connection_t *c)
* There are several addresses on this port and one of them
* is the "*:port" wildcard so getsockname() is needed to determine
* the server address.
*
* AcceptEx() already gave this address.
*/
if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
-6
View File
@@ -40,17 +40,11 @@ void ngx_os_status(ngx_log_t *log);
ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid);
ssize_t ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
ssize_t ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
ssize_t ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf,
size_t size);
ssize_t ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit);
ssize_t ngx_wsasend(ngx_connection_t *c, u_char *buf, size_t size);
ssize_t ngx_overlapped_wsasend(ngx_connection_t *c, u_char *buf, size_t size);
ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit);
ngx_chain_t *ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in,
off_t limit);
void ngx_cdecl ngx_event_log(ngx_err_t err, const char *fmt, ...);
-98
View File
@@ -49,101 +49,3 @@ ngx_udp_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
return bytes;
}
ssize_t
ngx_udp_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
{
int rc;
u_long bytes, flags;
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, c->log, 0, "second wsa post");
return NGX_AGAIN;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"rev->complete: %d", rev->complete);
if (rev->complete) {
rev->complete = 0;
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
if (rev->ovlp.error) {
ngx_connection_error(c, rev->ovlp.error, "WSARecv() failed");
return NGX_ERROR;
}
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSARecv ovlp: fd:%d %ul of %z",
c->fd, rev->available, size);
return rev->available;
}
if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
&bytes, 0, NULL)
== 0)
{
ngx_connection_error(c, ngx_socket_errno,
"WSARecv() or WSAGetOverlappedResult() failed");
return NGX_ERROR;
}
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSARecv: fd:%d %ul of %z", c->fd, bytes, size);
return bytes;
}
ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
wsabuf[0].buf = (char *) buf;
wsabuf[0].len = size;
flags = 0;
bytes = 0;
rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
rev->complete = 0;
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSARecv ovlp: fd:%d rc:%d %ul of %z",
c->fd, rc, bytes, size);
if (rc == -1) {
err = ngx_socket_errno;
if (err == WSA_IO_PENDING) {
rev->active = 1;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
"WSARecv() posted");
return NGX_AGAIN;
}
rev->error = 1;
ngx_connection_error(c, 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;
}
rev->active = 0;
return bytes;
}
-111
View File
@@ -102,114 +102,3 @@ ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
return bytes;
}
ssize_t
ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size)
{
int rc;
u_long bytes, flags;
WSABUF wsabuf[1];
ngx_err_t err;
ngx_int_t n;
ngx_event_t *rev;
LPWSAOVERLAPPED ovlp;
rev = c->read;
if (!rev->ready) {
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "second wsa post");
return NGX_AGAIN;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"rev->complete: %d", rev->complete);
if (rev->complete) {
rev->complete = 0;
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
if (rev->ovlp.error) {
ngx_connection_error(c, rev->ovlp.error, "WSARecv() failed");
return NGX_ERROR;
}
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSARecv ovlp: fd:%d %ul of %z",
c->fd, rev->available, size);
return rev->available;
}
if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
&bytes, 0, NULL)
== 0)
{
ngx_connection_error(c, ngx_socket_errno,
"WSARecv() or WSAGetOverlappedResult() failed");
return NGX_ERROR;
}
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSARecv: fd:%d %ul of %z", c->fd, bytes, size);
return bytes;
}
ovlp = (LPWSAOVERLAPPED) &rev->ovlp;
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
wsabuf[0].buf = (char *) buf;
wsabuf[0].len = size;
flags = 0;
bytes = 0;
rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
rev->complete = 0;
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSARecv ovlp: fd:%d rc:%d %ul of %z",
c->fd, rc, bytes, size);
if (rc == -1) {
err = ngx_socket_errno;
if (err == WSA_IO_PENDING) {
rev->active = 1;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
"WSARecv() posted");
return NGX_AGAIN;
}
n = ngx_connection_error(c, err, "WSARecv() failed");
if (n == NGX_ERROR) {
rev->error = 1;
}
return n;
}
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;
}
-120
View File
@@ -63,123 +63,3 @@ ngx_wsasend(ngx_connection_t *c, u_char *buf, size_t size)
return NGX_ERROR;
}
ssize_t
ngx_overlapped_wsasend(ngx_connection_t *c, u_char *buf, size_t size)
{
int n;
u_long sent;
ngx_err_t err;
ngx_event_t *wev;
LPWSAOVERLAPPED ovlp;
WSABUF wsabuf;
wev = c->write;
if (!wev->ready) {
return NGX_AGAIN;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"wev->complete: %d", wev->complete);
if (!wev->complete) {
/* post the overlapped WSASend() */
/*
* WSABUFs must be 4-byte aligned otherwise
* WSASend() will return undocumented WSAEINVAL error.
*/
wsabuf.buf = (char *) buf;
wsabuf.len = size;
sent = 0;
ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
n = WSASend(c->fd, &wsabuf, 1, &sent, 0, ovlp, NULL);
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSASend: fd:%d, %d, %ul of %uz", c->fd, n, sent, size);
wev->complete = 0;
if (n == 0) {
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 NGX_AGAIN;
}
if (sent < size) {
wev->ready = 0;
}
c->sent += sent;
return sent;
}
err = ngx_socket_errno;
if (err == WSA_IO_PENDING) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
"WSASend() posted");
wev->active = 1;
return NGX_AGAIN;
}
wev->error = 1;
ngx_connection_error(c, err, "WSASend() failed");
return NGX_ERROR;
}
/* the overlapped WSASend() complete */
wev->complete = 0;
wev->active = 0;
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
if (wev->ovlp.error) {
ngx_connection_error(c, wev->ovlp.error, "WSASend() failed");
return NGX_ERROR;
}
sent = wev->available;
} else {
if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &wev->ovlp,
&sent, 0, NULL)
== 0)
{
ngx_connection_error(c, ngx_socket_errno,
"WSASend() or WSAGetOverlappedResult() failed");
return NGX_ERROR;
}
}
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSAGetOverlappedResult: fd:%d, %ul of %uz",
c->fd, sent, size);
if (sent < size) {
wev->ready = 0;
}
c->sent += sent;
return sent;
}
-167
View File
@@ -127,170 +127,3 @@ ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
}
}
}
ngx_chain_t *
ngx_overlapped_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
{
int rc;
u_char *prev;
u_long size, send, sent;
ngx_err_t err;
ngx_event_t *wev;
ngx_array_t vec;
ngx_chain_t *cl;
LPWSAOVERLAPPED ovlp;
LPWSABUF wsabuf;
WSABUF wsabufs[NGX_WSABUFS];
wev = c->write;
if (!wev->ready) {
return in;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"wev->complete: %d", wev->complete);
if (!wev->complete) {
/* post the overlapped WSASend() */
/* the maximum limit size is the maximum u_long value - the page size */
if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize))
{
limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
}
/*
* WSABUFs must be 4-byte aligned otherwise
* WSASend() will return undocumented WSAEINVAL error.
*/
vec.elts = wsabufs;
vec.nelts = 0;
vec.size = sizeof(WSABUF);
vec.nalloc = ngx_min(NGX_WSABUFS, ngx_max_wsabufs);
vec.pool = c->pool;
send = 0;
prev = NULL;
wsabuf = NULL;
/* create the WSABUF and coalesce the neighbouring bufs */
for (cl = in; cl && send < limit; cl = cl->next) {
if (ngx_buf_special(cl->buf)) {
continue;
}
size = cl->buf->last - cl->buf->pos;
if (send + size > limit) {
size = (u_long) (limit - send);
}
if (prev == cl->buf->pos) {
wsabuf->len += cl->buf->last - cl->buf->pos;
} else {
if (vec.nelts == vec.nalloc) {
break;
}
wsabuf = ngx_array_push(&vec);
if (wsabuf == NULL) {
return NGX_CHAIN_ERROR;
}
wsabuf->buf = (char *) cl->buf->pos;
wsabuf->len = cl->buf->last - cl->buf->pos;
}
prev = cl->buf->last;
send += size;
}
ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
rc = WSASend(c->fd, vec.elts, vec.nelts, &sent, 0, ovlp, NULL);
wev->complete = 0;
if (rc == -1) {
err = ngx_errno;
if (err == WSA_IO_PENDING) {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
"WSASend() posted");
wev->active = 1;
return in;
} else {
wev->error = 1;
ngx_connection_error(c, 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;
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSASend: fd:%d, s:%ul", c->fd, sent);
} else {
/* the overlapped WSASend() complete */
wev->complete = 0;
wev->active = 0;
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
if (wev->ovlp.error) {
ngx_connection_error(c, 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_connection_error(c, ngx_socket_errno,
"WSASend() or WSAGetOverlappedResult() failed");
return NGX_CHAIN_ERROR;
}
}
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"WSASend ovlp: fd:%d, s:%ul", c->fd, sent);
c->sent += sent;
in = ngx_chain_update_sent(in, sent);
if (in) {
wev->ready = 0;
} else {
wev->ready = 1;
}
return in;
}
+1 -1
View File
@@ -50,7 +50,7 @@ ngx_stream_init_connection(ngx_connection_t *c)
* is the "*:port" wildcard so getsockname() is needed to determine
* the server address.
*
* AcceptEx() and recvmsg() already gave this address.
* recvmsg() already gave this address.
*/
if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {