/* * select/poll wake up when a socket is closed, but epoll just removes * the socket from its internal list without notification. */ void mono_thread_pool_remove_socket (int sock) { MonoMList *list; MonoSocketAsyncResult *state; MonoObject *ares; if (socket_io_data.inited == 0) return; EnterCriticalSection (&socket_io_data.io_lock); if (socket_io_data.sock_to_state == NULL) { LeaveCriticalSection (&socket_io_data.io_lock); return; } list = mono_g_hash_table_lookup (socket_io_data.sock_to_state, GINT_TO_POINTER (sock)); if (list) mono_g_hash_table_remove (socket_io_data.sock_to_state, GINT_TO_POINTER (sock)); LeaveCriticalSection (&socket_io_data.io_lock); while (list) { state = (MonoSocketAsyncResult *) mono_mlist_get_data (list); if (state->operation == AIO_OP_RECEIVE) state->operation = AIO_OP_RECV_JUST_CALLBACK; else if (state->operation == AIO_OP_SEND) state->operation = AIO_OP_SEND_JUST_CALLBACK; ares = get_io_event (&list, MONO_POLLIN); threadpool_append_job (&async_io_tp, ares); if (list) { ares = get_io_event (&list, MONO_POLLOUT); threadpool_append_job (&async_io_tp, ares); } } }
MonoAsyncResult * mono_thread_pool_add (MonoObject *target, MonoMethodMessage *msg, MonoDelegate *async_callback, MonoObject *state) { MonoDomain *domain = mono_domain_get (); MonoAsyncResult *ares; ASyncCall *ac; ac = (ASyncCall*)mono_object_new (domain, async_call_klass); MONO_OBJECT_SETREF (ac, msg, msg); MONO_OBJECT_SETREF (ac, state, state); if (async_callback) { ac->cb_method = mono_get_delegate_invoke (((MonoObject *)async_callback)->vtable->klass); MONO_OBJECT_SETREF (ac, cb_target, async_callback); } ares = mono_async_result_new (domain, NULL, ac->state, NULL, (MonoObject*)ac); MONO_OBJECT_SETREF (ares, async_delegate, target); #ifndef DISABLE_SOCKETS if (socket_io_filter (target, state)) { socket_io_add (ares, (MonoSocketAsyncResult *) state); return ares; } #endif threadpool_append_job (&async_tp, (MonoObject *) ares); return ares; }
static void threadpool_clear_queue (ThreadPool *tp, MonoDomain *domain) { MonoObject *obj; MonoMList *other = NULL; MonoCQ *queue = tp->queue; if (!queue) return; while (mono_cq_dequeue (queue, &obj)) { if (obj == NULL) continue; if (obj->vtable->domain != domain) other = mono_mlist_prepend (other, obj); threadpool_jobs_dec (obj); } if (mono_runtime_is_shutting_down ()) return; while (other) { threadpool_append_job (tp, (MonoObject *) mono_mlist_get_data (other)); other = mono_mlist_next (other); } }
static void threadpool_clear_queue (ThreadPool *tp, MonoDomain *domain) { MonoObject *obj; MonoMList *other; other = NULL; while (mono_cq_dequeue (tp->queue, &obj)) { if (obj == NULL) continue; if (obj->vtable->domain != domain) other = mono_mlist_prepend (other, obj); threadpool_jobs_dec (obj); } while (other) { threadpool_append_job (tp, (MonoObject *) mono_mlist_get_data (other)); other = mono_mlist_next (other); } }
static void threadpool_clear_queue (ThreadPool *tp, MonoDomain *domain) { MonoObject *obj; MonoMList *other; int domain_count; other = NULL; domain_count = 0; while (mono_cq_dequeue (tp->queue, &obj)) { if (obj != NULL && obj->vtable->domain == domain) { domain_count++; threadpool_jobs_dec (obj); } else if (obj != NULL) { other = mono_mlist_prepend (other, obj); } } while (other) { threadpool_append_job (tp, (MonoObject *) mono_mlist_get_data (other)); other = mono_mlist_next (other); } }
static MonoMList * process_io_event (MonoMList *list, int event) { MonoSocketAsyncResult *state; MonoMList *oldlist; oldlist = list; state = NULL; while (list) { state = (MonoSocketAsyncResult *) mono_mlist_get_data (list); if (get_event_from_state (state) == event) break; list = mono_mlist_next (list); } if (list != NULL) { oldlist = mono_mlist_remove_item (oldlist, list); EPOLL_DEBUG ("Dispatching event %d on socket %p", event, state->handle); threadpool_append_job (&async_io_tp, (MonoObject *) state); } return oldlist; }