static void socket_io_init (SocketIOData *data) { int inited; if (data->inited >= 2) // 2 -> initialized, 3-> cleaned up return; inited = InterlockedCompareExchange (&data->inited, 1, 0); if (inited >= 1) { while (TRUE) { if (data->inited >= 2) return; SleepEx (1, FALSE); } } EnterCriticalSection (&data->io_lock); data->sock_to_state = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC); #ifdef HAVE_EPOLL data->event_system = EPOLL_BACKEND; #elif defined(HAVE_KQUEUE) data->event_system = KQUEUE_BACKEND; #else data->event_system = POLL_BACKEND; #endif if (g_getenv ("MONO_DISABLE_AIO") != NULL) data->event_system = POLL_BACKEND; init_event_system (data); mono_thread_create_internal (mono_get_root_domain (), data->wait, data, TRUE, SMALL_STACK); LeaveCriticalSection (&data->io_lock); data->inited = 2; threadpool_start_thread (&async_io_tp); }
gpointer ves_icall_System_Threading_StInternalMethods_RegisterHandle_internal (MonoObject *obj) { guint32 handle; if (handles == NULL) { MONO_GC_REGISTER_ROOT_FIXED (handles); handles = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC); st_lock_init (&lock, SPIN_COUNT); } st_lock_enter (&lock); handle = next_handle; if (next_handle == (~0 - 1)) { next_handle = 1; } else { next_handle += 1; } mono_g_hash_table_insert (handles, (gpointer)handle, (gpointer)obj); st_lock_exit (&lock); return (gpointer) handle; }
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; }
MonoDynamicImage* mono_dynamic_image_create (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name) { static const guchar entrycode [16] = {0xff, 0x25, 0}; MonoDynamicImage *image; int i; const char *version; if (!strcmp (mono_get_runtime_info ()->framework_version, "2.1")) version = "v2.0.50727"; /* HACK: SL 2 enforces the .net 2 metadata version */ else version = mono_get_runtime_info ()->runtime_version; image = g_new0 (MonoDynamicImage, 1); MONO_PROFILER_RAISE (image_loading, (&image->image)); /*g_print ("created image %p\n", image);*/ /* keep in sync with image.c */ image->image.name = assembly_name; image->image.assembly_name = image->image.name; /* they may be different */ image->image.module_name = module_name; image->image.version = g_strdup (version); image->image.md_version_major = 1; image->image.md_version_minor = 1; image->image.dynamic = TRUE; image->image.references = g_new0 (MonoAssembly*, 1); image->image.references [0] = NULL; mono_image_init (&image->image); image->token_fixups = mono_g_hash_table_new_type ((GHashFunc)mono_object_hash, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_REFLECTION, NULL, "Reflection Dynamic Image Token Fixup Table"); image->method_to_table_idx = g_hash_table_new (NULL, NULL); image->field_to_table_idx = g_hash_table_new (NULL, NULL); image->method_aux_hash = g_hash_table_new (NULL, NULL); image->vararg_aux_hash = g_hash_table_new (NULL, NULL); image->handleref = g_hash_table_new (NULL, NULL); image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, NULL, "Reflection Dynamic Image Token Table"); image->generic_def_objects = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, NULL, "Reflection Dynamic Image Generic Definition Table"); image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal); image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal); image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal); image->gen_params = g_ptr_array_new (); image->remapped_tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_REFLECTION, NULL, "Reflection Dynamic Image Remapped Token Table"); /*g_print ("string heap create for image %p (%s)\n", image, module_name);*/ string_heap_init (&image->sheap); mono_dynstream_add_data (&image->us, "", 1); mono_dynamic_image_add_to_blob_cached (image, (char*) "", 1, NULL, 0); /* import tables... */ mono_dynstream_add_data (&image->code, (char*)entrycode, sizeof (entrycode)); image->iat_offset = mono_dynstream_add_zero (&image->code, 8); /* two IAT entries */ image->idt_offset = mono_dynstream_add_zero (&image->code, 2 * sizeof (MonoIDT)); /* two IDT entries */ image->imp_names_offset = mono_dynstream_add_zero (&image->code, 2); /* flags for name entry */ mono_dynstream_add_data (&image->code, "_CorExeMain", 12); mono_dynstream_add_data (&image->code, "mscoree.dll", 12); image->ilt_offset = mono_dynstream_add_zero (&image->code, 8); /* two ILT entries */ mono_dynstream_data_align (&image->code); image->cli_header_offset = mono_dynstream_add_zero (&image->code, sizeof (MonoCLIHeader)); for (i=0; i < MONO_TABLE_NUM; ++i) { image->tables [i].next_idx = 1; image->tables [i].columns = table_sizes [i]; } image->image.assembly = (MonoAssembly*)assembly; image->run = assembly->run; image->save = assembly->save; image->pe_kind = 0x1; /* ILOnly */ image->machine = 0x14c; /* I386 */ MONO_PROFILER_RAISE (image_loaded, (&image->image)); dynamic_images_lock (); if (!dynamic_images) dynamic_images = g_ptr_array_new (); g_ptr_array_add (dynamic_images, image); dynamic_images_unlock (); return image; }