mirror of
https://github.com/nginx/nginx.git
synced 2024-11-24 04:49:01 +08:00
nginx-0.0.1-2003-05-21-17:28:21 import
This commit is contained in:
parent
1c13c662f0
commit
fa73aac774
@ -4,218 +4,59 @@
|
||||
|
||||
#include <ngx_auto_config.h>
|
||||
|
||||
/*
|
||||
auto_conf
|
||||
ngx_inline inline __inline __inline__
|
||||
*/
|
||||
|
||||
/* STUB */
|
||||
#if defined __FreeBSD__
|
||||
#include <ngx_freebsd_config.h>
|
||||
|
||||
|
||||
#elif defined __linux__
|
||||
#include <ngx_linux_config.h>
|
||||
|
||||
|
||||
/* Solaris */
|
||||
#elif defined(sun) && (defined(__svr4__) || defined(__SVR4))
|
||||
#include <ngx_solaris_config.h>
|
||||
|
||||
|
||||
#elif defined _WIN32
|
||||
|
||||
/* STUB to allocate a big ngx_connections */
|
||||
#undef FD_SETSIZE
|
||||
#define FD_SETSIZE 1024
|
||||
|
||||
#include <ngx_win32_config.h>
|
||||
|
||||
/* auto_conf */
|
||||
#define NGX_ALIGN (4 - 1)
|
||||
#define NGX_ALIGN_TYPE unsigned
|
||||
|
||||
#define ngx_align(p) (char *) (((NGX_ALIGN_TYPE) p + NGX_ALIGN) & ~NGX_ALIGN)
|
||||
#else /* posix */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Platform specific: array[NGX_INVALID_ARRAY_INDEX] should cause SIGSEGV */
|
||||
/* TODO: platform specific: array[NGX_INVALID_ARRAY_INDEX] must cause SIGSEGV */
|
||||
#define NGX_INVALID_ARRAY_INDEX 0x80000000
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
/* TODO: auto_conf */
|
||||
#define NGX_ALIGN (4 - 1)
|
||||
#define NGX_ALIGN_TYPE (unsigned int)
|
||||
|
||||
#define WIN32 1
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <mswsock.h>
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#define ngx_inline __inline
|
||||
|
||||
|
||||
#ifndef HAVE_INHERITED_NONBLOCK
|
||||
#define HAVE_INHERITED_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WIN32_TRANSMITPACKETS
|
||||
#define HAVE_WIN32_TRANSMITPACKETS 1
|
||||
#define HAVE_WIN32_TRANSMITFILE 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WIN32_TRANSMITFILE
|
||||
#define HAVE_WIN32_TRANSMITFILE 1
|
||||
#endif
|
||||
|
||||
#if (HAVE_WIN32_TRANSMITPACKETS) || (HAVE_WIN32_TRANSMITFILE)
|
||||
#define HAVE_SENDFILE 1
|
||||
#endif
|
||||
|
||||
#else /* POSIX */
|
||||
|
||||
|
||||
|
||||
/* Solaris */
|
||||
#if defined(sun) && (defined(__svr4__) || defined(__SVR4))
|
||||
|
||||
#define SOLARIS 1
|
||||
|
||||
#define _FILE_OFFSET_BITS 64 /* should be before sys/types.h */
|
||||
|
||||
#ifndef HAVE_INHERITED_NONBLOCK
|
||||
#define HAVE_INHERITED_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
#include <sys/stropts.h> /* INFTIM */
|
||||
|
||||
#endif /* Solaris */
|
||||
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/resource.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
|
||||
#ifndef HAVE_POLL
|
||||
#define HAVE_POLL 1
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if (HAVE_DEVPOLL) && !(TEST_DEVPOLL)
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/devpoll.h> /* Solaris, HP/UX */
|
||||
#endif
|
||||
|
||||
|
||||
#if (HAVE_AIO)
|
||||
#include <aio.h>
|
||||
#endif
|
||||
#define ngx_align(p) (char *) ((NGX_ALIGN_TYPE p + NGX_ALIGN) & ~NGX_ALIGN)
|
||||
|
||||
|
||||
/* TODO: auto_conf: ngx_inline inline __inline __inline__ */
|
||||
#ifndef ngx_inline
|
||||
#define ngx_inline inline
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* POSIX */
|
||||
|
||||
|
||||
|
||||
#define LF 10
|
||||
#define CR 13
|
||||
#define CRLF "\x0d\x0a"
|
||||
|
||||
#ifndef INADDR_NONE /* Solaris */
|
||||
#define INADDR_NONE ((unsigned long) -1)
|
||||
#endif
|
||||
|
||||
#ifndef INET_ADDRSTRLEN
|
||||
#define INET_ADDRSTRLEN 16
|
||||
#endif
|
||||
|
||||
|
||||
#if defined SO_ACCEPTFILTER || defined TCP_DEFER_ACCEPT
|
||||
|
||||
#ifndef HAVE_DEFERRED_ACCEPT
|
||||
#define HAVE_DEFERRED_ACCEPT 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_SELECT
|
||||
#define HAVE_SELECT 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#include <osreldate.h>
|
||||
|
||||
#ifndef HAVE_INHERITED_NONBLOCK
|
||||
#define HAVE_INHERITED_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
/* FreeBSD sendfile */
|
||||
#if __FreeBSD_version >= 300007
|
||||
|
||||
#ifndef HAVE_FREEBSD_SENDFILE
|
||||
#define HAVE_FREEBSD_SENDFILE 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FREEBSD_SENDFILE_NBYTES_BUG
|
||||
#define HAVE_FREEBSD_SENDFILE_NBYTES_BUG 2
|
||||
#endif
|
||||
|
||||
#endif /* FreeBSD sendfile */
|
||||
|
||||
/* FreeBSD sendfile nbytes bug */
|
||||
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460100) \
|
||||
|| __FreeBSD_version == 460001 \
|
||||
|| __FreeBSD_version >= 500029
|
||||
|
||||
#if (HAVE_FREEBSD_SENDFILE_NBYTES_BUG == 2)
|
||||
#undef HAVE_FREEBSD_SENDFILE_NBYTES_BUG
|
||||
#define HAVE_FREEBSD_SENDFILE_NBYTES_BUG 0
|
||||
#endif
|
||||
|
||||
#endif /* FreeBSD sendfile nbytes bug */
|
||||
|
||||
#if (HAVE_FREEBSD_SENDFILE)
|
||||
#define HAVE_SENDFILE 1
|
||||
#endif
|
||||
|
||||
|
||||
/* FreeBSD kqueue */
|
||||
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \
|
||||
|| __FreeBSD_version >= 500011
|
||||
|
||||
#ifndef HAVE_KQUEUE
|
||||
#define HAVE_KQUEUE 1
|
||||
#include <sys/event.h>
|
||||
#endif
|
||||
|
||||
/* kqueue's NOTE_LOWAT */
|
||||
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
|
||||
|| __FreeBSD_version >= 500018
|
||||
|
||||
#ifndef HAVE_LOWAT_EVENT
|
||||
#define HAVE_LOWAT_EVENT 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* FreeBSD kqueue */
|
||||
|
||||
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
|
||||
#ifdef __SOME_OS_TEMPLATE__
|
||||
|
||||
#ifndef HAVE_INHERITED_NONBLOCK
|
||||
#define HAVE_INHERITED_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _NGX_CONFIG_H_INCLUDED_ */
|
||||
|
@ -37,6 +37,12 @@ typedef struct ngx_event_s ngx_event_t;
|
||||
*/
|
||||
|
||||
|
||||
#define LF 10
|
||||
#define CR 13
|
||||
#define CRLF "\x0d\x0a"
|
||||
|
||||
|
||||
|
||||
#define NGX_MAXHOSTNAMELEN 32
|
||||
/*
|
||||
#define NGX_MAXHOSTNAMELEN MAXHOSTNAMELEN
|
||||
|
@ -81,7 +81,7 @@ ngx_log_debug(file->log, "temp fd: %d" _ file->fd);
|
||||
|
||||
if (ngx_create_path(file, path) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,9 @@ ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
ngx_hunk_t *ngx_create_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
|
||||
{
|
||||
{
|
||||
ngx_hunk_t *h;
|
||||
|
||||
ngx_test_null(h, ngx_palloc(pool, sizeof(ngx_hunk_t)), NULL);
|
||||
@ -47,7 +47,7 @@ ngx_hunk_t *ngx_create_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
|
||||
|
||||
} else {
|
||||
ngx_test_null(h->pre_start, ngx_palloc(pool, size), NULL);
|
||||
h->start = h->pos = h->last = h->pre_start;
|
||||
h->start = h->pos = h->last = h->pre_start;
|
||||
h->end = h->post_end = h->start + size;
|
||||
h->file_pos = h->file_last = 0;
|
||||
|
||||
@ -84,7 +84,7 @@ ngx_hunk_t *ngx_create_hunk_after(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
|
||||
|
||||
} else {
|
||||
ngx_test_null(h->pre_start, ngx_palloc(pool, size), NULL);
|
||||
h->start = h->pos = h->last = h->pre_start;
|
||||
h->start = h->pos = h->last = h->pre_start;
|
||||
h->end = h->post_end = h->start + size;
|
||||
h->file_pos = h->file_last = 0;
|
||||
|
||||
|
@ -147,7 +147,7 @@ void ngx_log_stderr(ngx_event_t *ev)
|
||||
n = read((ngx_fd_t) ev->data, errstr, sizeof(errstr - 1));
|
||||
|
||||
if (n == -1) {
|
||||
err = ngx_errno;
|
||||
err = ngx_errno;
|
||||
if (err == NGX_EAGAIN) {
|
||||
return;
|
||||
}
|
||||
|
@ -17,6 +17,9 @@ extern ngx_module_t ngx_kqueue_module;
|
||||
#if (HAVE_DEVPOLL)
|
||||
extern ngx_module_t ngx_devpoll_module;
|
||||
#endif
|
||||
#if (HAVE_AIO)
|
||||
extern ngx_module_t ngx_aio_module;
|
||||
#endif
|
||||
|
||||
|
||||
extern ngx_module_t ngx_http_module;
|
||||
@ -47,6 +50,9 @@ ngx_module_t *ngx_modules[] = {
|
||||
#if (HAVE_DEVPOLL)
|
||||
&ngx_devpoll_module,
|
||||
#endif
|
||||
#if (HAVE_AIO)
|
||||
&ngx_aio_module,
|
||||
#endif
|
||||
|
||||
/* http */
|
||||
|
||||
|
@ -4,23 +4,40 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#if 0
|
||||
#include <ngx_connection.h>
|
||||
|
||||
|
||||
#define NGX_IO_SENDFILE 1
|
||||
#define NGX_IO_ZEROCOPY 2
|
||||
|
||||
#if (HAVE_SENDFILE)
|
||||
#define NGX_HAVE_SENDFILE NGX_IO_SENDFILE
|
||||
#else
|
||||
#define NGX_HAVE_SENDFILE 0
|
||||
#endif
|
||||
|
||||
#if (HAVE_ZEROCOPY)
|
||||
#define NGX_HAVE_ZEROCOPY NGX_IO_ZEROCOPY
|
||||
#else
|
||||
#define NGX_HAVE_ZEROCOPY 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
ssize_t (*recv)(ngx_connection_t *c, char *buf, size_t size);
|
||||
void *dummy_recv_chain;
|
||||
void *dummy_send;
|
||||
ngx_chain_t *(*send_chain)(ngx_connection_t *c, ngx_chain_t *in);
|
||||
int flags;
|
||||
} ngx_os_io_t;
|
||||
|
||||
|
||||
int ngx_os_init(ngx_log_t *log);
|
||||
|
||||
|
||||
extern ngx_os_io_t ngx_os_io;
|
||||
extern int ngx_max_sockets;
|
||||
extern int ngx_inherited_nonblocking;
|
||||
|
||||
|
||||
#endif /* _NGX_OS_INIT_H_INCLUDED_ */
|
||||
|
@ -1,39 +1,109 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_types.h>
|
||||
#include <ngx_log.h>
|
||||
#include <ngx_connection.h>
|
||||
#include <ngx_event.h>
|
||||
#include <ngx_event_timer.h>
|
||||
#include <ngx_aio.h>
|
||||
|
||||
#if (HAVE_KQUEUE)
|
||||
#include <ngx_kqueue_module.h>
|
||||
#endif
|
||||
|
||||
|
||||
int ngx_aio_init(int max_connections, ngx_log_t *log)
|
||||
{
|
||||
static int ngx_aio_init(ngx_log_t *log);
|
||||
static void ngx_aio_done(ngx_log_t *log);
|
||||
static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags);
|
||||
static int ngx_aio_process_events(ngx_log_t *log);
|
||||
|
||||
|
||||
ngx_os_io_t ngx_os_aio = {
|
||||
ngx_aio_read,
|
||||
NULL,
|
||||
ngx_aio_write,
|
||||
ngx_aio_write_chain,
|
||||
NGX_HAVE_ZEROCOPY
|
||||
};
|
||||
|
||||
|
||||
static ngx_str_t aio_name = ngx_string("aio");
|
||||
|
||||
ngx_event_module_t ngx_aio_module_ctx = {
|
||||
NGX_EVENT_MODULE,
|
||||
&aio_name,
|
||||
NULL, /* create configuration */
|
||||
NULL, /* init configuration */
|
||||
|
||||
{
|
||||
ngx_aio_add_event, /* add an event */
|
||||
ngx_aio_del_event, /* delete an event */
|
||||
NULL, /* enable an event */
|
||||
NULL, /* disable an event */
|
||||
NULL, /* add an connection */
|
||||
NULL, /* delete an connection */
|
||||
ngx_aio_process_events, /* process the events */
|
||||
ngx_aio_init, /* init the events */
|
||||
ngx_aio_done /* done the events */
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ngx_module_t ngx_aio_module = {
|
||||
&ngx_aio_module_ctx, /* module context */
|
||||
0, /* module index */
|
||||
NULL, /* module directives */
|
||||
NGX_EVENT_MODULE_TYPE, /* module type */
|
||||
NULL /* init module */
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if (HAVE_KQUEUE)
|
||||
|
||||
int rc;
|
||||
|
||||
rc = ngx_kqueue_init(max_connections, log);
|
||||
static int ngx_aio_init(ngx_log_t *log)
|
||||
{
|
||||
if (ngx_kqueue_module_ctx.actions.init(log) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_USE_AIO_EVENT;
|
||||
ngx_write_chain_proc = ngx_aio_write_chain;
|
||||
ngx_event_actions = ngx_aio_module_ctx.actions;
|
||||
ngx_io = ngx_os_aio;
|
||||
|
||||
return rc;
|
||||
|
||||
#endif
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void ngx_aio_done(ngx_log_t *log)
|
||||
{
|
||||
ngx_kqueue_module_ctx.actions.done(log);
|
||||
}
|
||||
|
||||
|
||||
/* The event adding and deleteing are needed for the listening sockets */
|
||||
|
||||
static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags)
|
||||
{
|
||||
return ngx_kqueue_module_ctx.actions.add(ev, event, flags);
|
||||
}
|
||||
|
||||
|
||||
static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags)
|
||||
{
|
||||
return ngx_kqueue_module_ctx.actions.del(ev, event, flags);
|
||||
}
|
||||
|
||||
|
||||
static int ngx_aio_process_events(ngx_log_t *log)
|
||||
{
|
||||
return ngx_kqueue_module_ctx.actions.process(log);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* 1 */
|
||||
int ngx_posix_aio_process_events(ngx_log_t *log)
|
||||
{
|
||||
@ -66,6 +136,7 @@ int ngx_posix_aio_process_events(ngx_log_t *log)
|
||||
/* 3 */
|
||||
int ngx_posix_aio_process_events(ngx_log_t *log)
|
||||
{
|
||||
#if 0
|
||||
unmask signal
|
||||
|
||||
/* BUG: AIO signal can be delivered before select() */
|
||||
@ -73,6 +144,9 @@ int ngx_posix_aio_process_events(ngx_log_t *log)
|
||||
select(listen);
|
||||
|
||||
mask signal
|
||||
#endif
|
||||
|
||||
pselect(listen, mask);
|
||||
|
||||
if (ngx_socket_errno == NGX_EINTR)
|
||||
look ready array
|
||||
@ -82,4 +156,5 @@ void aio_sig_handler(int signo, siginfo_t *siginfo, void *context)
|
||||
{
|
||||
push siginfo->si_value.sival_ptr
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <ngx_event.h>
|
||||
|
||||
|
||||
#if (TEST_DEVPOLL)
|
||||
#if (TEST_BUILD_DEVPOLL)
|
||||
|
||||
/* Solaris declarations */
|
||||
|
||||
|
@ -66,7 +66,7 @@ ngx_event_module_t ngx_kqueue_module_ctx = {
|
||||
NULL, /* delete an connection */
|
||||
ngx_kqueue_process_events, /* process the events */
|
||||
ngx_kqueue_init, /* init the events */
|
||||
ngx_kqueue_done, /* done the events */
|
||||
ngx_kqueue_done /* done the events */
|
||||
}
|
||||
|
||||
};
|
||||
@ -343,22 +343,23 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
|
||||
}
|
||||
|
||||
ev = (ngx_event_t *) event_list[i].udata;
|
||||
instance = (uintptr_t) ev & 1;
|
||||
ev = (void *) ((uintptr_t) ev & ~1);
|
||||
|
||||
/* It's a stale event from a file descriptor
|
||||
that was just closed in this iteration */
|
||||
|
||||
if (ev->active == 0 || ev->instance != instance) {
|
||||
ngx_log_debug(log, "stale kevent");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (event_list[i].filter) {
|
||||
|
||||
case EVFILT_READ:
|
||||
case EVFILT_WRITE:
|
||||
|
||||
instance = (uintptr_t) ev & 1;
|
||||
ev = (void *) ((uintptr_t) ev & ~1);
|
||||
|
||||
/* It's a stale event from a file descriptor
|
||||
that was just closed in this iteration */
|
||||
|
||||
if (ev->active == 0 || ev->instance != instance) {
|
||||
ngx_log_debug(log, "stale kevent");
|
||||
continue;
|
||||
}
|
||||
|
||||
ev->available = event_list[i].data;
|
||||
|
||||
if (event_list[i].flags & EV_EOF) {
|
||||
|
@ -9,6 +9,8 @@ typedef struct {
|
||||
|
||||
|
||||
extern int ngx_kqueue;
|
||||
/* STUB */ extern ngx_event_module_t ngx_kqueue_module_ctx;
|
||||
|
||||
|
||||
|
||||
#endif /* _NGX_KQUEUE_MODULE_H_INCLUDED_ */
|
||||
|
@ -31,7 +31,7 @@ extern ngx_event_module_t ngx_devpoll_module_ctx;
|
||||
|
||||
|
||||
static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
|
||||
static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
|
||||
static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
|
||||
static void *ngx_event_create_conf(ngx_pool_t *pool);
|
||||
static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf);
|
||||
|
||||
@ -84,9 +84,9 @@ static ngx_command_t ngx_event_commands[] = {
|
||||
offsetof(ngx_event_conf_t, connections),
|
||||
NULL},
|
||||
|
||||
{ngx_string("type"),
|
||||
{ngx_string("use"),
|
||||
NGX_EVENT_CONF|NGX_CONF_TAKE1,
|
||||
ngx_event_set_type,
|
||||
ngx_event_use,
|
||||
0,
|
||||
0,
|
||||
NULL},
|
||||
@ -135,7 +135,7 @@ int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
|
||||
ecf = ngx_event_get_conf(ngx_event_module_ctx);
|
||||
|
||||
ngx_log_debug(log, "CONN: %d" _ ecf->connections);
|
||||
ngx_log_debug(log, "TYPE: %d" _ ecf->type);
|
||||
ngx_log_debug(log, "TYPE: %d" _ ecf->use);
|
||||
|
||||
for (m = 0; ngx_modules[m]; m++) {
|
||||
if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) {
|
||||
@ -143,7 +143,7 @@ ngx_log_debug(log, "TYPE: %d" _ ecf->type);
|
||||
}
|
||||
|
||||
module = ngx_modules[m]->ctx;
|
||||
if (module->index == ecf->type) {
|
||||
if (module->index == ecf->use) {
|
||||
if (module->actions.init(log) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -317,7 +317,7 @@ static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
|
||||
}
|
||||
|
||||
|
||||
static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
|
||||
static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
|
||||
{
|
||||
ngx_event_conf_t *ecf = (ngx_event_conf_t *) conf;
|
||||
|
||||
@ -325,8 +325,8 @@ static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
|
||||
ngx_str_t *args;
|
||||
ngx_event_module_t *module;
|
||||
|
||||
if (ecf->type != NGX_CONF_UNSET) {
|
||||
return "duplicate event type" ;
|
||||
if (ecf->use != NGX_CONF_UNSET) {
|
||||
return "is duplicate" ;
|
||||
}
|
||||
|
||||
args = cf->args->elts;
|
||||
@ -339,7 +339,7 @@ static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
|
||||
module = ngx_modules[m]->ctx;
|
||||
if (module->name->len == args[1].len) {
|
||||
if (ngx_strcmp(module->name->data, args[1].data) == 0) {
|
||||
ecf->type = module->index;
|
||||
ecf->use = module->index;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
}
|
||||
@ -358,7 +358,7 @@ static void *ngx_event_create_conf(ngx_pool_t *pool)
|
||||
|
||||
ecf->connections = NGX_CONF_UNSET;
|
||||
ecf->timer_queues = NGX_CONF_UNSET;
|
||||
ecf->type = NGX_CONF_UNSET;
|
||||
ecf->use = NGX_CONF_UNSET;
|
||||
|
||||
return ecf;
|
||||
}
|
||||
@ -380,19 +380,19 @@ static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf)
|
||||
#endif
|
||||
|
||||
ngx_conf_init_value(ecf->connections, DEF_CONNECTIONS);
|
||||
ngx_conf_init_value(ecf->type, ngx_kqueue_module_ctx.index);
|
||||
ngx_conf_init_value(ecf->use, ngx_kqueue_module_ctx.index);
|
||||
|
||||
#elif (HAVE_DEVPOLL)
|
||||
|
||||
ngx_conf_init_value(ecf->connections, DEF_CONNECTIONS);
|
||||
ngx_conf_init_value(ecf->type, ngx_devpoll_module_ctx.index);
|
||||
ngx_conf_init_value(ecf->use, ngx_devpoll_module_ctx.index);
|
||||
|
||||
#else /* HAVE_SELECT */
|
||||
|
||||
ngx_conf_init_value(ecf->connections,
|
||||
FD_SETSIZE < DEF_CONNECTIONS ? FD_SETSIZE : DEF_CONNECTIONS);
|
||||
|
||||
ngx_conf_init_value(ecf->type, ngx_select_module_ctx.index);
|
||||
ngx_conf_init_value(ecf->use, ngx_select_module_ctx.index);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -327,7 +327,7 @@ extern int ngx_event_flags;
|
||||
typedef struct {
|
||||
int connections;
|
||||
int timer_queues;
|
||||
int type;
|
||||
int use;
|
||||
} ngx_event_conf_t;
|
||||
|
||||
|
||||
|
@ -65,39 +65,28 @@ void ngx_event_accept(ngx_event_t *ev)
|
||||
return;
|
||||
}
|
||||
|
||||
/* set a blocking mode for aio and non-blocking mode for others */
|
||||
|
||||
#if (HAVE_INHERITED_NONBLOCK)
|
||||
if (ngx_inherited_nonblocking) {
|
||||
if ((ngx_event_flags & NGX_USE_AIO_EVENT)) {
|
||||
if (ngx_blocking(s) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
|
||||
ngx_blocking_n " %s failed",
|
||||
ls->addr_text.data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if (HAVE_AIO_EVENT)
|
||||
if ((ngx_event_flags & NGX_HAVE_AIO_EVENT)) {
|
||||
if (ngx_blocking(s) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
|
||||
ngx_blocking_n " %s failed", ls->addr_text.data);
|
||||
return;
|
||||
} else {
|
||||
if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) {
|
||||
if (ngx_nonblocking(s) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
|
||||
ngx_nonblocking_n " %s failed",
|
||||
ls->addr_text.data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* !HAVE_INHERITED_NONBLOCK */
|
||||
|
||||
#if (HAVE_AIO_EVENT)
|
||||
if (!(ngx_event_flags & NGX_HAVE_AIO_EVENT)) {
|
||||
if (ngx_nonblocking(s) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
|
||||
ngx_nonblocking_n " %s failed", ls->addr_text.data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (ngx_nonblocking(s) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
|
||||
ngx_nonblocking_n " %s failed", ls->addr_text.data);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_INHERITED_NONBLOCK */
|
||||
|
||||
|
||||
rev = &ngx_read_events[s];
|
||||
wev = &ngx_write_events[s];
|
||||
@ -130,15 +119,9 @@ void ngx_event_accept(ngx_event_t *ev)
|
||||
c->unexpected_eof = 1;
|
||||
wev->write = 1;
|
||||
|
||||
#if (USE_KQUEUE)
|
||||
wev->ready = 1;
|
||||
#else
|
||||
if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) {
|
||||
wev->ready = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* STUB ? */ wev->timer = rev->timer = 10000;
|
||||
|
||||
c->ctx = ls->ctx;
|
||||
c->servers = ls->servers;
|
||||
@ -174,17 +157,10 @@ void ngx_event_accept(ngx_event_t *ev)
|
||||
|
||||
ls->handler(c);
|
||||
|
||||
#if (USE_KQUEUE)
|
||||
|
||||
ev->available--;
|
||||
|
||||
#elif (HAVE_KQUEUE)
|
||||
|
||||
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
|
||||
ev->available--;
|
||||
}
|
||||
|
||||
#endif
|
||||
} while (ev->available);
|
||||
|
||||
return;
|
||||
|
@ -29,6 +29,22 @@ int ngx_event_acceptex(ngx_event_t *ev)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* can we do SO_UPDATE_ACCEPT_CONTEXT just before shutdown() ???
|
||||
or AcceptEx's context will be lost ??? */
|
||||
|
||||
/* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */
|
||||
if (setsockopt(context->accept_socket, SOL_SOCKET,
|
||||
SO_UPDATE_ACCEPT_CONTEXT, (char *)&nsd,
|
||||
sizeof(nsd))) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, WSAGetLastError(), server_conf,
|
||||
"setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed.");
|
||||
|
||||
/* non fatal - we can not only do lingering close */
|
||||
|
||||
#endif
|
||||
|
||||
getacceptexsockaddrs(c->data, 0,
|
||||
c->socklen + 16, c->socklen + 16,
|
||||
&c->local_sockaddr, &c->local_socklen,
|
||||
|
@ -134,6 +134,13 @@ static ngx_command_t ngx_http_core_commands[] = {
|
||||
offsetof(ngx_http_core_loc_conf_t, send_timeout),
|
||||
NULL},
|
||||
|
||||
{ngx_string("keepalive_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_loc_conf_t, keepalive_timeout),
|
||||
NULL},
|
||||
|
||||
{ngx_string("lingering_time"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
@ -912,6 +919,7 @@ static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool)
|
||||
|
||||
lcf->send_timeout = NGX_CONF_UNSET;
|
||||
lcf->discarded_buffer_size = NGX_CONF_UNSET;
|
||||
lcf->keepalive_timeout = NGX_CONF_UNSET;
|
||||
lcf->lingering_time = NGX_CONF_UNSET;
|
||||
lcf->lingering_timeout = NGX_CONF_UNSET;
|
||||
|
||||
@ -981,6 +989,8 @@ static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool,
|
||||
|
||||
ngx_conf_merge_size_value(conf->discarded_buffer_size,
|
||||
prev->discarded_buffer_size, 1500);
|
||||
ngx_conf_merge_msec_value(conf->keepalive_timeout, prev->keepalive_timeout,
|
||||
70000);
|
||||
ngx_conf_merge_msec_value(conf->lingering_time, prev->lingering_time,
|
||||
30000);
|
||||
ngx_conf_merge_msec_value(conf->lingering_timeout, prev->lingering_timeout,
|
||||
|
@ -100,6 +100,7 @@ typedef struct {
|
||||
ngx_msec_t send_timeout; /* send_timeout */
|
||||
size_t send_lowat; /* send_lowa */
|
||||
size_t discarded_buffer_size; /* discarded_buffer_size */
|
||||
ngx_msec_t keepalive_timeout; /* keepalive_timeout */
|
||||
ngx_msec_t lingering_time; /* lingering_time */
|
||||
ngx_msec_t lingering_timeout; /* lingering_timeout */
|
||||
|
||||
|
@ -996,6 +996,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r)
|
||||
ngx_connection_t *c;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = (ngx_connection_t *) r->connection;
|
||||
rev = c->read;
|
||||
@ -1004,6 +1005,17 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r)
|
||||
ctx->action = "closing request";
|
||||
ngx_http_close_request(r, 0);
|
||||
|
||||
if (rev->timer_set) {
|
||||
ngx_del_timer(rev);
|
||||
} else {
|
||||
rev->timer_set = 1;
|
||||
}
|
||||
|
||||
clcf = (ngx_http_core_loc_conf_t *)
|
||||
ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
|
||||
|
||||
ngx_add_timer(rev, clcf->keepalive_timeout);
|
||||
|
||||
if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
|
||||
ngx_http_close_connection(c);
|
||||
|
13
src/os/unix/ngx_aio.h
Normal file
13
src/os/unix/ngx_aio.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef _NGX_AIO_H_INCLUDED_
|
||||
#define _NGX_AIO_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size);
|
||||
ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size);
|
||||
ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in);
|
||||
|
||||
|
||||
#endif /* _NGX_AIO_H_INCLUDED_ */
|
110
src/os/unix/ngx_aio_read.c
Normal file
110
src/os/unix/ngx_aio_read.c
Normal file
@ -0,0 +1,110 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_aio.h>
|
||||
|
||||
#if (HAVE_KQUEUE)
|
||||
#include <ngx_kqueue_module.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
The data is ready - 3 syscalls:
|
||||
aio_read(), aio_error(), aio_return()
|
||||
The data is not ready - 4 (kqueue) or 5 syscalls:
|
||||
aio_read(), aio_error(), notifiction,
|
||||
aio_error(), aio_return()
|
||||
aio_cancel(), aio_error()
|
||||
*/
|
||||
|
||||
|
||||
ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
|
||||
{
|
||||
int rc, first, canceled;
|
||||
ngx_event_t *ev;
|
||||
|
||||
ev = c->read;
|
||||
|
||||
canceled = 0;
|
||||
|
||||
if (ev->timedout) {
|
||||
ngx_set_socket_errno(NGX_ETIMEDOUT);
|
||||
ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_read() timed out");
|
||||
|
||||
rc = aio_cancel(c->fd, &ev->aiocb);
|
||||
if (rc == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
|
||||
"aio_cancel() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug(ev->log, "aio_cancel: %d" _ rc);
|
||||
|
||||
canceled = 1;
|
||||
|
||||
ev->ready = 1;
|
||||
}
|
||||
|
||||
first = 0;
|
||||
|
||||
if (!ev->ready) {
|
||||
ngx_memzero(&ev->aiocb, sizeof(struct aiocb));
|
||||
|
||||
ev->aiocb.aio_fildes = c->fd;
|
||||
ev->aiocb.aio_buf = buf;
|
||||
ev->aiocb.aio_nbytes = size;
|
||||
|
||||
#if (HAVE_KQUEUE)
|
||||
ev->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
|
||||
ev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
|
||||
ev->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev;
|
||||
#endif
|
||||
|
||||
if (aio_read(&ev->aiocb) == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
|
||||
"aio_read() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug(ev->log, "aio_read: OK");
|
||||
|
||||
ev->active = 1;
|
||||
first = 1;
|
||||
}
|
||||
|
||||
ev->ready = 0;
|
||||
|
||||
rc = aio_error(&ev->aiocb);
|
||||
if (rc == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_error() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
if (rc == NGX_EINPROGRESS) {
|
||||
if (!first) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, rc,
|
||||
"aio_read() still in progress");
|
||||
}
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (rc == NGX_ECANCELED && canceled) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, rc, "aio_read() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rc = aio_return(&ev->aiocb);
|
||||
if (rc == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_return() failed");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug(ev->log, "aio_read: %d" _ rc);
|
||||
|
||||
return rc;
|
||||
}
|
112
src/os/unix/ngx_aio_write.c
Normal file
112
src/os/unix/ngx_aio_write.c
Normal file
@ -0,0 +1,112 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_aio.h>
|
||||
|
||||
#if (HAVE_KQUEUE)
|
||||
#include <ngx_kqueue_module.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
The data is ready - 3 syscalls:
|
||||
aio_write(), aio_error(), aio_return()
|
||||
The data is not ready - 4 (kqueue) or 5 syscalls:
|
||||
aio_write(), aio_error(), notifiction,
|
||||
aio_error(), aio_return()
|
||||
aio_cancel(), aio_error()
|
||||
*/
|
||||
|
||||
ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size)
|
||||
{
|
||||
int rc, first, canceled;
|
||||
ngx_event_t *ev;
|
||||
|
||||
ev = c->write;
|
||||
|
||||
canceled = 0;
|
||||
|
||||
ngx_log_debug(ev->log, "aio: ev->ready: %d" _ ev->ready);
|
||||
ngx_log_debug(ev->log, "aio: aiocb: %08x" _ &ev->aiocb);
|
||||
|
||||
if (ev->timedout) {
|
||||
ngx_set_socket_errno(NGX_ETIMEDOUT);
|
||||
ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_write() timed out");
|
||||
|
||||
rc = aio_cancel(c->fd, &ev->aiocb);
|
||||
if (rc == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
|
||||
"aio_cancel() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug(ev->log, "aio_cancel: %d" _ rc);
|
||||
|
||||
canceled = 1;
|
||||
|
||||
ev->ready = 1;
|
||||
}
|
||||
|
||||
first = 0;
|
||||
|
||||
if (!ev->ready) {
|
||||
ngx_memzero(&ev->aiocb, sizeof(struct aiocb));
|
||||
|
||||
ev->aiocb.aio_fildes = c->fd;
|
||||
ev->aiocb.aio_buf = buf;
|
||||
ev->aiocb.aio_nbytes = size;
|
||||
|
||||
#if (HAVE_KQUEUE)
|
||||
ev->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
|
||||
ev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
|
||||
ev->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev;
|
||||
#endif
|
||||
|
||||
if (aio_write(&ev->aiocb) == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
|
||||
"aio_write() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug(ev->log, "aio_write: OK");
|
||||
|
||||
ev->active = 1;
|
||||
first = 1;
|
||||
}
|
||||
|
||||
ev->ready = 0;
|
||||
|
||||
rc = aio_error(&ev->aiocb);
|
||||
if (rc == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_error() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
if (rc == NGX_EINPROGRESS) {
|
||||
if (!first) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, rc,
|
||||
"aio_write() still in progress");
|
||||
}
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (rc == NGX_ECANCELED && canceled) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, rc, "aio_write() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rc = aio_return(&ev->aiocb);
|
||||
if (rc == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_return() failed");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug(ev->log, "aio_write: %d" _ rc);
|
||||
|
||||
return rc;
|
||||
}
|
@ -1,14 +1,7 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_types.h>
|
||||
#include <ngx_alloc.h>
|
||||
#include <ngx_array.h>
|
||||
#include <ngx_hunk.h>
|
||||
#include <ngx_connection.h>
|
||||
#include <ngx_sendv.h>
|
||||
#include <ngx_sendfile.h>
|
||||
#include <ngx_aio.h>
|
||||
|
||||
|
||||
ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
@ -25,19 +18,19 @@ ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
|
||||
while (ce) {
|
||||
|
||||
ngx_log_debug(c->log, "aio_write ce: %x" _ ce->hunk->pos.mem);
|
||||
ngx_log_debug(c->log, "aio_write ce: %x" _ ce->hunk->pos);
|
||||
|
||||
buf = prev = ce->hunk->pos.mem;
|
||||
buf = prev = ce->hunk->pos;
|
||||
size = 0;
|
||||
|
||||
/* coalesce the neighbouring chain entries */
|
||||
while (ce && prev == ce->hunk->pos.mem) {
|
||||
size += ce->hunk->last.mem - ce->hunk->pos.mem;
|
||||
prev = ce->hunk->last.mem;
|
||||
while (ce && prev == ce->hunk->pos) {
|
||||
size += ce->hunk->last - ce->hunk->pos;
|
||||
prev = ce->hunk->last;
|
||||
ce = ce->next;
|
||||
}
|
||||
|
||||
rc = ngx_event_aio_write(c, buf, size);
|
||||
rc = ngx_aio_write(c, buf, size);
|
||||
|
||||
ngx_log_debug(c->log, "aio_write rc: %d" _ rc);
|
||||
|
||||
@ -62,27 +55,27 @@ ngx_log_debug(c->log, "aio_write rc: %d" _ rc);
|
||||
#if (NGX_DEBUG_WRITE_CHAIN)
|
||||
ngx_log_debug(c->log, "write chain: %x %qx %qd" _
|
||||
ce->hunk->type _
|
||||
ce->hunk->pos.file _
|
||||
ce->hunk->last.file - ce->hunk->pos.file);
|
||||
ce->hunk->file_pos _
|
||||
ce->hunk->file_last - ce->hunk->file_pos);
|
||||
#endif
|
||||
|
||||
if (sent >= ce->hunk->last.file - ce->hunk->pos.file) {
|
||||
sent -= ce->hunk->last.file - ce->hunk->pos.file;
|
||||
ce->hunk->pos.file = ce->hunk->last.file;
|
||||
if (sent >= ce->hunk->file_last - ce->hunk->file_pos) {
|
||||
sent -= ce->hunk->file_last - ce->hunk->file_pos;
|
||||
ce->hunk->file_pos = ce->hunk->file_last;
|
||||
|
||||
#if (NGX_DEBUG_WRITE_CHAIN)
|
||||
ngx_log_debug(c->log, "write chain done: %qx %qd" _
|
||||
ce->hunk->pos.file _ sent);
|
||||
ce->hunk->file_pos _ sent);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
ce->hunk->pos.file += sent;
|
||||
ce->hunk->file_pos += sent;
|
||||
|
||||
#if (NGX_DEBUG_WRITE_CHAIN)
|
||||
ngx_log_debug(c->log, "write chain rest: %qx %qd" _
|
||||
ce->hunk->pos.file _
|
||||
ce->hunk->last.file - ce->hunk->pos.file);
|
||||
ce->hunk->file_pos _
|
||||
ce->hunk->file_last - ce->hunk->file_pos);
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
112
src/os/unix/ngx_freebsd_config.h
Normal file
112
src/os/unix/ngx_freebsd_config.h
Normal file
@ -0,0 +1,112 @@
|
||||
#ifndef _NGX_FREEBSD_CONFIG_H_INCLUDED_
|
||||
#define _NGX_FREEBSD_CONFIG_H_INCLUDED_
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <osreldate.h>
|
||||
|
||||
|
||||
#ifndef HAVE_SELECT
|
||||
#define HAVE_SELECT 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_POLL
|
||||
#define HAVE_POLL 1
|
||||
#endif
|
||||
#if (HAVE_POLL)
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
/* FreeBSD aio supported via kqueue */
|
||||
|
||||
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
|
||||
|| __FreeBSD_version >= 500014
|
||||
|
||||
#ifndef HAVE_AIO
|
||||
#define HAVE_AIO 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (HAVE_AIO)
|
||||
#include <aio.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined SO_ACCEPTFILTER && !defined HAVE_DEFERRED_ACCEPT
|
||||
#define HAVE_DEFERRED_ACCEPT 1
|
||||
#endif
|
||||
|
||||
|
||||
/* FreeBSD sendfile */
|
||||
|
||||
#if __FreeBSD_version >= 300007
|
||||
|
||||
#ifndef HAVE_FREEBSD_SENDFILE
|
||||
#define HAVE_FREEBSD_SENDFILE 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if (HAVE_FREEBSD_SENDFILE)
|
||||
#define HAVE_SENDFILE 1
|
||||
#endif
|
||||
|
||||
|
||||
/* FreeBSD kqueue */
|
||||
|
||||
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \
|
||||
|| __FreeBSD_version >= 500011
|
||||
|
||||
#ifndef HAVE_KQUEUE
|
||||
#define HAVE_KQUEUE 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (HAVE_KQUEUE)
|
||||
#include <sys/event.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* kqueue's NOTE_LOWAT */
|
||||
|
||||
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
|
||||
|| __FreeBSD_version >= 500018
|
||||
|
||||
#ifndef HAVE_LOWAT_EVENT
|
||||
#define HAVE_LOWAT_EVENT 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_INHERITED_NONBLOCK
|
||||
#define HAVE_INHERITED_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _NGX_FREEBSD_CONFIG_H_INCLUDED_ */
|
@ -12,9 +12,10 @@ int ngx_freebsd_sendfile_nbytes_bug;
|
||||
|
||||
ngx_os_io_t ngx_os_io = {
|
||||
ngx_unix_recv,
|
||||
ngx_readv_chain,
|
||||
NULL,
|
||||
NULL,
|
||||
ngx_freebsd_write_chain
|
||||
ngx_freebsd_write_chain,
|
||||
NGX_HAVE_SENDFILE|NGX_HAVE_ZEROCOPY
|
||||
};
|
||||
|
||||
|
||||
@ -107,5 +108,5 @@ int ngx_os_init(ngx_log_t *log)
|
||||
ngx_log_error(NGX_LOG_INFO, log, 0, "net.inet.tcp.sendspace: %d",
|
||||
ngx_freebsd_net_inet_tcp_sendspace);
|
||||
|
||||
return ngx_unix_init(log);
|
||||
return ngx_posix_init(log);
|
||||
}
|
||||
|
@ -7,8 +7,11 @@
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
|
||||
int ngx_unix_init(ngx_log_t *log);
|
||||
/* STUB */
|
||||
int ngx_posix_init(ngx_log_t *log);
|
||||
ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
|
||||
ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
|
||||
/* */
|
||||
|
||||
|
||||
extern int ngx_freebsd_kern_osreldate;
|
||||
|
@ -168,7 +168,7 @@ ngx_tid_t ngx_thread_self()
|
||||
|
||||
|
||||
static inline int ngx_gettid()
|
||||
{
|
||||
{
|
||||
char *sp;
|
||||
|
||||
if (stack_size == 0) {
|
||||
|
48
src/os/unix/ngx_linux_config.h
Normal file
48
src/os/unix/ngx_linux_config.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef _NGX_LINUX_CONFIG_H_INCLUDED_
|
||||
#define _NGX_LINUX_CONFIG_H_INCLUDED_
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/resource.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
|
||||
#ifndef HAVE_SELECT
|
||||
#define HAVE_SELECT 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_POLL
|
||||
#define HAVE_POLL 1
|
||||
#endif
|
||||
#if (HAVE_POLL)
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined TCP_DEFER_ACCEPT && !defined HAVE_DEFERRED_ACCEPT
|
||||
#define HAVE_DEFERRED_ACCEPT 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_INHERITED_NONBLOCK
|
||||
#define HAVE_INHERITED_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */
|
70
src/os/unix/ngx_posix_init.c
Normal file
70
src/os/unix/ngx_posix_init.c
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
int ngx_max_sockets;
|
||||
int ngx_inherited_nonblocking;
|
||||
|
||||
|
||||
int ngx_posix_init(ngx_log_t *log)
|
||||
{
|
||||
struct sigaction sa;
|
||||
struct rlimit rlmt;
|
||||
|
||||
ngx_memzero(&sa, sizeof(struct sigaction));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
|
||||
if (sigaction(SIGPIPE, &sa, NULL) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
|
||||
"sigaction(SIGPIPE, SIG_IGN) failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, errno,
|
||||
"getrlimit(RLIMIT_NOFILE) failed)");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, log, 0,
|
||||
"getrlimit(RLIMIT_NOFILE): %qd:%qd",
|
||||
rlmt.rlim_cur, rlmt.rlim_max);
|
||||
|
||||
ngx_max_sockets = rlmt.rlim_cur;
|
||||
|
||||
#if (HAVE_INHERITED_NONBLOCK)
|
||||
ngx_inherited_nonblocking = 1;
|
||||
#else
|
||||
ngx_inherited_nonblocking = 0;
|
||||
#endif
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
int ngx_posix_post_conf_init(ngx_log_t *log)
|
||||
{
|
||||
ngx_fd_t pp[2];
|
||||
|
||||
if (pipe(pp) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (dup2(pp[1], STDERR_FILENO) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (pp[1] > STDERR_FILENO) {
|
||||
if (close(pp[1]) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_errno.h>
|
||||
#include <ngx_log.h>
|
||||
#include <ngx_connection.h>
|
||||
|
||||
|
||||
ssize_t ngx_recv_chain(ngx_connection_t *c, ngx_chain_t *entry)
|
||||
ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry)
|
||||
{
|
||||
ssize_t n;
|
||||
struct iovec *iov;
|
@ -17,7 +17,7 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
|
||||
|
||||
#if (HAVE_KQUEUE) /* DEBUG */
|
||||
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
|
||||
ngx_log_debug(c->log, "ngx_recv: eof:%d, avail:%d, err:%d" _
|
||||
ngx_log_debug(c->log, "recv: eof:%d, avail:%d, err:%d" _
|
||||
ev->eof _ ev->available _ ev->error);
|
||||
}
|
||||
#endif
|
||||
@ -38,7 +38,7 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
|
||||
} else {
|
||||
n = recv(c->fd, buf, size, 0);
|
||||
|
||||
ngx_log_debug(c->log, "ngx_recv: read:%d:%d" _ n _ size);
|
||||
ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size);
|
||||
|
||||
if (n == -1) {
|
||||
err = ngx_socket_errno;
|
||||
@ -49,6 +49,8 @@ ngx_log_debug(c->log, "ngx_recv: read:%d:%d" _ n _ size);
|
||||
|
||||
n = recv(c->fd, buf, size, 0);
|
||||
|
||||
ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size);
|
||||
|
||||
if (n == -1) {
|
||||
err = ngx_socket_errno;
|
||||
}
|
||||
|
@ -2,12 +2,15 @@
|
||||
#include <ngx_socket.h>
|
||||
|
||||
|
||||
/* ioctl(FIONBIO) set blocking mode with one syscall only while
|
||||
/*
|
||||
ioctl(FIONBIO) set blocking mode with one syscall only while
|
||||
fcntl(F_SETFL, ~O_NONBLOCK) need to know previous state
|
||||
using fcntl(F_GETFL).
|
||||
On FreeBSD both are syscall */
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
ioctl() and fcntl() are syscalls on FreeBSD, Solaris 7/8 and Linux
|
||||
*/
|
||||
|
||||
#if 1
|
||||
|
||||
int ngx_nonblocking(ngx_socket_t s)
|
||||
{
|
||||
|
@ -4,10 +4,6 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define NGX_WRITE_SHUTDOWN SHUT_WR
|
||||
|
||||
@ -17,7 +13,7 @@ typedef int ngx_socket_t;
|
||||
#define ngx_socket_n "socket()"
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#if 1
|
||||
|
||||
int ngx_nonblocking(ngx_socket_t s);
|
||||
int ngx_blocking(ngx_socket_t s);
|
||||
|
64
src/os/unix/ngx_solaris_config.h
Normal file
64
src/os/unix/ngx_solaris_config.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef _NGX_SOLARIS_CONFIG_H_INCLUDED_
|
||||
#define _NGX_SOLARIS_CONFIG_H_INCLUDED_
|
||||
|
||||
|
||||
#define SOLARIS 1
|
||||
|
||||
#define _FILE_OFFSET_BITS 64 /* must be before sys/types.h */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <strings.h> /* bzero() */
|
||||
#include <sys/types.h>
|
||||
#include <sys/filio.h> /* FIONBIO */
|
||||
#include <sys/stropts.h> /* INFTIM */
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/resource.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
|
||||
typedef uint32_t u_int32_t;
|
||||
|
||||
|
||||
#ifndef HAVE_SELECT
|
||||
#define HAVE_SELECT 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_POLL
|
||||
#define HAVE_POLL 1
|
||||
#endif
|
||||
#if (HAVE_POLL)
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if (HAVE_AIO)
|
||||
#include <aio.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if (HAVE_DEVPOLL)
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/devpoll.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_INHERITED_NONBLOCK
|
||||
#define HAVE_INHERITED_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _NGX_SOLARIS_CONFIG_H_INCLUDED_ */
|
@ -3,61 +3,30 @@
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
int ngx_max_sockets;
|
||||
/* STUB */
|
||||
ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
|
||||
ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in);
|
||||
int ngx_posix_init(ngx_log_t *log);
|
||||
int ngx_posix_post_conf_init(ngx_log_t *log);
|
||||
/* */
|
||||
|
||||
|
||||
int ngx_unix_init(ngx_log_t *log)
|
||||
ngx_os_io_t ngx_os_io = {
|
||||
ngx_unix_recv,
|
||||
NULL,
|
||||
NULL,
|
||||
ngx_writev_chain,
|
||||
NGX_HAVE_ZEROCOPY
|
||||
};
|
||||
|
||||
|
||||
int ngx_os_init(ngx_log_t *log)
|
||||
{
|
||||
struct sigaction sa;
|
||||
struct rlimit rlmt;
|
||||
|
||||
ngx_memzero(&sa, sizeof(struct sigaction));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
|
||||
if (sigaction(SIGPIPE, &sa, NULL) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
|
||||
"sigaction(SIGPIPE, SIG_IGN) failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, errno,
|
||||
"getrlimit(RLIMIT_NOFILE) failed)");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, log, 0,
|
||||
"getrlimit(RLIMIT_NOFILE): %qd:%qd",
|
||||
rlmt.rlim_cur, rlmt.rlim_max);
|
||||
|
||||
ngx_max_sockets = rlmt.rlim_cur;
|
||||
|
||||
return NGX_OK;
|
||||
return ngx_posix_init(log);
|
||||
}
|
||||
|
||||
|
||||
int ngx_unix_post_conf_init(ngx_log_t *log)
|
||||
int ngx_os_post_conf_init(ngx_log_t *log)
|
||||
{
|
||||
ngx_fd_t pp[2];
|
||||
|
||||
if (pipe(pp) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (dup2(pp[1], STDERR_FILENO) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (pp[1] > STDERR_FILENO) {
|
||||
if (close(pp[1]) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
return ngx_posix_post_conf_init(log);
|
||||
}
|
||||
|
93
src/os/unix/ngx_writev_chain.c
Normal file
93
src/os/unix/ngx_writev_chain.c
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
{
|
||||
char *prev;
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
off_t sent;
|
||||
struct iovec *iov;
|
||||
ngx_err_t err;
|
||||
ngx_array_t io;
|
||||
ngx_chain_t *ce;
|
||||
|
||||
ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
|
||||
|
||||
prev = NULL;
|
||||
iov = NULL;
|
||||
|
||||
/* create the iovec and coalesce the neighbouring chain entries */
|
||||
for (ce = in; ce; ce = ce->next) {
|
||||
|
||||
if (prev == ce->hunk->pos) {
|
||||
iov->iov_len += ce->hunk->last - ce->hunk->pos;
|
||||
prev = ce->hunk->last;
|
||||
|
||||
} else {
|
||||
ngx_test_null(iov, ngx_push_array(&io), NGX_CHAIN_ERROR);
|
||||
iov->iov_base = ce->hunk->pos;
|
||||
iov->iov_len = ce->hunk->last - ce->hunk->pos;
|
||||
prev = ce->hunk->last;
|
||||
}
|
||||
}
|
||||
|
||||
n = writev(c->fd, (struct iovec *) io.elts, io.nelts);
|
||||
|
||||
if (n == -1) {
|
||||
err = ngx_errno;
|
||||
if (err == NGX_EAGAIN) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
|
||||
|
||||
} else if (err == NGX_EINTR) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
|
||||
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
|
||||
return NGX_CHAIN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
sent = n > 0 ? n : 0;
|
||||
|
||||
#if (NGX_DEBUG_WRITE_CHAIN)
|
||||
ngx_log_debug(c->log, "writev: %qd" _ sent);
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (ce->hunk->type & NGX_HUNK_FILE) {
|
||||
ce->hunk->file_pos = ce->hunk->file_last;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
|
||||
ce->hunk->pos += sent;
|
||||
}
|
||||
|
||||
if (ce->hunk->type & NGX_HUNK_FILE) {
|
||||
ce->hunk->file_pos += sent;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
ngx_destroy_array(&io);
|
||||
|
||||
return ce;
|
||||
}
|
@ -7,17 +7,10 @@ int ngx_max_sockets;
|
||||
|
||||
|
||||
ngx_os_io_t ngx_os_io = {
|
||||
#if 0
|
||||
ngx_unix_recv,
|
||||
NULL,
|
||||
NULL,
|
||||
ngx_freebsd_write_chain
|
||||
#else
|
||||
NULL,
|
||||
ngx_wsarecv,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
93
src/os/win32/ngx_recv.c
Normal file
93
src/os/win32/ngx_recv.c
Normal file
@ -0,0 +1,93 @@
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_event.h>
|
||||
|
||||
|
||||
ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
|
||||
{
|
||||
int rc;
|
||||
u_int flags;
|
||||
size_t bytes;
|
||||
ngx_err_t err;
|
||||
WSABUF wsabuf[1];
|
||||
ngx_event_t *ev;
|
||||
LPWSAOVERLAPPED_COMPLETION_ROUTINE handler;
|
||||
|
||||
ev = c->read;
|
||||
|
||||
/* DEBUG */ bytes = 0;
|
||||
|
||||
if (ev->timedout) {
|
||||
ngx_set_socket_errno(NGX_ETIMEDOUT);
|
||||
ngx_log_error(NGX_LOG_ERR, ev->log, 0, "WSARecv() timed out");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ev->ready) {
|
||||
ev->ready = 0;
|
||||
|
||||
#if (HAVE_IOCP_EVENT) /* iocp */
|
||||
|
||||
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
|
||||
if (ev->ovlp.error) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, ev->ovlp.error,
|
||||
"WSARecv() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return ev->available;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &ev->ovlp,
|
||||
&bytes, 0, NULL) == 0) {
|
||||
err = ngx_socket_errno;
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, err,
|
||||
"WSARecv() or WSAGetOverlappedResult() failed");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
ngx_memzero(&ev->ovlp, sizeof(WSAOVERLAPPED));
|
||||
wsabuf[0].buf = buf;
|
||||
wsabuf[0].len = size;
|
||||
flags = 0;
|
||||
|
||||
#if 0
|
||||
handler = ev->handler;
|
||||
#else
|
||||
handler = NULL;
|
||||
#endif
|
||||
|
||||
rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags,
|
||||
(LPWSAOVERLAPPED) &ev->ovlp, handler);
|
||||
|
||||
ngx_log_debug(ev->log, "WSARecv: %d:%d" _ rc _ bytes);
|
||||
|
||||
if (rc == -1) {
|
||||
err = ngx_socket_errno;
|
||||
if (err == WSA_IO_PENDING) {
|
||||
return NGX_AGAIN;
|
||||
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_CRIT, ev->log, err, "WSARecv() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#if (HAVE_IOCP_EVENT) /* iocp */
|
||||
|
||||
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return bytes;
|
||||
}
|
35
src/os/win32/ngx_win32_config.h
Normal file
35
src/os/win32/ngx_win32_config.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef _NGX_WIN32_CONFIG_H_INCLUDED_
|
||||
#define _NGX_WIN32_CONFIG_H_INCLUDED_
|
||||
|
||||
|
||||
#define WIN32 1
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <mswsock.h>
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#define ngx_inline __inline
|
||||
|
||||
|
||||
#ifndef HAVE_INHERITED_NONBLOCK
|
||||
#define HAVE_INHERITED_NONBLOCK 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WIN32_TRANSMITPACKETS
|
||||
#define HAVE_WIN32_TRANSMITPACKETS 1
|
||||
#define HAVE_WIN32_TRANSMITFILE 0
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WIN32_TRANSMITFILE
|
||||
#define HAVE_WIN32_TRANSMITFILE 1
|
||||
#endif
|
||||
|
||||
#if (HAVE_WIN32_TRANSMITPACKETS) || (HAVE_WIN32_TRANSMITFILE)
|
||||
#define HAVE_SENDFILE 1
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _NGX_WIN32_CONFIG_H_INCLUDED_ */
|
Loading…
Reference in New Issue
Block a user