Skip to content

Commit

Permalink
Merge remote-tracking branch 'github/21_fast_syscalls'
Browse files Browse the repository at this point in the history
  • Loading branch information
nmathewson committed Feb 16, 2012
2 parents a63ed16 + 2b0a2c4 commit a220a08
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 107 deletions.
5 changes: 2 additions & 3 deletions bufferevent_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,10 @@ bufferevent_socket_connect(struct bufferevent *bev,
if (fd < 0) {
if (!sa)
goto done;
fd = socket(sa->sa_family, SOCK_STREAM, 0);
fd = evutil_socket(sa->sa_family,
SOCK_STREAM|EVUTIL_SOCK_NONBLOCK, 0);
if (fd < 0)
goto done;
if (evutil_make_socket_nonblocking(fd)<0)
goto done;
ownfd = 1;
}
if (sa) {
Expand Down
3 changes: 3 additions & 0 deletions configure.in
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,12 @@ AC_HEADER_TIME

dnl Checks for library functions.
AC_CHECK_FUNCS([ \
accept4 \
arc4random \
arc4random_buf \
clock_gettime \
eventfd \
epoll_create1 \
fcntl \
getegid \
geteuid \
Expand All @@ -329,6 +331,7 @@ AC_CHECK_FUNCS([ \
mmap \
nanosleep \
pipe \
pipe2 \
putenv \
sendfile \
setenv \
Expand Down
23 changes: 14 additions & 9 deletions epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,24 @@ const struct eventop epollops = {
static void *
epoll_init(struct event_base *base)
{
int epfd;
int epfd = -1;
struct epollop *epollop;

/* Initialize the kernel queue. (The size field is ignored since
* 2.6.8.) */
if ((epfd = epoll_create(32000)) == -1) {
if (errno != ENOSYS)
event_warn("epoll_create");
return (NULL);
#ifdef _EVENT_HAVE_EPOLL_CREATE1
/* First, try the shiny new epoll_create1 interface, if we have it. */
epfd = epoll_create1(EPOLL_CLOEXEC);
#endif
if (epfd == -1) {
/* Initialize the kernel queue using the old interface. (The
size field is ignored since 2.6.8.) */
if ((epfd = epoll_create(32000)) == -1) {
if (errno != ENOSYS)
event_warn("epoll_create");
return (NULL);
}
evutil_make_socket_closeonexec(epfd);
}

evutil_make_socket_closeonexec(epfd);

if (!(epollop = mm_calloc(1, sizeof(struct epollop)))) {
close(epfd);
return (NULL);
Expand Down
5 changes: 2 additions & 3 deletions evdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -2458,10 +2458,9 @@ _evdns_nameserver_add_impl(struct evdns_base *base, const struct sockaddr *addre

evtimer_assign(&ns->timeout_event, ns->base->event_base, nameserver_prod_callback, ns);

ns->socket = socket(address->sa_family, SOCK_DGRAM, 0);
ns->socket = evutil_socket(address->sa_family,
SOCK_DGRAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
if (ns->socket < 0) { err = 1; goto out1; }
evutil_make_socket_closeonexec(ns->socket);
evutil_make_socket_nonblocking(ns->socket);

if (base->global_outgoing_addrlen &&
!evutil_sockaddr_is_loopback(address)) {
Expand Down
67 changes: 10 additions & 57 deletions event.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@
#ifdef _EVENT_HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef _EVENT_HAVE_SYS_EVENTFD_H
#include <sys/eventfd.h>
#endif
#include <ctype.h>
#include <errno.h>
#include <signal.h>
Expand Down Expand Up @@ -2118,7 +2115,6 @@ evthread_notify_base_default(struct event_base *base)
return (r < 0 && errno != EAGAIN) ? -1 : 0;
}

#if defined(_EVENT_HAVE_EVENTFD) && defined(_EVENT_HAVE_SYS_EVENTFD_H)
/* Helper callback: wake an event_base from another thread. This version
* assumes that you have a working eventfd() implementation. */
static int
Expand All @@ -2132,7 +2128,6 @@ evthread_notify_base_eventfd(struct event_base *base)

return (r < 0) ? -1 : 0;
}
#endif

/** Tell the thread currently running the event_loop for base (if any) that it
* needs to stop waiting in its dispatch function (if it is) and process all
Expand Down Expand Up @@ -2910,7 +2905,6 @@ event_set_mem_functions(void *(*malloc_fn)(size_t sz),
}
#endif

#if defined(_EVENT_HAVE_EVENTFD) && defined(_EVENT_HAVE_SYS_EVENTFD_H)
static void
evthread_notify_drain_eventfd(evutil_socket_t fd, short what, void *arg)
{
Expand All @@ -2926,7 +2920,6 @@ evthread_notify_drain_eventfd(evutil_socket_t fd, short what, void *arg)
base->is_notify_pending = 0;
EVBASE_RELEASE_LOCK(base, th_base_lock);
}
#endif

static void
evthread_notify_drain_default(evutil_socket_t fd, short what, void *arg)
Expand All @@ -2949,8 +2942,8 @@ evthread_notify_drain_default(evutil_socket_t fd, short what, void *arg)
int
evthread_make_base_notifiable(struct event_base *base)
{
void (*cb)(evutil_socket_t, short, void *) = evthread_notify_drain_default;
int (*notify)(struct event_base *) = evthread_notify_base_default;
void (*cb)(evutil_socket_t, short, void *);
int (*notify)(struct event_base *);

/* XXXX grab the lock here? */
if (!base)
Expand All @@ -2961,61 +2954,21 @@ evthread_make_base_notifiable(struct event_base *base)
return 0;
}

#if defined(_EVENT_HAVE_EVENTFD) && defined(_EVENT_HAVE_SYS_EVENTFD_H)
#ifndef EFD_CLOEXEC
#define EFD_CLOEXEC 0
#endif
base->th_notify_fd[0] = eventfd(0, EFD_CLOEXEC);
base->th_notify_fd[0] = evutil_eventfd(0,
EVUTIL_EFD_CLOEXEC|EVUTIL_EFD_NONBLOCK);
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;
cb = evthread_notify_drain_eventfd;
}
#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]);
}
} else if (evutil_make_internal_pipe(base->th_notify_fd) == 0) {
notify = evthread_notify_base_default;
cb = evthread_notify_drain_default;
} else {
return -1;
}

evutil_make_socket_nonblocking(base->th_notify_fd[0]);

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 */
event_assign(&base->th_notify, base, base->th_notify_fd[0],
EV_READ|EV_PERSIST, cb, base);
Expand Down
Loading

0 comments on commit a220a08

Please sign in to comment.