X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fthreadpool-ms-io-epoll.c;h=462fa98df8143115552eeb48bc32c6e21813a529;hb=07b2a10491496316c18a442effd4484c2dadc85d;hp=eb18b3e98e6ae590da09a16686dde0928516a624;hpb=a7c3e83d98f6ec4b80ca5925b9a8301a7c069780;p=mono.git diff --git a/mono/metadata/threadpool-ms-io-epoll.c b/mono/metadata/threadpool-ms-io-epoll.c index eb18b3e98e6..462fa98df81 100644 --- a/mono/metadata/threadpool-ms-io-epoll.c +++ b/mono/metadata/threadpool-ms-io-epoll.c @@ -27,9 +27,9 @@ epoll_init (gint wakeup_pipe_fd) if (epoll_fd == -1) { #ifdef EPOOL_CLOEXEC - g_warning ("epoll_init: epoll (EPOLL_CLOEXEC) failed, error (%d) %s\n", errno, g_strerror (errno)); + g_error ("epoll_init: epoll (EPOLL_CLOEXEC) failed, error (%d) %s\n", errno, g_strerror (errno)); #else - g_warning ("epoll_init: epoll (256) failed, error (%d) %s\n", errno, g_strerror (errno)); + g_error ("epoll_init: epoll (256) failed, error (%d) %s\n", errno, g_strerror (errno)); #endif return FALSE; } @@ -37,7 +37,7 @@ epoll_init (gint wakeup_pipe_fd) event.events = EPOLLIN; event.data.fd = wakeup_pipe_fd; if (epoll_ctl (epoll_fd, EPOLL_CTL_ADD, event.data.fd, &event) == -1) { - g_warning ("epoll_init: epoll_ctl () failed, error (%d) %s", errno, g_strerror (errno)); + g_error ("epoll_init: epoll_ctl () failed, error (%d) %s", errno, g_strerror (errno)); close (epoll_fd); return FALSE; } @@ -48,33 +48,46 @@ epoll_init (gint wakeup_pipe_fd) } static void -epoll_cleanup (void) -{ - g_free (epoll_events); - close (epoll_fd); -} - -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; +#ifndef EPOLLONESHOT +/* it was only defined on android in May 2013 */ +#define EPOLLONESHOT 0x40000000 +#endif + event.data.fd = fd; - if ((events & MONO_POLLIN) != 0) + event.events = EPOLLONESHOT; + if ((events & EVENT_IN) != 0) event.events |= EPOLLIN; - if ((events & MONO_POLLOUT) != 0) + if ((events & EVENT_OUT) != 0) event.events |= EPOLLOUT; if (epoll_ctl (epoll_fd, is_new ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, event.data.fd, &event) == -1) - g_warning ("epoll_update_add: epoll_ctl(%s) failed, error (%d) %s", is_new ? "EPOLL_CTL_ADD" : "EPOLL_CTL_MOD", errno, g_strerror (errno)); + 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 void +epoll_remove_fd (gint fd) +{ + if (epoll_ctl (epoll_fd, EPOLL_CTL_DEL, fd, NULL) == -1) + g_error ("epoll_remove_fd: epoll_ctl (EPOLL_CTL_DEL) failed, error (%d) %s", errno, g_strerror (errno)); } static gint -epoll_event_wait (void) +epoll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data) { - gint ready; + gint i, ready; + + memset (epoll_events, 0, sizeof (struct epoll_event) * EPOLL_NEVENTS); + + mono_gc_set_skip_thread (TRUE); ready = epoll_wait (epoll_fd, epoll_events, EPOLL_NEVENTS, -1); + + mono_gc_set_skip_thread (FALSE); + if (ready == -1) { switch (errno) { case EINTR: @@ -82,54 +95,34 @@ epoll_event_wait (void) ready = 0; break; default: - g_warning ("epoll_event_wait: epoll_wait () failed, error (%d) %s", errno, g_strerror (errno)); + g_error ("epoll_event_wait: epoll_wait () failed, error (%d) %s", errno, g_strerror (errno)); break; } } - return ready; -} + if (ready == -1) + return -1; -static gint -epoll_event_get_fd_max (void) -{ - return EPOLL_NEVENTS; -} + for (i = 0; i < ready; ++i) { + gint fd, events = 0; -static gint -epoll_event_get_fd_at (gint i, gint *events) -{ - g_assert (events); + fd = epoll_events [i].data.fd; + if (epoll_events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP)) + events |= EVENT_IN; + if (epoll_events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) + events |= EVENT_OUT; - *events = ((epoll_events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP)) ? MONO_POLLIN : 0) - | ((epoll_events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) ? MONO_POLLOUT : 0); - - 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, &epoll_events [i]) == -1) - g_warning ("epoll_event_reset_fd_at: epoll_ctl (EPOLL_CTL_DEL) failed, error (%d) %s", errno, g_strerror (errno)); - } else { - epoll_events [i].events = ((events & MONO_POLLOUT) ? EPOLLOUT : 0) - | ((events & MONO_POLLIN) ? EPOLLIN : 0); - - if (epoll_ctl (epoll_fd, EPOLL_CTL_MOD, epoll_events [i].data.fd, &epoll_events [i]) == -1) - g_warning ("epoll_event_get_ioares_at: epoll_ctl (EPOLL_CTL_MOD) failed, error (%d) %s", errno, g_strerror (errno)); + callback (fd, events, user_data); } + + return 0; } static ThreadPoolIOBackend backend_epoll = { .init = epoll_init, - .cleanup = epoll_cleanup, - .update_add = epoll_update_add, + .register_fd = epoll_register_fd, + .remove_fd = epoll_remove_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