# HG changeset patch # User Igor Sysoev # Date 1217420287 0 # Node ID 345a014436d4eea518b476f0f7c0652aab6fec73 # Parent 05e8de8fcfbb468ed4d987191f817b315dca6551 *) move Darwin support to separate files *) Darwin sendfile() support diff --git a/auto/os/conf b/auto/os/conf --- a/auto/os/conf +++ b/auto/os/conf @@ -18,6 +18,10 @@ case "$NGX_PLATFORM" in . auto/os/solaris ;; + Darwin:*) + . auto/os/darwin + ;; + win32) . auto/os/win32 ;; @@ -36,24 +40,6 @@ case "$NGX_PLATFORM" in ' ;; - Darwin:*) - have=NGX_DARWIN . auto/have_headers - have=NGX_HAVE_INHERITED_NONBLOCK . auto/have - CORE_INCS="$UNIX_INCS" - CORE_DEPS="$UNIX_DEPS $POSIX_DEPS" - CORE_SRCS="$UNIX_SRCS" - - ngx_feature="atomic(3)" - ngx_feature_name=NGX_DARWIN_ATOMIC - ngx_feature_run=no - ngx_feature_incs="#include " - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="int32_t lock, n; - n = OSAtomicCompareAndSwap32Barrier(0, 1, lock)" - . auto/feature - ;; - HP-UX:*) # HP/UX have=NGX_HPUX . auto/have_headers diff --git a/auto/os/darwin b/auto/os/darwin new file mode 100644 --- /dev/null +++ b/auto/os/darwin @@ -0,0 +1,115 @@ + +# Copyright (C) Igor Sysoev + + +have=NGX_DARWIN . auto/have_headers + +CORE_INCS="$UNIX_INCS" +CORE_DEPS="$UNIX_DEPS $DARWIN_DEPS" +CORE_SRCS="$UNIX_SRCS $DARWIN_SRCS" + + + +ngx_spacer=' +' + +# kqueue + +echo " + kqueue found" +have=NGX_HAVE_KQUEUE . auto/have +have=NGX_HAVE_CLEAR_EVENT . auto/have +EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE" +CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS" +EVENT_FOUND=YES +NGX_KQUEUE_CHECKED=YES + +ngx_feature="kqueue's EVFILT_TIMER" +ngx_feature_name="NGX_HAVE_TIMER_EVENT" +ngx_feature_run=yes +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="int kq; + struct kevent kev; + struct timespec ts; + + if ((kq = kqueue()) == -1) return 1; + + kev.ident = 0; + kev.filter = EVFILT_TIMER; + kev.flags = EV_ADD|EV_ENABLE; + kev.fflags = 0; + kev.data = 1000; + kev.udata = 0; + + ts.tv_sec = 0; + ts.tv_nsec = 0; + + if (kevent(kq, &kev, 1, &kev, 1, &ts) == -1) return 1; + + if (kev.flags & EV_ERROR) return 1;" + +. auto/feature + + +ngx_feature="Darwin 64-bit kqueue millisecond timeout bug" +ngx_feature_name=NGX_DARWIN_KEVENT_BUG +ngx_feature_run=bug +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="int kq; + struct kevent kev; + struct timespec ts; + struct timeval tv, tv0; + + kq = kqueue(); + + ts.tv_sec = 0; + ts.tv_nsec = 999000000; + + gettimeofday(&tv, 0); + kevent(kq, NULL, 0, &kev, 1, &ts); + gettimeofday(&tv0, 0); + timersub(&tv0, &tv, &tv); + + if (tv.tv_sec * 1000000 + tv.tv_usec < 900000) return 1;" + +. auto/feature + + +# sendfile() + +CC_AUX_FLAGS="$CC_AUX_FLAGS" +ngx_feature="sendfile()" +ngx_feature_name="NGX_HAVE_SENDFILE" +ngx_feature_run=yes +ngx_feature_incs="#include + #include + #include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="int s = 0, fd = 1; + off_t n; off_t off = 0; + n = sendfile(s, fd, off, &n, NULL, 0); + if (n == -1 && errno == ENOSYS) return 1" +. auto/feature + +if [ $ngx_found = yes ]; then + have=NGX_HAVE_SENDFILE . auto/have + CORE_SRCS="$CORE_SRCS $DARWIN_SENDFILE_SRCS" +fi + + +ngx_feature="atomic(3)" +ngx_feature_name=NGX_DARWIN_ATOMIC +ngx_feature_run=no +ngx_feature_incs="#include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="int32_t lock, n; + n = OSAtomicCompareAndSwap32Barrier(0, 1, lock)" +. auto/feature diff --git a/auto/os/features b/auto/os/features --- a/auto/os/features +++ b/auto/os/features @@ -122,36 +122,6 @@ if test -z "$NGX_KQUEUE_CHECKED"; then if (kev.flags & EV_ERROR) return 1;" . auto/feature - - - if [ "$NGX_SYSTEM" = "Darwin" ]; then - - ngx_feature="Darwin 64-bit kqueue millisecond timeout bug" - ngx_feature_name=NGX_DARWIN_KEVENT_BUG - ngx_feature_run=bug - ngx_feature_incs="#include -#include " - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="int kq; - struct kevent kev; - struct timespec ts; - struct timeval tv, tv0; - - kq = kqueue(); - - ts.tv_sec = 0; - ts.tv_nsec = 999000000; - - gettimeofday(&tv, 0); - kevent(kq, NULL, 0, &kev, 1, &ts); - gettimeofday(&tv0, 0); - timersub(&tv0, &tv, &tv); - - if (tv.tv_sec * 1000000 + tv.tv_usec < 900000) return 1;" - - . auto/feature - fi fi fi diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -198,6 +198,11 @@ SOLARIS_SRCS=src/os/unix/ngx_solaris_ini SOLARIS_SENDFILEV_SRCS=src/os/unix/ngx_solaris_sendfilev_chain.c +DARWIN_DEPS="src/os/unix/ngx_darwin_config.h src/os/unix/ngx_darwin.h" +DARWIN_SRCS=src/os/unix/ngx_darwin_init.c +DARWIN_SENDFILE_SRCS=src/os/unix/ngx_darwin_sendfile_chain.c + + WIN32_INCS="$CORE_INCS $EVENT_INCS src/os/win32" WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \ diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -29,6 +29,10 @@ #include +#elif (NGX_DARWIN) +#include + + #elif (NGX_WIN32) #include diff --git a/src/os/unix/ngx_freebsd.h b/src/os/unix/ngx_darwin.h copy from src/os/unix/ngx_freebsd.h copy to src/os/unix/ngx_darwin.h --- a/src/os/unix/ngx_freebsd.h +++ b/src/os/unix/ngx_darwin.h @@ -4,21 +4,16 @@ */ -#ifndef _NGX_FREEBSD_H_INCLUDED_ -#define _NGX_FREEBSD_H_INCLUDED_ +#ifndef _NGX_DARWIN_H_INCLUDED_ +#define _NGX_DARWIN_H_INCLUDED_ -ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, +ngx_chain_t *ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); -extern int ngx_freebsd_kern_osreldate; -extern int ngx_freebsd_hw_ncpu; -extern u_long ngx_freebsd_net_inet_tcp_sendspace; -extern int ngx_freebsd_kern_ipc_zero_copy_send; - -extern ngx_uint_t ngx_freebsd_sendfile_nbytes_bug; -extern ngx_uint_t ngx_freebsd_use_tcp_nopush; -extern ngx_uint_t ngx_freebsd_debug_malloc; +extern int ngx_darwin_kern_osreldate; +extern int ngx_darwin_hw_ncpu; +extern u_long ngx_darwin_net_inet_tcp_sendspace; -#endif /* _NGX_FREEBSD_H_INCLUDED_ */ +#endif /* _NGX_DARWIN_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_darwin_config.h copy from src/os/unix/ngx_posix_config.h copy to src/os/unix/ngx_darwin_config.h --- a/src/os/unix/ngx_posix_config.h +++ b/src/os/unix/ngx_darwin_config.h @@ -4,35 +4,15 @@ */ -#ifndef _NGX_POSIX_CONFIG_H_INCLUDED_ -#define _NGX_POSIX_CONFIG_H_INCLUDED_ - - -#if (NGX_HPUX) -#define _XOPEN_SOURCE -#define _XOPEN_SOURCE_EXTENDED 1 -#endif - +#ifndef _NGX_DARWIN_CONFIG_H_INCLUDED_ +#define _NGX_DARWIN_CONFIG_H_INCLUDED_ -#if (NGX_TRU64) -#define _REENTRANT -#endif - - -#ifdef __CYGWIN__ -#define timezonevar /* timezone is variable */ -#define NGX_BROKEN_SCM_RIGHTS 1 -#endif #include #include -#if (NGX_HAVE_UNISTD_H) #include -#endif -#if (NGX_HAVE_INTTYPES_H) #include -#endif #include #include /* offsetof() */ #include @@ -45,11 +25,8 @@ #include #include -#if (NGX_HAVE_SYS_FILIO_H) #include /* FIONBIO */ -#endif -#include /* FIONBIO */ - +#include #include #include #include @@ -66,21 +43,12 @@ #include #include -#if (NGX_HAVE_LIMITS_H) -#include /* IOV_MAX */ -#endif - -#ifdef __CYGWIN__ -#include /* memalign() */ -#endif - -#if (NGX_HAVE_CRYPT_H) -#include -#endif +#include +#include #ifndef IOV_MAX -#define IOV_MAX 16 +#define IOV_MAX 64 #endif @@ -97,36 +65,23 @@ #endif -#if (NGX_HAVE_DEVPOLL) -#include -#include +#define NGX_LISTEN_BACKLOG -1 + + +#ifndef NGX_HAVE_INHERITED_NONBLOCK +#define NGX_HAVE_INHERITED_NONBLOCK 1 #endif -#define NGX_LISTEN_BACKLOG 511 +#ifndef NGX_HAVE_CASELESS_FILESYSTEM +#define NGX_HAVE_CASELESS_FILESYSTEM 1 +#endif -#if (__FreeBSD__) && (__FreeBSD_version < 400017) - -#include /* ALIGN() */ - -/* - * FreeBSD 3.x has no CMSG_SPACE() and CMSG_LEN() and has the broken CMSG_DATA() - */ - -#undef CMSG_SPACE -#define CMSG_SPACE(l) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(l)) - -#undef CMSG_LEN -#define CMSG_LEN(l) (ALIGN(sizeof(struct cmsghdr)) + (l)) - -#undef CMSG_DATA -#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + ALIGN(sizeof(struct cmsghdr))) - -#endif +#define NGX_HAVE_OS_SPECIFIC_INIT 1 extern char **environ; -#endif /* _NGX_POSIX_CONFIG_H_INCLUDED_ */ +#endif /* _NGX_DARWIN_CONFIG_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_darwin_init.c copy from src/os/unix/ngx_freebsd_init.c copy to src/os/unix/ngx_darwin_init.c --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_darwin_init.c @@ -8,33 +8,20 @@ #include -/* FreeBSD 3.0 at least */ -char ngx_freebsd_kern_ostype[16]; -char ngx_freebsd_kern_osrelease[128]; -int ngx_freebsd_kern_osreldate; -int ngx_freebsd_hw_ncpu; -int ngx_freebsd_kern_ipc_somaxconn; -u_long ngx_freebsd_net_inet_tcp_sendspace; - -/* FreeBSD 4.9 */ -int ngx_freebsd_machdep_hlt_logical_cpus; - -/* FreeBSD 5.0 */ -int ngx_freebsd_kern_ipc_zero_copy_send; +char ngx_darwin_kern_ostype[16]; +char ngx_darwin_kern_osrelease[128]; +int ngx_darwin_hw_ncpu; +int ngx_darwin_kern_ipc_somaxconn; +u_long ngx_darwin_net_inet_tcp_sendspace; -ngx_uint_t ngx_freebsd_sendfile_nbytes_bug; -ngx_uint_t ngx_freebsd_use_tcp_nopush; -ngx_uint_t ngx_freebsd_debug_malloc; - - -static ngx_os_io_t ngx_freebsd_io = { +static ngx_os_io_t ngx_darwin_io = { ngx_unix_recv, ngx_readv_chain, ngx_udp_unix_recv, ngx_unix_send, #if (NGX_HAVE_SENDFILE) - ngx_freebsd_sendfile_chain, + ngx_darwin_sendfile_chain, NGX_IO_SENDFILE #else ngx_writev_chain, @@ -53,65 +40,32 @@ typedef struct { sysctl_t sysctls[] = { { "hw.ncpu", - &ngx_freebsd_hw_ncpu, - sizeof(ngx_freebsd_hw_ncpu), 0 }, - - { "machdep.hlt_logical_cpus", - &ngx_freebsd_machdep_hlt_logical_cpus, - sizeof(ngx_freebsd_machdep_hlt_logical_cpus), 0 }, + &ngx_darwin_hw_ncpu, + sizeof(ngx_darwin_hw_ncpu), 0 }, { "net.inet.tcp.sendspace", - &ngx_freebsd_net_inet_tcp_sendspace, - sizeof(ngx_freebsd_net_inet_tcp_sendspace), 0 }, + &ngx_darwin_net_inet_tcp_sendspace, + sizeof(ngx_darwin_net_inet_tcp_sendspace), 0 }, { "kern.ipc.somaxconn", - &ngx_freebsd_kern_ipc_somaxconn, - sizeof(ngx_freebsd_kern_ipc_somaxconn), 0 }, - - { "kern.ipc.zero_copy.send", - &ngx_freebsd_kern_ipc_zero_copy_send, - sizeof(ngx_freebsd_kern_ipc_zero_copy_send), 0 }, + &ngx_darwin_kern_ipc_somaxconn, + sizeof(ngx_darwin_kern_ipc_somaxconn), 0 }, { NULL, NULL, 0, 0 } }; -void -ngx_debug_init() -{ -#if (NGX_DEBUG_MALLOC) - -#if __FreeBSD_version >= 500014 - _malloc_options = "J"; -#else - malloc_options = "J"; -#endif - - ngx_freebsd_debug_malloc = 1; - -#else - char *mo; - - mo = getenv("MALLOC_OPTIONS"); - - if (mo && ngx_strchr(mo, 'J')) { - ngx_freebsd_debug_malloc = 1; - } -#endif -} - - ngx_int_t ngx_os_specific_init(ngx_log_t *log) { - int version, somaxconn; + int somaxconn; size_t size; ngx_err_t err; ngx_uint_t i; - size = sizeof(ngx_freebsd_kern_ostype); + size = sizeof(ngx_darwin_kern_ostype); if (sysctlbyname("kern.ostype", - ngx_freebsd_kern_ostype, &size, NULL, 0) == -1) { + ngx_darwin_kern_ostype, &size, NULL, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "sysctlbyname(kern.ostype) failed"); @@ -119,12 +73,12 @@ ngx_os_specific_init(ngx_log_t *log) return NGX_ERROR; } - ngx_freebsd_kern_ostype[size - 1] = '\0'; + ngx_darwin_kern_ostype[size - 1] = '\0'; } - size = sizeof(ngx_freebsd_kern_osrelease); + size = sizeof(ngx_darwin_kern_osrelease); if (sysctlbyname("kern.osrelease", - ngx_freebsd_kern_osrelease, &size, NULL, 0) == -1) { + ngx_darwin_kern_osrelease, &size, NULL, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "sysctlbyname(kern.osrelease) failed"); @@ -132,59 +86,7 @@ ngx_os_specific_init(ngx_log_t *log) return NGX_ERROR; } - ngx_freebsd_kern_osrelease[size - 1] = '\0'; - } - - - size = sizeof(int); - if (sysctlbyname("kern.osreldate", - &ngx_freebsd_kern_osreldate, &size, NULL, 0) == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, - "sysctlbyname(kern.osreldate) failed"); - return NGX_ERROR; - } - - version = ngx_freebsd_kern_osreldate; - - -#if (NGX_HAVE_SENDFILE) - - /* - * The determination of the sendfile() "nbytes bug" is complex enough. - * There are two sendfile() syscalls: a new #393 has no bug while - * an old #336 has the bug in some versions and has not in others. - * Besides libc_r wrapper also emulates the bug in some versions. - * There is no way to say exactly if syscall #336 in FreeBSD circa 4.6 - * has the bug. We use the algorithm that is correct at least for - * RELEASEs and for syscalls only (not libc_r wrapper). - * - * 4.6.1-RELEASE and below have the bug - * 4.6.2-RELEASE and above have the new syscall - * - * We detect the new sendfile() syscall available at the compile time - * to allow an old binary to run correctly on an updated FreeBSD system. - */ - -#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \ - || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039 - - /* a new syscall without the bug */ - - ngx_freebsd_sendfile_nbytes_bug = 0; - -#else - - /* an old syscall that may have the bug */ - - ngx_freebsd_sendfile_nbytes_bug = 1; - -#endif - -#endif /* NGX_HAVE_SENDFILE */ - - - if ((version < 500000 && version >= 440003) || version >= 500017) { - ngx_freebsd_use_tcp_nopush = 1; + ngx_darwin_kern_osrelease[size - 1] = '\0'; } @@ -209,16 +111,11 @@ ngx_os_specific_init(ngx_log_t *log) return NGX_ERROR; } - if (ngx_freebsd_machdep_hlt_logical_cpus) { - ngx_ncpu = ngx_freebsd_hw_ncpu / 2; + ngx_ncpu = ngx_darwin_hw_ncpu; - } else { - ngx_ncpu = ngx_freebsd_hw_ncpu; - } + somaxconn = 32676; - somaxconn = version < 600008 ? 32676 : 65535; - - if (ngx_freebsd_kern_ipc_somaxconn > somaxconn) { + if (ngx_darwin_kern_ipc_somaxconn > somaxconn) { ngx_log_error(NGX_LOG_ALERT, log, 0, "sysctl kern.ipc.somaxconn must be no more than %d", somaxconn); @@ -227,7 +124,7 @@ ngx_os_specific_init(ngx_log_t *log) ngx_tcp_nodelay_and_tcp_nopush = 1; - ngx_os_io = ngx_freebsd_io; + ngx_os_io = ngx_darwin_io; return NGX_OK; } @@ -240,17 +137,7 @@ ngx_os_specific_status(ngx_log_t *log) ngx_uint_t i; ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s", - ngx_freebsd_kern_ostype, ngx_freebsd_kern_osrelease); - -#ifdef __DragonFly_version - ngx_log_error(NGX_LOG_NOTICE, log, 0, - "kern.osreldate: %d, built on %d", - ngx_freebsd_kern_osreldate, __DragonFly_version); -#else - ngx_log_error(NGX_LOG_NOTICE, log, 0, - "kern.osreldate: %d, built on %d", - ngx_freebsd_kern_osreldate, __FreeBSD_version); -#endif + ngx_darwin_kern_ostype, ngx_darwin_kern_osrelease); for (i = 0; sysctls[i].name; i++) { if (sysctls[i].exists) { diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_darwin_sendfile_chain.c copy from src/os/unix/ngx_freebsd_sendfile_chain.c copy to src/os/unix/ngx_darwin_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_darwin_sendfile_chain.c @@ -10,21 +10,19 @@ /* - * Although FreeBSD sendfile() allows to pass a header and a trailer, - * it can not send a header with a part of the file in one packet until - * FreeBSD 5.3. Besides, over the fast ethernet connection sendfile() - * may send the partially filled packets, i.e. the 8 file pages may be sent - * as the 11 full 1460-bytes packets, then one incomplete 324-bytes packet, - * and then again the 11 full 1460-bytes packets. + * It seems that Darwin 9.4 (Mac OS X 1.5) sendfile() has the same + * old bug as early FreeBSD sendfile() syscall: + * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771 * - * Threfore we use the TCP_NOPUSH option (similar to Linux's TCP_CORK) - * to postpone the sending - it not only sends a header and the first part of - * the file in one packet, but also sends the file pages in the full packets. + * Besides sendfile() has another bug: if one calls sendfile() + * with both a header and a trailer, then sendfile() ignores a file part + * at all and sends only the header and the trailer together. + * For this reason we send a trailer only if there is no a header. * - * But until FreeBSD 4.5 turning TCP_NOPUSH off does not flush a pending - * data that less than MSS, so that data may be sent with 5 second delay. - * So we do not use TCP_NOPUSH on FreeBSD prior to 4.5, although it can be used - * for non-keepalive HTTP connections. + * Although sendfile() allows to pass a header or a trailer, + * it may send the header or the trailer and a part of the file + * in different packets. And FreeBSD workaround (TCP_NOPUSH option) + * does not help. */ @@ -38,12 +36,12 @@ ngx_chain_t * -ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) +ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) { int rc; u_char *prev; off_t size, send, prev_send, aligned, sent, fprev; - size_t header_size, file_size; + off_t header_size, file_size; ngx_uint_t eintr, eagain, complete; ngx_err_t err; ngx_buf_t *file; @@ -137,7 +135,7 @@ ngx_freebsd_sendfile_chain(ngx_connectio } prev = cl->buf->pos + (size_t) size; - header_size += (size_t) size; + header_size += size; send += size; } @@ -161,7 +159,7 @@ ngx_freebsd_sendfile_chain(ngx_connectio } } - file_size += (size_t) size; + file_size += size; send += size; fprev = cl->buf->file_pos + size; cl = cl->next; @@ -173,8 +171,7 @@ ngx_freebsd_sendfile_chain(ngx_connectio && fprev == cl->buf->file_pos); } - - if (file) { + if (file && header.nelts == 0) { /* create the tailer iovec and coalesce the neighbouring bufs */ @@ -219,50 +216,24 @@ ngx_freebsd_sendfile_chain(ngx_connectio if (file) { - if (ngx_freebsd_use_tcp_nopush - && c->tcp_nopush == NGX_TCP_NOPUSH_UNSET) - { - if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { - err = ngx_errno; - - /* - * there is a tiny chance to be interrupted, however, - * we continue a processing without the TCP_NOPUSH - */ + /* + * sendfile() returns EINVAL if sf_hdtr's count is 0, + * but corresponding pointer is not NULL + */ - if (err != NGX_EINTR) { - wev->error = 1; - (void) ngx_connection_error(c, err, - ngx_tcp_nopush_n " failed"); - return NGX_CHAIN_ERROR; - } - - } else { - c->tcp_nopush = NGX_TCP_NOPUSH_SET; - - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "tcp_nopush"); - } - } - - hdtr.headers = (struct iovec *) header.elts; + hdtr.headers = header.nelts ? (struct iovec *) header.elts: NULL; hdtr.hdr_cnt = header.nelts; - hdtr.trailers = (struct iovec *) trailer.elts; + hdtr.trailers = trailer.nelts ? (struct iovec *) trailer.elts: NULL; hdtr.trl_cnt = trailer.nelts; - /* - * the "nbytes bug" of the old sendfile() syscall: - * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771 - */ + sent = header_size + file_size; - if (!ngx_freebsd_sendfile_nbytes_bug) { - header_size = 0; - } - - sent = 0; + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, + "sendfile: @%O %O h:%O", + file->file_pos, sent, header_size); rc = sendfile(file->file->fd, c->fd, file->file_pos, - file_size + header_size, &hdtr, &sent, 0); + &sent, &hdtr, 0); if (rc == -1) { err = ngx_errno; @@ -285,15 +256,10 @@ ngx_freebsd_sendfile_chain(ngx_connectio } } - /* - * sendfile() in FreeBSD 3.x-4.x may return value >= 0 - * on success, although only 0 is documented - */ - - if (rc >= 0 && sent == 0) { + if (rc == 0 && sent == 0) { /* - * if rc is OK and sent equal to zero, then someone + * if rc and sent equal to zero, then someone * has truncated the file, so the offset became beyond * the end of the file */ @@ -306,14 +272,14 @@ ngx_freebsd_sendfile_chain(ngx_connectio } ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, - "sendfile: %d, @%O %O:%uz", + "sendfile: %d, @%O %O:%O", rc, file->file_pos, sent, file_size + header_size); } else { rc = writev(c->fd, header.elts, header.nelts); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, - "writev: %d of %uz", rc, header_size); + "writev: %d of %uz", rc, send); if (rc == -1) { err = ngx_errno; @@ -379,19 +345,6 @@ ngx_freebsd_sendfile_chain(ngx_connectio break; } - if (eagain) { - - /* - * sendfile() may return EAGAIN, even if it has sent a whole file - * part, it indicates that the successive sendfile() call would - * return EAGAIN right away and would not send anything. - * We use it as a hint. - */ - - wev->ready = 0; - return cl; - } - if (eintr) { continue; } diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h --- a/src/os/unix/ngx_os.h +++ b/src/os/unix/ngx_os.h @@ -66,6 +66,10 @@ extern ngx_uint_t ngx_tcp_nodelay_and_ #elif (NGX_SOLARIS) #include + + +#elif (NGX_DARWIN) +#include #endif