Events: use eventfd() instead of syscall(SYS_eventfd) if possible.

This fixes --with-file-aio support on systems that lack eventfd()
syscall, notably aarch64 Linux.

The syscall(SYS_eventfd) may still be necessary on systems that
have eventfd() syscall in the kernel but lack it in glibc, e.g.
as seen in the current CentOS 5 release.
stable-1.8
Ruslan Ermilov 2014-05-23 16:37:05 +04:00
parent 3e279a8eb4
commit 5c17030671
3 changed files with 34 additions and 10 deletions
auto

View File

@ -398,16 +398,36 @@ if [ $NGX_FILE_AIO = YES ]; then
if [ $ngx_found = yes ]; then
CORE_SRCS="$CORE_SRCS $FILE_AIO_SRCS"
fi
elif [ $ngx_found = no ]; then
if [ $ngx_found = no ]; then
ngx_feature="Linux AIO support"
ngx_feature_name="NGX_HAVE_FILE_AIO"
ngx_feature_run=no
ngx_feature_incs="#include <linux/aio_abi.h>
#include <sys/syscall.h>"
#include <sys/eventfd.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="struct iocb iocb;
iocb.aio_lio_opcode = IOCB_CMD_PREAD;
iocb.aio_flags = IOCB_FLAG_RESFD;
iocb.aio_resfd = -1;
(void) eventfd(0, 0)"
. auto/feature
if [ $ngx_found = yes ]; then
have=NGX_HAVE_EVENTFD . auto/have
have=NGX_HAVE_SYS_EVENTFD_H . auto/have
CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
fi
fi
if [ $ngx_found = no ]; then
ngx_feature="Linux AIO support (SYS_eventfd)"
ngx_feature_incs="#include <linux/aio_abi.h>
#include <sys/syscall.h>"
ngx_feature_test="int n = SYS_eventfd;
struct iocb iocb;
iocb.aio_lio_opcode = IOCB_CMD_PREAD;
@ -418,16 +438,17 @@ if [ $NGX_FILE_AIO = YES ]; then
if [ $ngx_found = yes ]; then
have=NGX_HAVE_EVENTFD . auto/have
CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
fi
fi
else
cat << END
if [ $ngx_found = no ]; then
cat << END
$0: no supported file AIO was found
Currently file AIO is supported on FreeBSD 4.3+ and Linux 2.6.22+ only
END
exit 1
fi
exit 1
fi
fi

View File

@ -193,10 +193,6 @@ ngx_module_t ngx_epoll_module = {
* We call io_setup(), io_destroy() io_submit(), and io_getevents() directly
* as syscalls instead of libaio usage, because the library header file
* supports eventfd() since 0.3.107 version only.
*
* Also we do not use eventfd() in glibc, because glibc supports it
* since 2.8 version and glibc maps two syscalls eventfd() and eventfd2()
* into single eventfd() function with different number of parameters.
*/
static int
@ -227,7 +223,11 @@ ngx_epoll_aio_init(ngx_cycle_t *cycle, ngx_epoll_conf_t *epcf)
int n;
struct epoll_event ee;
#if (NGX_HAVE_SYS_EVENTFD_H)
ngx_eventfd = eventfd(0, 0);
#else
ngx_eventfd = syscall(SYS_eventfd, 0);
#endif
if (ngx_eventfd == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,

View File

@ -94,6 +94,9 @@ extern ssize_t sendfile(int s, int fd, int32_t *offset, size_t size);
#if (NGX_HAVE_FILE_AIO)
#if (NGX_HAVE_SYS_EVENTFD_H)
#include <sys/eventfd.h>
#endif
#include <sys/syscall.h>
#include <linux/aio_abi.h>
typedef struct iocb ngx_aiocb_t;