diff options
author | Igor Sysoev <igor@sysoev.ru> | 2003-05-21 13:28:21 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2003-05-21 13:28:21 +0000 |
commit | fa73aac7747c9d0a8575eb2beffcdab50171e006 (patch) | |
tree | d1e354f2e321b8f1c4e5518984759bab1ae05ddd /src/os/unix | |
parent | 1c13c662f0ae8066d1d4849b4158d7459a4c7822 (diff) | |
download | nginx-fa73aac7747c9d0a8575eb2beffcdab50171e006.tar.gz nginx-fa73aac7747c9d0a8575eb2beffcdab50171e006.zip |
nginx-0.0.1-2003-05-21-17:28:21 import
Diffstat (limited to 'src/os/unix')
-rw-r--r-- | src/os/unix/ngx_aio.h | 13 | ||||
-rw-r--r-- | src/os/unix/ngx_aio_read.c | 110 | ||||
-rw-r--r-- | src/os/unix/ngx_aio_write.c | 112 | ||||
-rw-r--r-- | src/os/unix/ngx_aio_write_chain.c | 39 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_config.h | 112 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_init.c | 7 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_init.h | 5 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_rfork_thread.c | 2 | ||||
-rw-r--r-- | src/os/unix/ngx_linux_config.h | 48 | ||||
-rw-r--r-- | src/os/unix/ngx_posix_init.c | 70 | ||||
-rw-r--r-- | src/os/unix/ngx_readv_chain.c (renamed from src/os/unix/ngx_recv_chain.c) | 5 | ||||
-rw-r--r-- | src/os/unix/ngx_recv.c | 6 | ||||
-rw-r--r-- | src/os/unix/ngx_socket.c | 9 | ||||
-rw-r--r-- | src/os/unix/ngx_socket.h | 6 | ||||
-rw-r--r-- | src/os/unix/ngx_solaris_config.h | 64 | ||||
-rw-r--r-- | src/os/unix/ngx_unix_init.c | 67 | ||||
-rw-r--r-- | src/os/unix/ngx_writev_chain.c | 93 |
17 files changed, 677 insertions, 91 deletions
diff --git a/src/os/unix/ngx_aio.h b/src/os/unix/ngx_aio.h new file mode 100644 index 000000000..a37dafc6a --- /dev/null +++ b/src/os/unix/ngx_aio.h @@ -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_ */ diff --git a/src/os/unix/ngx_aio_read.c b/src/os/unix/ngx_aio_read.c new file mode 100644 index 000000000..4896af9ce --- /dev/null +++ b/src/os/unix/ngx_aio_read.c @@ -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; +} diff --git a/src/os/unix/ngx_aio_write.c b/src/os/unix/ngx_aio_write.c new file mode 100644 index 000000000..918535aa7 --- /dev/null +++ b/src/os/unix/ngx_aio_write.c @@ -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; +} diff --git a/src/os/unix/ngx_aio_write_chain.c b/src/os/unix/ngx_aio_write_chain.c index 34c4f4016..14586ce40 100644 --- a/src/os/unix/ngx_aio_write_chain.c +++ b/src/os/unix/ngx_aio_write_chain.c @@ -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; diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h new file mode 100644 index 000000000..f8066e561 --- /dev/null +++ b/src/os/unix/ngx_freebsd_config.h @@ -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_ */ diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c index f9cba480c..aac8ed988 100644 --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -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); } diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h index 6f5862599..e81942b16 100644 --- a/src/os/unix/ngx_freebsd_init.h +++ b/src/os/unix/ngx_freebsd_init.h @@ -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; diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c index 88cecedde..8199d0b6a 100644 --- a/src/os/unix/ngx_freebsd_rfork_thread.c +++ b/src/os/unix/ngx_freebsd_rfork_thread.c @@ -168,7 +168,7 @@ ngx_tid_t ngx_thread_self() static inline int ngx_gettid() -{ +{ char *sp; if (stack_size == 0) { diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h new file mode 100644 index 000000000..69a607ed5 --- /dev/null +++ b/src/os/unix/ngx_linux_config.h @@ -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_ */ diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c new file mode 100644 index 000000000..aadb64c2d --- /dev/null +++ b/src/os/unix/ngx_posix_init.c @@ -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; +} diff --git a/src/os/unix/ngx_recv_chain.c b/src/os/unix/ngx_readv_chain.c index 4e9316830..8432f0c8d 100644 --- a/src/os/unix/ngx_recv_chain.c +++ b/src/os/unix/ngx_readv_chain.c @@ -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; diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c index c6e8b0390..b2be905f7 100644 --- a/src/os/unix/ngx_recv.c +++ b/src/os/unix/ngx_recv.c @@ -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; } diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c index d213fa86f..0746fa0ec 100644 --- a/src/os/unix/ngx_socket.c +++ b/src/os/unix/ngx_socket.c @@ -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) { diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h index 937c12d9a..cee1f4aeb 100644 --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -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); diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h new file mode 100644 index 000000000..1545fc914 --- /dev/null +++ b/src/os/unix/ngx_solaris_config.h @@ -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_ */ diff --git a/src/os/unix/ngx_unix_init.c b/src/os/unix/ngx_unix_init.c index 7b38bb18e..95741642b 100644 --- a/src/os/unix/ngx_unix_init.c +++ b/src/os/unix/ngx_unix_init.c @@ -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) -{ - 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; - } - +ngx_os_io_t ngx_os_io = { + ngx_unix_recv, + NULL, + NULL, + ngx_writev_chain, + NGX_HAVE_ZEROCOPY +}; - 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; +int ngx_os_init(ngx_log_t *log) +{ + 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); } diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c new file mode 100644 index 000000000..fdaa52a48 --- /dev/null +++ b/src/os/unix/ngx_writev_chain.c @@ -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; +} |