Merge pull request #1698 from ludovic-henry/socket-reorg-2
[mono.git] / mono / metadata / threadpool-ms-io.c
index 9a7669cf99ed3cebdb881fc6e256f42295f87199..772a2fe5c6cef28614acadbf5c93efc698131fc5 100644 (file)
@@ -259,7 +259,7 @@ epoll_init (void)
 #ifdef EPOOL_CLOEXEC
        threadpool_io->epoll.fd = epoll_create1 (EPOLL_CLOEXEC);
 #else
-       threadpool_io->epoll.fd = epoll_create1 (256);
+       threadpool_io->epoll.fd = epoll_create (256);
        fcntl (threadpool_io->epoll.fd, F_SETFD, FD_CLOEXEC);
 #endif
 
@@ -806,7 +806,7 @@ polling_thread (gpointer data)
                }
 
                mono_mutex_lock (&threadpool_io->states_lock);
-               for (i = 0; i < max; ++i) {
+               for (i = 0; i < max && ready > 0; ++i) {
                        MonoMList *list;
                        gboolean created;
                        gint fd;
@@ -830,6 +830,7 @@ polling_thread (gpointer data)
 
                        if (fd == threadpool_io->wakeup_pipes [0]) {
                                polling_thread_drain_wakeup_pipes ();
+                               ready -= 1;
                                continue;
                        }
 
@@ -860,8 +861,7 @@ polling_thread (gpointer data)
                        else
                                mono_g_hash_table_remove (threadpool_io->states, GINT_TO_POINTER (fd));
 
-                       if (-- ready == 0)
-                               break;
+                       ready -= 1;
                }
                mono_mutex_unlock (&threadpool_io->states_lock);
        }
@@ -1062,43 +1062,39 @@ ensure_cleanedup (void)
        io_status = STATUS_CLEANED_UP;
 }
 
-gboolean
-mono_threadpool_ms_is_io (MonoObject *target, MonoObject *state)
+static gboolean
+is_socket_async_callback (MonoImage *system_image, MonoClass *class)
 {
-       static MonoClass *socket_class = NULL;
-       static MonoClass *socket_async_class = NULL;
-       static MonoClass *process_class = NULL;
-       static MonoClass *async_read_handler_class = NULL;
-       MonoClass *class;
-       MonoSocketAsyncResult *sockares;
+       MonoClass *socket_async_callback_class = NULL;
 
-       if (!mono_defaults.system)
-               mono_defaults.system = mono_image_loaded ("System");
-       if (!mono_defaults.system)
-               return FALSE;
-       g_assert (mono_defaults.system);
+       socket_async_callback_class = mono_class_from_name (system_image, "System.Net.Sockets", "SocketAsyncCallback");
+       g_assert (socket_async_callback_class);
+
+       return class == socket_async_callback_class;
+}
 
-       if (!socket_class)
-               socket_class = mono_class_from_name (mono_defaults.system, "System.Net.Sockets", "Socket");
-       g_assert (socket_class);
+static gboolean
+is_async_read_handler (MonoImage *system_image, MonoClass *class)
+{
+       MonoClass *process_class = NULL;
 
-       if (!process_class)
-               process_class = mono_class_from_name (mono_defaults.system, "System.Diagnostics", "Process");
+       process_class = mono_class_from_name (system_image, "System.Diagnostics", "Process");
        g_assert (process_class);
 
-       class = target->vtable->klass;
+       return class->nested_in && class->nested_in == process_class && strcmp (class->name, "AsyncReadHandler") == 0;
+}
 
-       if (!socket_async_class) {
-               if (class->nested_in && class->nested_in == socket_class && strcmp (class->name, "SocketAsyncCall") == 0)
-                       socket_async_class = class;
-       }
+gboolean
+mono_threadpool_ms_is_io (MonoObject *target, MonoObject *state)
+{
+       MonoImage *system_image;
+       MonoSocketAsyncResult *sockares;
 
-       if (!async_read_handler_class) {
-               if (class->nested_in && class->nested_in == process_class && strcmp (class->name, "AsyncReadHandler") == 0)
-                       async_read_handler_class = class;
-       }
+       system_image = mono_image_loaded ("System");
+       if (!system_image)
+               return FALSE;
 
-       if (class != socket_async_class && class != async_read_handler_class)
+       if (!is_socket_async_callback (system_image, target->vtable->klass) && !is_async_read_handler (system_image, target->vtable->klass))
                return FALSE;
 
        sockares = (MonoSocketAsyncResult*) state;
@@ -1237,17 +1233,16 @@ mono_threadpool_ms_io_remove_domain_jobs (MonoDomain *domain)
 void
 mono_threadpool_io_enqueue_socket_async_result (MonoDomain *domain, MonoSocketAsyncResult *sockares)
 {
-       static MonoClass *socket_runtime_work_item_class = NULL;
+       MonoImage *system_image;
+       MonoClass *socket_runtime_work_item_class;
        MonoSocketRuntimeWorkItem *srwi;
 
        g_assert (sockares);
 
-       if (!mono_defaults.system)
-               mono_defaults.system = mono_image_loaded ("System");
-       g_assert (mono_defaults.system);
+       system_image = mono_image_loaded ("System");
+       g_assert (system_image);
 
-       if (!socket_runtime_work_item_class)
-               socket_runtime_work_item_class = mono_class_from_name (mono_defaults.system, "System.Net.Sockets", "MonoSocketRuntimeWorkItem");
+       socket_runtime_work_item_class = mono_class_from_name (system_image, "System.Net.Sockets", "MonoSocketRuntimeWorkItem");
        g_assert (socket_runtime_work_item_class);
 
        srwi = (MonoSocketRuntimeWorkItem*) mono_object_new (domain, socket_runtime_work_item_class);