static void socket_io_cleanup (SocketIOData *data) { if (data->inited == 0) return; EnterCriticalSection (&data->io_lock); data->inited = 0; #ifdef HOST_WIN32 closesocket (data->pipe [0]); closesocket (data->pipe [1]); #else close (data->pipe [0]); close (data->pipe [1]); #endif data->pipe [0] = -1; data->pipe [1] = -1; if (data->new_sem) CloseHandle (data->new_sem); data->new_sem = NULL; mono_g_hash_table_destroy (data->sock_to_state); data->sock_to_state = NULL; g_free (data->newpfd); data->newpfd = NULL; #ifdef HAVE_EPOLL if (FALSE == data->epoll_disabled) close (data->epollfd); #endif LeaveCriticalSection (&data->io_lock); }
static void release_hashtable (MonoGHashTable **hash) { if (*hash) { mono_g_hash_table_destroy (*hash); *hash = NULL; } }
static void selector_thread (gpointer data) { MonoGHashTable *states; io_selector_running = TRUE; if (mono_runtime_is_shutting_down ()) { io_selector_running = FALSE; return; } states = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_THREAD_POOL, "i/o thread pool states table"); for (;;) { gint i, j; gint res; mono_mutex_lock (&threadpool_io->updates_lock); for (i = 0; i < threadpool_io->updates_size; ++i) { ThreadPoolIOUpdate *update = &threadpool_io->updates [i]; switch (update->type) { case UPDATE_EMPTY: break; case UPDATE_ADD: { gint fd; gint operations; gpointer k; gboolean exists; MonoMList *list = NULL; MonoIOSelectorJob *job; fd = update->data.add.fd; g_assert (fd >= 0); job = update->data.add.job; g_assert (job); exists = mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list); list = mono_mlist_append (list, (MonoObject*) job); mono_g_hash_table_replace (states, GINT_TO_POINTER (fd), list); operations = get_operations_for_jobs (list); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: %3s fd %3d, operations = %2s | %2s | %2s", exists ? "mod" : "add", fd, (operations & EVENT_IN) ? "RD" : "..", (operations & EVENT_OUT) ? "WR" : ".."); threadpool_io->backend.register_fd (fd, operations, !exists); break; } case UPDATE_REMOVE_SOCKET: { gint fd; gpointer k; MonoMList *list = NULL; fd = update->data.remove_socket.fd; g_assert (fd >= 0); if (mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list)) { mono_g_hash_table_remove (states, GINT_TO_POINTER (fd)); for (j = i + 1; j < threadpool_io->updates_size; ++j) { ThreadPoolIOUpdate *update = &threadpool_io->updates [j]; if (update->type == UPDATE_ADD && update->data.add.fd == fd) memset (update, 0, sizeof (ThreadPoolIOUpdate)); } for (; list; list = mono_mlist_remove_item (list, list)) mono_threadpool_ms_enqueue_work_item (mono_object_domain (mono_mlist_get_data (list)), mono_mlist_get_data (list)); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: del fd %3d", fd); threadpool_io->backend.remove_fd (fd); } break; } case UPDATE_REMOVE_DOMAIN: { MonoDomain *domain; domain = update->data.remove_domain.domain; g_assert (domain); FilterSockaresForDomainData user_data = { .domain = domain, .states = states }; mono_g_hash_table_foreach (states, filter_jobs_for_domain, &user_data); for (j = i + 1; j < threadpool_io->updates_size; ++j) { ThreadPoolIOUpdate *update = &threadpool_io->updates [j]; if (update->type == UPDATE_ADD && mono_object_domain (update->data.add.job) == domain) memset (update, 0, sizeof (ThreadPoolIOUpdate)); } break; } default: g_assert_not_reached (); } } mono_cond_broadcast (&threadpool_io->updates_cond); if (threadpool_io->updates_size > 0) { threadpool_io->updates_size = 0; memset (&threadpool_io->updates, 0, UPDATES_CAPACITY * sizeof (ThreadPoolIOUpdate)); } mono_mutex_unlock (&threadpool_io->updates_lock); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: wai"); res = threadpool_io->backend.event_wait (wait_callback, states); if (res == -1 || mono_runtime_is_shutting_down ()) break; } mono_g_hash_table_destroy (states); io_selector_running = FALSE; }
// Free dynamic image pass one: Free resources but not image itself void mono_dynamic_image_free (MonoDynamicImage *image) { MonoDynamicImage *di = image; GList *list; int i; if (di->typespec) g_hash_table_destroy (di->typespec); if (di->typeref) g_hash_table_destroy (di->typeref); if (di->handleref) g_hash_table_destroy (di->handleref); if (di->tokens) mono_g_hash_table_destroy (di->tokens); if (di->remapped_tokens) mono_g_hash_table_destroy (di->remapped_tokens); if (di->generic_def_objects) mono_g_hash_table_destroy (di->generic_def_objects); if (di->blob_cache) { g_hash_table_foreach (di->blob_cache, free_blob_cache_entry, NULL); g_hash_table_destroy (di->blob_cache); } if (di->standalonesig_cache) g_hash_table_destroy (di->standalonesig_cache); for (list = di->array_methods; list; list = list->next) { ArrayMethod *am = (ArrayMethod *)list->data; mono_sre_array_method_free (am); } g_list_free (di->array_methods); if (di->gen_params) { for (i = 0; i < di->gen_params->len; i++) { GenericParamTableEntry *entry = (GenericParamTableEntry *)g_ptr_array_index (di->gen_params, i); mono_sre_generic_param_table_entry_free (entry); } g_ptr_array_free (di->gen_params, TRUE); } if (di->token_fixups) mono_g_hash_table_destroy (di->token_fixups); if (di->method_to_table_idx) g_hash_table_destroy (di->method_to_table_idx); if (di->field_to_table_idx) g_hash_table_destroy (di->field_to_table_idx); if (di->method_aux_hash) g_hash_table_destroy (di->method_aux_hash); if (di->vararg_aux_hash) g_hash_table_destroy (di->vararg_aux_hash); g_free (di->strong_name); g_free (di->win32_res); if (di->public_key) g_free (di->public_key); /*g_print ("string heap destroy for image %p\n", di);*/ mono_dynamic_stream_reset (&di->sheap); mono_dynamic_stream_reset (&di->code); mono_dynamic_stream_reset (&di->resources); mono_dynamic_stream_reset (&di->us); mono_dynamic_stream_reset (&di->blob); mono_dynamic_stream_reset (&di->tstream); mono_dynamic_stream_reset (&di->guid); for (i = 0; i < MONO_TABLE_NUM; ++i) { g_free (di->tables [i].values); } dynamic_images_lock (); if (dynamic_images) g_ptr_array_remove (dynamic_images, di); dynamic_images_unlock (); }