Use eventfd instead of pipes if available
eventfd has less overhead than a pipe, works as a counter and uses a single fd. Use it on Linux if available (that should be pretty much always given the glibc and kernel requirements).
This commit is contained in:
parent
274dccf66c
commit
cb4320791b
|
@ -34,6 +34,8 @@ AC_CHECK_HEADERS([sys/wait.h])
|
|||
AC_CHECK_HEADERS([sys/param.h])
|
||||
AC_CHECK_HEADERS([sys/select.h])
|
||||
AC_CHECK_HEADERS([dirent.h])
|
||||
AC_CHECK_HEADERS([sys/eventfd.h])
|
||||
AC_CHECK_FUNCS(eventfd)
|
||||
AC_CHECK_FUNCS(posix_fadvise)
|
||||
AC_CHECK_FUNCS(strptime)
|
||||
AC_CHECK_FUNCS(strtok_r)
|
||||
|
|
|
@ -44,6 +44,11 @@
|
|||
# include <sys/event.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD)
|
||||
# define USE_EVENTFD
|
||||
# include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
#include <event.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
@ -68,7 +73,11 @@ struct stacked_dir {
|
|||
};
|
||||
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
static int exit_efd;
|
||||
#else
|
||||
static int exit_pipe[2];
|
||||
#endif
|
||||
static int scan_exit;
|
||||
static int inofd;
|
||||
static struct event_base *evbase_scan;
|
||||
|
@ -1231,17 +1240,27 @@ filescanner_init(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
ret = pipe2(exit_pipe, O_CLOEXEC);
|
||||
#ifdef USE_EVENTFD
|
||||
exit_efd = eventfd(0, EFD_CLOEXEC);
|
||||
if (exit_efd < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_SCAN, "Could not create eventfd: %s\n", strerror(errno));
|
||||
|
||||
goto pipe_fail;
|
||||
}
|
||||
#else
|
||||
# if defined(__linux__)
|
||||
ret = pipe2(exit_pipe, O_CLOEXEC);
|
||||
# else
|
||||
ret = pipe(exit_pipe);
|
||||
#endif
|
||||
# endif
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_SCAN, "Could not create pipe: %s\n", strerror(errno));
|
||||
|
||||
goto pipe_fail;
|
||||
}
|
||||
#endif /* USE_EVENTFD */
|
||||
|
||||
#if defined(__linux__)
|
||||
inofd = inotify_init1(IN_CLOEXEC);
|
||||
|
@ -1269,7 +1288,11 @@ filescanner_init(void)
|
|||
|
||||
event_base_set(evbase_scan, &inoev);
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
event_set(&exitev, exit_efd, EV_READ, exit_cb, NULL);
|
||||
#else
|
||||
event_set(&exitev, exit_pipe[0], EV_READ, exit_cb, NULL);
|
||||
#endif
|
||||
event_base_set(evbase_scan, &exitev);
|
||||
event_add(&exitev, NULL);
|
||||
|
||||
|
@ -1286,8 +1309,12 @@ filescanner_init(void)
|
|||
thread_fail:
|
||||
close(inofd);
|
||||
ino_fail:
|
||||
#ifdef USE_EVENTFD
|
||||
close(exit_efd);
|
||||
#else
|
||||
close(exit_pipe[0]);
|
||||
close(exit_pipe[1]);
|
||||
#endif
|
||||
pipe_fail:
|
||||
event_base_free(evbase_scan);
|
||||
|
||||
|
@ -1298,9 +1325,19 @@ filescanner_init(void)
|
|||
void
|
||||
filescanner_deinit(void)
|
||||
{
|
||||
int dummy = 42;
|
||||
int ret;
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
ret = eventfd_write(exit_efd, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_SCAN, "Could not send exit event: %s\n", strerror(errno));
|
||||
|
||||
return;
|
||||
}
|
||||
#else
|
||||
int dummy = 42;
|
||||
|
||||
ret = write(exit_pipe[1], &dummy, sizeof(dummy));
|
||||
if (ret != sizeof(dummy))
|
||||
{
|
||||
|
@ -1308,6 +1345,7 @@ filescanner_deinit(void)
|
|||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = pthread_join(tid_scan, NULL);
|
||||
if (ret != 0)
|
||||
|
@ -1317,8 +1355,12 @@ filescanner_deinit(void)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
close(exit_efd);
|
||||
#else
|
||||
close(exit_pipe[0]);
|
||||
close(exit_pipe[1]);
|
||||
#endif
|
||||
close(inofd);
|
||||
event_base_free(evbase_scan);
|
||||
}
|
||||
|
|
50
src/httpd.c
50
src/httpd.c
|
@ -36,6 +36,11 @@
|
|||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD)
|
||||
# define USE_EVENTFD
|
||||
# include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
#include <event.h>
|
||||
#include "evhttp/evhttp.h"
|
||||
|
||||
|
@ -107,7 +112,11 @@ static struct content_type_map ext2ctype[] =
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
static int exit_efd;
|
||||
#else
|
||||
static int exit_pipe[2];
|
||||
#endif
|
||||
static int httpd_exit;
|
||||
static struct event_base *evbase_httpd;
|
||||
static struct event exitev;
|
||||
|
@ -1104,17 +1113,27 @@ httpd_init(void)
|
|||
goto dacp_fail;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
ret = pipe2(exit_pipe, O_CLOEXEC);
|
||||
#ifdef USE_EVENTFD
|
||||
exit_efd = eventfd(0, EFD_CLOEXEC);
|
||||
if (exit_efd < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_HTTPD, "Could not create eventfd: %s\n", strerror(errno));
|
||||
|
||||
goto pipe_fail;
|
||||
}
|
||||
#else
|
||||
# if defined(__linux__)
|
||||
ret = pipe2(exit_pipe, O_CLOEXEC);
|
||||
# else
|
||||
ret = pipe(exit_pipe);
|
||||
#endif
|
||||
# endif
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_HTTPD, "Could not create pipe: %s\n", strerror(errno));
|
||||
|
||||
goto pipe_fail;
|
||||
}
|
||||
#endif /* USE_EVENTFD */
|
||||
|
||||
evbase_httpd = event_base_new();
|
||||
if (!evbase_httpd)
|
||||
|
@ -1124,7 +1143,11 @@ httpd_init(void)
|
|||
goto evbase_fail;
|
||||
}
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
event_set(&exitev, exit_efd, EV_READ, exit_cb, NULL);
|
||||
#else
|
||||
event_set(&exitev, exit_pipe[0], EV_READ, exit_cb, NULL);
|
||||
#endif
|
||||
event_base_set(evbase_httpd, &exitev);
|
||||
event_add(&exitev, NULL);
|
||||
|
||||
|
@ -1172,8 +1195,12 @@ httpd_init(void)
|
|||
evhttp_fail:
|
||||
event_base_free(evbase_httpd);
|
||||
evbase_fail:
|
||||
#ifdef USE_EVENTFD
|
||||
close(exit_efd);
|
||||
#else
|
||||
close(exit_pipe[0]);
|
||||
close(exit_pipe[1]);
|
||||
#endif
|
||||
pipe_fail:
|
||||
dacp_deinit();
|
||||
dacp_fail:
|
||||
|
@ -1188,9 +1215,19 @@ httpd_init(void)
|
|||
void
|
||||
httpd_deinit(void)
|
||||
{
|
||||
int dummy = 42;
|
||||
int ret;
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
ret = eventfd_write(exit_efd, 1);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_HTTPD, "Could not send exit event: %s\n", strerror(errno));
|
||||
|
||||
return;
|
||||
}
|
||||
#else
|
||||
int dummy = 42;
|
||||
|
||||
ret = write(exit_pipe[1], &dummy, sizeof(dummy));
|
||||
if (ret != sizeof(dummy))
|
||||
{
|
||||
|
@ -1198,6 +1235,7 @@ httpd_deinit(void)
|
|||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = pthread_join(tid_httpd, NULL);
|
||||
if (ret != 0)
|
||||
|
@ -1211,8 +1249,12 @@ httpd_deinit(void)
|
|||
dacp_deinit();
|
||||
daap_deinit();
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
close(exit_efd);
|
||||
#else
|
||||
close(exit_pipe[0]);
|
||||
close(exit_pipe[1]);
|
||||
#endif
|
||||
evhttp_free(evhttpd);
|
||||
event_base_free(evbase_httpd);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@
|
|||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD)
|
||||
# define USE_EVENTFD
|
||||
# include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
#include <avahi-common/malloc.h>
|
||||
|
||||
#include <event.h>
|
||||
|
@ -77,7 +82,11 @@ struct remote_info {
|
|||
/* Main event base, from main.c */
|
||||
extern struct event_base *evbase_main;
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
static int pairing_efd;
|
||||
#else
|
||||
static int pairing_pipe[2];
|
||||
#endif
|
||||
static struct event pairingev;
|
||||
static pthread_mutex_t remote_lck = PTHREAD_MUTEX_INITIALIZER;
|
||||
static struct remote_info *remote_list;
|
||||
|
@ -460,12 +469,20 @@ add_remote_pin_data(char *devname, char *pin)
|
|||
static void
|
||||
kickoff_pairing(void)
|
||||
{
|
||||
#ifdef USE_EVENTFD
|
||||
int ret;
|
||||
|
||||
ret = eventfd_write(pairing_efd, 1);
|
||||
if (ret < 0)
|
||||
DPRINTF(E_LOG, L_REMOTE, "Could not send pairing event: %s\n", strerror(errno));
|
||||
#else
|
||||
int dummy = 42;
|
||||
int ret;
|
||||
|
||||
ret = write(pairing_pipe[1], &dummy, sizeof(dummy));
|
||||
if (ret != sizeof(dummy))
|
||||
DPRINTF(E_LOG, L_REMOTE, "Could not write to pairing fd: %s\n", strerror(errno));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -845,11 +862,24 @@ static void
|
|||
pairing_cb(int fd, short event, void *arg)
|
||||
{
|
||||
struct remote_info *ri;
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
eventfd_t count;
|
||||
int ret;
|
||||
|
||||
ret = eventfd_read(pairing_efd, &count);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_REMOTE, "Could not read event counter: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
int dummy;
|
||||
|
||||
/* Drain the pipe */
|
||||
while (read(pairing_pipe[0], &dummy, sizeof(dummy)) >= 0)
|
||||
; /* EMPTY */
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -886,11 +916,20 @@ remote_pairing_init(void)
|
|||
|
||||
remote_list = NULL;
|
||||
|
||||
#if defined(__linux__)
|
||||
ret = pipe2(pairing_pipe, O_CLOEXEC | O_NONBLOCK);
|
||||
#ifdef USE_EVENTFD
|
||||
pairing_efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
|
||||
if (pairing_efd < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_REMOTE, "Could not create eventfd: %s\n", strerror(errno));
|
||||
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
# if defined(__linux__)
|
||||
ret = pipe2(pairing_pipe, O_CLOEXEC | O_NONBLOCK);
|
||||
# else
|
||||
ret = pipe(pairing_pipe);
|
||||
#endif
|
||||
# endif
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_REMOTE, "Could not create pairing pipe: %s\n", strerror(errno));
|
||||
|
@ -898,7 +937,7 @@ remote_pairing_init(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifndef __linux__
|
||||
# ifndef __linux__
|
||||
ret = fcntl(pairing_pipe[0], F_SETFL, O_NONBLOCK);
|
||||
if (ret < 0)
|
||||
{
|
||||
|
@ -906,7 +945,8 @@ remote_pairing_init(void)
|
|||
|
||||
goto pairing_pipe_fail;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
#endif /* USE_EVENTFD */
|
||||
|
||||
ret = mdns_browse("_touch-remote._tcp", touch_remote_cb);
|
||||
if (ret < 0)
|
||||
|
@ -919,7 +959,11 @@ remote_pairing_init(void)
|
|||
libname = cfg_getstr(cfg_getnsec(cfg, "library", 0), "name");
|
||||
libhash = murmur_hash64(libname, strlen(libname), 0);
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
event_set(&pairingev, pairing_efd, EV_READ, pairing_cb, NULL);
|
||||
#else
|
||||
event_set(&pairingev, pairing_pipe[0], EV_READ, pairing_cb, NULL);
|
||||
#endif
|
||||
event_base_set(evbase_main, &pairingev);
|
||||
event_add(&pairingev, NULL);
|
||||
|
||||
|
@ -929,8 +973,12 @@ remote_pairing_init(void)
|
|||
pairing_pipe_fail:
|
||||
#endif
|
||||
mdns_browse_fail:
|
||||
#ifdef USE_EVENTFD
|
||||
close(pairing_efd);
|
||||
#else
|
||||
close(pairing_pipe[0]);
|
||||
close(pairing_pipe[1]);
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -948,6 +996,10 @@ remote_pairing_deinit(void)
|
|||
free_remote(ri);
|
||||
}
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
close(pairing_efd);
|
||||
#else
|
||||
close(pairing_pipe[0]);
|
||||
close(pairing_pipe[1]);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue