Skip to content

Commit

Permalink
[threadpool-ms-io] Remove socket synchronously from backend when clos…
Browse files Browse the repository at this point in the history
…ing socket

To achieve this, we need to wait for the update to be applied to the backend.

This is mainly for the epoll backend, as we do not need to remove the fd from the backend when using kqueue.
  • Loading branch information
luhenry committed Jul 20, 2015
1 parent 5ea5df6 commit fa26493
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 133 deletions.
50 changes: 17 additions & 33 deletions mono/metadata/threadpool-ms-io-epoll.c
Expand Up @@ -13,17 +13,6 @@
static gint epoll_fd;
static struct epoll_event *epoll_events;

static inline void
EPOLL_INIT_EVENT (struct epoll_event *event, gint fd, gint events)
{
event->data.fd = fd;
event->events = EPOLLONESHOT;
if ((events & MONO_POLLIN) != 0)
event->events |= EPOLLIN;
if ((events & MONO_POLLOUT) != 0)
event->events |= EPOLLOUT;
}

static gboolean
epoll_init (gint wakeup_pipe_fd)
{
Expand Down Expand Up @@ -66,13 +55,24 @@ epoll_cleanup (void)
}

static void
epoll_update_add (gint fd, gint events, gboolean is_new)
epoll_register_fd (gint fd, gint events, gboolean is_new)
{
struct epoll_event event;
EPOLL_INIT_EVENT (&event, fd, events);
if (events == 0) {
if (!is_new && epoll_ctl (epoll_fd, EPOLL_CTL_DEL, fd, NULL) == -1)
g_error ("epoll_register_fd: epoll_ctl (EPOLL_CTL_DEL) failed, error (%d) %s", errno, g_strerror (errno));
} else {
struct epoll_event event;

if (epoll_ctl (epoll_fd, is_new ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, event.data.fd, &event) == -1)
g_error ("epoll_update_add: epoll_ctl(%s) failed, error (%d) %s", is_new ? "EPOLL_CTL_ADD" : "EPOLL_CTL_MOD", errno, g_strerror (errno));
event.data.fd = fd;
event.events = EPOLLONESHOT;
if ((events & MONO_POLLIN) != 0)
event.events |= EPOLLIN;
if ((events & MONO_POLLOUT) != 0)
event.events |= EPOLLOUT;

if (epoll_ctl (epoll_fd, is_new ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, event.data.fd, &event) == -1)
g_error ("epoll_register_fd: epoll_ctl(%s) failed, error (%d) %s", is_new ? "EPOLL_CTL_ADD" : "EPOLL_CTL_MOD", errno, g_strerror (errno));
}
}

static gint
Expand Down Expand Up @@ -115,29 +115,13 @@ epoll_event_get_fd_at (gint i, gint *events)
return epoll_events [i].data.fd;
}

static void
epoll_event_reset_fd_at (gint i, gint events)
{
if (events == 0) {
if (epoll_ctl (epoll_fd, EPOLL_CTL_DEL, epoll_events [i].data.fd, NULL) == -1)
g_error ("epoll_event_reset_fd_at: epoll_ctl (EPOLL_CTL_DEL) failed, error (%d) %s", errno, g_strerror (errno));
} else {
struct epoll_event event;
EPOLL_INIT_EVENT (&event, epoll_events [i].data.fd, events);

if (epoll_ctl (epoll_fd, EPOLL_CTL_MOD, event.data.fd, &event) == -1)
g_error ("epoll_event_reset_fd_at: epoll_ctl (EPOLL_CTL_MOD) failed, error (%d) %s", errno, g_strerror (errno));
}
}

static ThreadPoolIOBackend backend_epoll = {
.init = epoll_init,
.cleanup = epoll_cleanup,
.update_add = epoll_update_add,
.register_fd = epoll_register_fd,
.event_wait = epoll_event_wait,
.event_get_fd_max = epoll_event_get_fd_max,
.event_get_fd_at = epoll_event_get_fd_at,
.event_reset_fd_at = epoll_event_reset_fd_at,
};

#endif
27 changes: 6 additions & 21 deletions mono/metadata/threadpool-ms-io-kqueue.c
Expand Up @@ -46,17 +46,20 @@ kqueue_cleanup (void)
}

static void
kqueue_update_add (gint fd, gint events, gboolean is_new)
kqueue_register_fd (gint fd, gint events, gboolean is_new)
{
struct kevent event;

if (events == 0)
return;

if ((events & MONO_POLLIN) != 0)
EV_SET (&event, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
if ((events & MONO_POLLOUT) != 0)
EV_SET (&event, fd, EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);

if (kevent (kqueue_fd, &event, 1, NULL, 0, NULL) == -1)
g_warning ("kqueue_update_add: kevent(update) failed, error (%d) %s", errno, g_strerror (errno));
g_warning ("kqueue_register_fd: kevent(update) failed, error (%d) %s", errno, g_strerror (errno));
}

static gint
Expand Down Expand Up @@ -97,31 +100,13 @@ kqueue_event_get_fd_max (void)
return KQUEUE_NEVENTS;
}

static void
kqueue_event_reset_fd_at (gint i, gint events)
{
if (kqueue_events [i].filter == EVFILT_READ && (events & MONO_POLLIN) != 0) {
EV_SET (&kqueue_events [i], kqueue_events [i].ident, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
if (kevent (kqueue_fd, &kqueue_events [i], 1, NULL, 0, NULL) == -1) {
g_warning ("kqueue_event_reset_fd_at: kevent (read) failed, error (%d) %s", errno, g_strerror (errno));
}
}
if (kqueue_events [i].filter == EVFILT_WRITE && (events & MONO_POLLOUT) != 0) {
EV_SET (&kqueue_events [i], kqueue_events [i].ident, EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
if (kevent (kqueue_fd, &kqueue_events [i], 1, NULL, 0, NULL) == -1) {
g_warning ("kqueue_event_reset_fd_at: kevent (write) failed, error (%d) %s", errno, g_strerror (errno));
}
}
}

static ThreadPoolIOBackend backend_kqueue = {
.init = kqueue_init,
.cleanup = kqueue_cleanup,
.update_add = kqueue_update_add,
.register_fd = kqueue_register_fd,
.event_wait = kqueue_event_wait,
.event_get_fd_max = kqueue_event_get_fd_max,
.event_get_fd_at = kqueue_event_get_fd_at,
.event_reset_fd_at = kqueue_event_reset_fd_at,
};

#endif
20 changes: 8 additions & 12 deletions mono/metadata/threadpool-ms-io-poll.c
Expand Up @@ -68,7 +68,7 @@ poll_mark_bad_fds (mono_pollfd *poll_fds, gint poll_fds_size)
}

static void
poll_update_add (gint fd, gint events, gboolean is_new)
poll_register_fd (gint fd, gint events, gboolean is_new)
{
gboolean found = FALSE;
gint j, k;
Expand All @@ -81,6 +81,12 @@ poll_update_add (gint fd, gint events, gboolean is_new)
}
}

if (events == 0) {
if (found)
POLL_INIT_FD (poll_fds + j, -1, 0);
return;
}

if (!found) {
for (j = 1; j < poll_fds_capacity; ++j) {
mono_pollfd *poll_fd = poll_fds + j;
Expand Down Expand Up @@ -175,21 +181,11 @@ poll_event_get_fd_max (void)
return poll_fds_size;
}

static void
poll_event_reset_fd_at (gint i, gint events)
{
g_assert (poll_fds [i].fd != -1);
g_assert (poll_fds [i].revents != 0);

POLL_INIT_FD (&poll_fds [i], events == 0 ? -1 : poll_fds [i].fd, events);
}

static ThreadPoolIOBackend backend_poll = {
.init = poll_init,
.cleanup = poll_cleanup,
.update_add = poll_update_add,
.register_fd = poll_register_fd,
.event_wait = poll_event_wait,
.event_get_fd_max = poll_event_get_fd_max,
.event_get_fd_at = poll_event_get_fd_at,
.event_reset_fd_at = poll_event_reset_fd_at,
};

0 comments on commit fa26493

Please sign in to comment.