mirror of
https://github.com/libevent/libevent.git
synced 2025-01-09 00:56:20 +08:00
Use a wrapper function to create the notification pipe/socketpair/eventfd
This commit is contained in:
parent
4970329a88
commit
ca76cd931f
63
event.c
63
event.c
@ -46,9 +46,6 @@
|
|||||||
#ifdef _EVENT_HAVE_UNISTD_H
|
#ifdef _EVENT_HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef _EVENT_HAVE_SYS_EVENTFD_H
|
|
||||||
#include <sys/eventfd.h>
|
|
||||||
#endif
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -2948,8 +2945,8 @@ evthread_notify_drain_default(evutil_socket_t fd, short what, void *arg)
|
|||||||
int
|
int
|
||||||
evthread_make_base_notifiable(struct event_base *base)
|
evthread_make_base_notifiable(struct event_base *base)
|
||||||
{
|
{
|
||||||
void (*cb)(evutil_socket_t, short, void *) = evthread_notify_drain_default;
|
void (*cb)(evutil_socket_t, short, void *);
|
||||||
int (*notify)(struct event_base *) = evthread_notify_base_default;
|
int (*notify)(struct event_base *);
|
||||||
|
|
||||||
/* XXXX grab the lock here? */
|
/* XXXX grab the lock here? */
|
||||||
if (!base)
|
if (!base)
|
||||||
@ -2960,61 +2957,21 @@ evthread_make_base_notifiable(struct event_base *base)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_EVENT_HAVE_EVENTFD) && defined(_EVENT_HAVE_SYS_EVENTFD_H)
|
base->th_notify_fd[0] = evutil_eventfd(0,
|
||||||
#ifndef EFD_CLOEXEC
|
EVUTIL_EFD_CLOEXEC|EVUTIL_EFD_NONBLOCK);
|
||||||
#define EFD_CLOEXEC 0
|
|
||||||
#endif
|
|
||||||
base->th_notify_fd[0] = eventfd(0, EFD_CLOEXEC);
|
|
||||||
if (base->th_notify_fd[0] >= 0) {
|
if (base->th_notify_fd[0] >= 0) {
|
||||||
evutil_make_socket_closeonexec(base->th_notify_fd[0]);
|
base->th_notify_fd[1] = -1;
|
||||||
notify = evthread_notify_base_eventfd;
|
notify = evthread_notify_base_eventfd;
|
||||||
cb = evthread_notify_drain_eventfd;
|
cb = evthread_notify_drain_eventfd;
|
||||||
|
} else if (evutil_make_internal_pipe(base->th_notify_fd) == 0) {
|
||||||
|
notify = evthread_notify_base_default;
|
||||||
|
cb = evthread_notify_drain_default;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if defined(_EVENT_HAVE_PIPE)
|
|
||||||
if (base->th_notify_fd[0] < 0) {
|
|
||||||
if ((base->evsel->features & EV_FEATURE_FDS)) {
|
|
||||||
if (pipe(base->th_notify_fd) < 0) {
|
|
||||||
event_warn("%s: pipe", __func__);
|
|
||||||
} else {
|
|
||||||
evutil_make_socket_closeonexec(base->th_notify_fd[0]);
|
|
||||||
evutil_make_socket_closeonexec(base->th_notify_fd[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define LOCAL_SOCKETPAIR_AF AF_INET
|
|
||||||
#else
|
|
||||||
#define LOCAL_SOCKETPAIR_AF AF_UNIX
|
|
||||||
#endif
|
|
||||||
if (base->th_notify_fd[0] < 0) {
|
|
||||||
if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0,
|
|
||||||
base->th_notify_fd) == -1) {
|
|
||||||
event_sock_warn(-1, "%s: socketpair", __func__);
|
|
||||||
return (-1);
|
|
||||||
} else {
|
|
||||||
evutil_make_socket_closeonexec(base->th_notify_fd[0]);
|
|
||||||
evutil_make_socket_closeonexec(base->th_notify_fd[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
evutil_make_socket_nonblocking(base->th_notify_fd[0]);
|
|
||||||
|
|
||||||
base->th_notify_fn = notify;
|
base->th_notify_fn = notify;
|
||||||
|
|
||||||
/*
|
|
||||||
Making the second socket nonblocking is a bit subtle, given that we
|
|
||||||
ignore any EAGAIN returns when writing to it, and you don't usally
|
|
||||||
do that for a nonblocking socket. But if the kernel gives us EAGAIN,
|
|
||||||
then there's no need to add any more data to the buffer, since
|
|
||||||
the main thread is already either about to wake up and drain it,
|
|
||||||
or woken up and in the process of draining it.
|
|
||||||
*/
|
|
||||||
if (base->th_notify_fd[1] > 0)
|
|
||||||
evutil_make_socket_nonblocking(base->th_notify_fd[1]);
|
|
||||||
|
|
||||||
/* prepare an event that we can use for wakeup */
|
/* prepare an event that we can use for wakeup */
|
||||||
event_assign(&base->th_notify, base, base->th_notify_fd[0],
|
event_assign(&base->th_notify, base, base->th_notify_fd[0],
|
||||||
EV_READ|EV_PERSIST, cb, base);
|
EV_READ|EV_PERSIST, cb, base);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user