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
esac
-EVENT_MODULES="$EVENT_MODULES $IOCP_MODULE"
-#EVENT_FOUND=YES
-
have=NGX_HAVE_INET6 . auto/have
-
-have=NGX_HAVE_IOCP . auto/have
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"
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"
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
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
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
#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,
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;
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;
#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"
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");
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 */
+++ /dev/null
-
-/*
- * 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;
-}
+++ /dev/null
-
-/*
- * 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_ */
}
}
- /* iocp */
-
return NGX_OK;
}
}
}
- /* iocp */
-
return NGX_OK;
}
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) {
/*
#if (NGX_WIN32)
- if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
- ngx_iocp_conf_t *iocpcf;
-
- rev->handler = ngx_event_acceptex;
+ rev->handler = ngx_event_accept;
- 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_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
#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;
* 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
ngx_event_handler_pt handler;
-
-#if (NGX_HAVE_IOCP)
- ngx_event_ovlp_t ovlp;
-#endif
-
ngx_uint_t index;
ngx_log_t *log;
*/
#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.
#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
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);
#include <ngx_event_posted.h>
#include <ngx_event_udp.h>
-#if (NGX_WIN32)
-#include <ngx_iocp_module.h>
-#endif
-
#endif /* _NGX_EVENT_H_INCLUDED_ */
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;
}
}
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)
+++ /dev/null
-
-/*
- * 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);
-}
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 */
+++ /dev/null
-
-/*
- * 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);
- }
-}
/* 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) {
}
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 (n == NGX_AGAIN) {
- if (p->single_buf) {
- ngx_event_pipe_remove_shadow_links(chain->buf);
- }
-
break;
}
unsigned read:1;
unsigned cacheable:1;
- unsigned single_buf:1;
unsigned free_bufs:1;
unsigned upstream_done:1;
unsigned upstream_error:1;
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;
}
if (rev->ready) {
- /* the deferred accept(), iocp */
+ /* the deferred accept() */
if (ngx_use_accept_mutex) {
ngx_post_event(rev, &ngx_posted_events);
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;
* 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) {
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, ...);
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;
-}
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;
-}
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;
-}
}
}
}
-
-
-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;
-}
* 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) {