Index: working_vm/vm/include/open/hythread.h =================================================================== --- working_vm/vm/include/open/hythread.h (revision 524976) +++ working_vm/vm/include/open/hythread.h (working copy) @@ -124,6 +124,8 @@ extern HY_CFUNC void VMCALL hythread_detach PROTOTYPE((hythread_t thread)); +extern HY_CFUNC void VMCALL +hythread_detach_shutdownthread PROTOTYPE((hythread_t thread)); extern HY_CFUNC UDATA VMCALL hythread_lib_set_flags PROTOTYPE((UDATA flags)); extern HY_CFUNC IDATA VMCALL Index: working_vm/vm/include/open/jthread.h =================================================================== --- working_vm/vm/include/open/jthread.h (revision 524976) +++ working_vm/vm/include/open/jthread.h (working copy) @@ -84,7 +84,8 @@ IDATA jthread_create(JNIEnv * jni_env, jthread thread, jthread_threadattr_t *attrs); IDATA jthread_create_with_function(JNIEnv * jni_env, jthread thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg); IDATA jthread_attach(JNIEnv * jni_env, jthread thread, jboolean daemon); - IDATA jthread_detach(jthread thread); +IDATA jthread_detach_shutdownthread ( jthread thread ); + IDATA jthread_detach(jthread thread ); IDATA jthread_join(jthread thread); IDATA jthread_timed_join(jthread thread, jlong millis, jint nanos); IDATA jthread_yield(); Index: working_vm/vm/vmcore/src/init/vm_shutdown.cpp =================================================================== --- working_vm/vm/vmcore/src/init/vm_shutdown.cpp (revision 524976) +++ working_vm/vm/vmcore/src/init/vm_shutdown.cpp (working copy) @@ -202,8 +202,9 @@ // TODO: ups we don't stop native threads as well :-(( // We are lucky! Currently, there are no such threads. - // Detach current thread. - status = jthread_detach(java_thread); + // Detach current shutdowning thread. + + status = jthread_detach_shutdownthread(java_thread); if (status != TM_ERROR_NONE) return JNI_ERR; // Call Agent_OnUnload() for agents and unload agents. Index: working_vm/vm/thread/src/hythr.exp =================================================================== --- working_vm/vm/thread/src/hythr.exp (revision 524976) +++ working_vm/vm/thread/src/hythr.exp (working copy) @@ -1,170 +1,172 @@ -HYTHR_0.1 { - global : -get_tls_helper; -hythread_detach; -hythread_tls_alloc; -hythread_sleep_interruptable; -hythread_cancel; -hythread_monitor_enter; -hythread_monitor_notify_all; -hythread_attach; -hythread_attach_ex; -hythread_monitor_destroy; -hythread_monitor_num_waiting; -hythread_interrupted; -hythread_park; -hythread_monitor_init_with_name; -hythread_monitor_try_enter; -hythread_self; -tm_self_tls; -hythread_tls_free; -hythread_yield; -hythread_suspend; -hythread_interrupt; -hythread_tls_set; -hythread_create; -hythread_monitor_wait; -hythread_monitor_wait_interruptable; -hythread_monitor_exit; -hythread_set_priority; -hythread_unpark; -hythread_sleep; -hythread_global; -hythread_tls_alloc_with_finalizer; -hythread_monitor_wait_timed; -hythread_resume; -hythread_monitor_notify; -hythread_get_priority; -hythread_tls_get; -hythread_tls_get_request_offset; -hythread_tls_get_offset; -hythread_global_lock; -hythread_global_unlock; -hythread_attach_to_group; -hythread_create_with_group; -hythread_clear_interrupted_other; -hythread_join; -hythread_join_timed; -hythread_join_interruptable; -hythread_get_self_id; -hythread_get_id; -hythread_get_thread; -hythread_get_thread_times; -hythread_struct_init; -hythread_cancel_all; -hythread_group_create; -hythread_group_release; -hythread_group_get_list; -hythread_get_private_data; -hythread_set_private_data; -hythread_is_suspend_enabled; -hythread_suspend_enable; -hythread_suspend_disable; -hythread_exception_safe_point; -hythread_safe_point; -hythread_safe_point_other; -hythread_suspend_other; -hythread_set_safepoint_callback; -hythread_suspend_all; -hythread_resume_all; -hythread_iterator_create; -hythread_iterator_release; -hythread_iterator_reset; -hythread_iterator_reset; -hythread_iterator_next; -hythread_iterator_has_next; -hythread_iterator_size; -hythread_thin_monitor_create; -hythread_thin_monitor_enter; -hythread_thin_monitor_try_enter; -hythread_thin_monitor_exit; -hythread_thin_monitor_wait; -hythread_thin_monitor_wait_timed; -hythread_thin_monitor_wait_interruptable; -hythread_thin_monitor_notify; -hythread_thin_monitor_notify_all; -hythread_thin_monitor_destroy; -hythread_thin_monitor_get_owner; -hythread_add_task; -hythread_get_function_pointer; -hythread_get_data_pointer; -hythread_get_next_task; -hythread_destroy_task_iterator; -hythread_create_task_iterator; -hythread_init_task_manager; -hythread_destroy_task_manager; -hythread_join_all_task; -hythread_shutdown_after_execute_all_task; -hythread_get_thread_count; -hythread_get_task_count; -hysem_post; -hysem_wait; -hysem_destroy; -hycond_create; -hycond_wait; -hycond_wait_timed; -hycond_wait_timed_raw; -hycond_wait_interruptable; -hycond_notify; -hycond_notify_all; -hycond_destroy; -hylatch_create; -hylatch_wait; -hylatch_wait_timed; -hylatch_wait_interruptable; -hylatch_set; -hylatch_count_down; -hylatch_get_count; -hylatch_destroy; -hysem_create; -hysem_wait_timed; -hysem_wait_interruptable; -hysem_getvalue; -hysem_set; -hymutex_create; -hymutex_lock; -hymutex_trylock; -hymutex_unlock; -hymutex_destroy; -hythread_exit; - -hythread_is_alive; -hythread_init; -hythread_shutdown; -hythread_lib_create; -hythread_lib_destroy; -hythread_lib_lock; -hythread_lib_unlock; -set_safepoint_callback; - -release_start_lock; -acquire_start_lock; -inflate_lock; -is_fat_lock; -owns_thin_lock; -unreserve_lock; -set_suspend_disable; -reset_suspend_disable; -hythread_is_blocked_on_monitor_enter; -hythread_is_waiting; -hythread_is_in_native; -hythread_is_suspended; -hythread_is_parked; -hythread_is_in_monitor_wait; -hythread_is_sleeping; -hythread_is_waiting_with_timeout; -hythread_is_waiting_indefinitely; -hythread_is_runnable; -hythread_is_terminated; -hythread_thin_monitor_get_recursion; -array_add; -array_create; -array_delete; -array_get; -get_java_thread_group; - -Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset; - - -local: *; -}; +HYTHR_0.1 { + global : +get_tls_helper; +hythread_detach; +hythread_detach_shutdownthread; +hythread_tls_alloc; +hythread_sleep_interruptable; +hythread_cancel; +hythread_monitor_enter; +hythread_monitor_notify_all; +hythread_attach; +hythread_attach_ex; +hythread_monitor_destroy; +hythread_monitor_num_waiting; +hythread_interrupted; +hythread_park; +hythread_monitor_init_with_name; +hythread_monitor_try_enter; +hythread_self; +tm_self_tls; +hythread_tls_free; +hythread_yield; +hythread_suspend; +hythread_interrupt; +hythread_tls_set; +hythread_create; +hythread_monitor_wait; +hythread_monitor_wait_interruptable; +hythread_monitor_exit; +hythread_set_priority; +hythread_unpark; +hythread_sleep; +hythread_global; +hythread_tls_alloc_with_finalizer; +hythread_monitor_wait_timed; +hythread_resume; +hythread_monitor_notify; +hythread_get_priority; +hythread_tls_get; +hythread_tls_get_request_offset; +hythread_tls_get_offset; +hythread_global_lock; +hythread_global_unlock; +hythread_attach_to_group; +hythread_create_with_group; +hythread_clear_interrupted_other; +hythread_join; +hythread_join_timed; +hythread_join_interruptable; +hythread_get_self_id; +hythread_get_id; +hythread_get_thread; +hythread_get_thread_times; +hythread_struct_init; +hythread_cancel_all; +hythread_group_create; +hythread_group_release; +hythread_group_get_list; +hythread_get_private_data; +hythread_set_private_data; +hythread_is_suspend_enabled; +hythread_suspend_enable; +hythread_suspend_disable; +hythread_exception_safe_point; +hythread_safe_point; +hythread_safe_point_other; +hythread_suspend_other; +hythread_set_safepoint_callback; +hythread_suspend_all; +hythread_resume_all; +hythread_iterator_create; +hythread_iterator_release; +hythread_iterator_reset; +hythread_iterator_reset; +hythread_iterator_next; +hythread_iterator_has_next; +hythread_iterator_size; +hythread_thin_monitor_create; +hythread_thin_monitor_enter; +hythread_thin_monitor_try_enter; +hythread_thin_monitor_exit; +hythread_thin_monitor_wait; +hythread_thin_monitor_wait_timed; +hythread_thin_monitor_wait_interruptable; +hythread_thin_monitor_notify; +hythread_thin_monitor_notify_all; +hythread_thin_monitor_destroy; +hythread_thin_monitor_get_owner; +hythread_add_task; +hythread_get_function_pointer; +hythread_get_data_pointer; +hythread_get_next_task; +hythread_destroy_task_iterator; +hythread_create_task_iterator; +hythread_init_task_manager; +hythread_destroy_task_manager; +hythread_join_all_task; +hythread_shutdown_after_execute_all_task; +hythread_get_thread_count; +hythread_get_task_count; +hysem_post; +hysem_wait; +hysem_destroy; +hycond_create; +hycond_wait; +hycond_wait_timed; +hycond_wait_timed_raw; +hycond_wait_interruptable; +hycond_notify; +hycond_notify_all; +hycond_destroy; +hylatch_create; +hylatch_wait; +hylatch_wait_timed; +hylatch_wait_interruptable; +hylatch_set; +hylatch_count_down; +hylatch_get_count; +hylatch_destroy; +hysem_create; +hysem_wait_timed; +hysem_wait_interruptable; +hysem_getvalue; +hysem_set; +hymutex_create; +hymutex_lock; +hymutex_trylock; +hymutex_unlock; +hymutex_destroy; +hythread_exit; + +hythread_is_alive; +hythread_init; +hythread_shutdown; +hythread_lib_create; +hythread_lib_destroy; +hythread_lib_lock; +hythread_lib_unlock; +set_safepoint_callback; + +release_start_lock; +acquire_start_lock; +inflate_lock; +is_fat_lock; +owns_thin_lock; +unreserve_lock; +set_suspend_disable; +reset_suspend_disable; +hythread_is_blocked_on_monitor_enter; +hythread_is_waiting; +hythread_is_in_native; +hythread_is_suspended; +hythread_is_parked; +hythread_is_in_monitor_wait; +hythread_is_sleeping; +hythread_is_waiting_with_timeout; +hythread_is_waiting_indefinitely; +hythread_is_runnable; +hythread_is_terminated; +hythread_thin_monitor_get_recursion; +array_add; +array_create; +array_delete; +array_get; +get_java_thread_group; + +Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset; + + +local: *; +}; + Index: working_vm/vm/thread/src/hythr.def =================================================================== --- working_vm/vm/thread/src/hythr.def (revision 524976) +++ working_vm/vm/thread/src/hythr.def (working copy) @@ -1,156 +1,157 @@ -LIBRARY HYTHR - -EXPORTS - -hythread_detach -hythread_tls_alloc -hythread_sleep_interruptable -hythread_cancel -hythread_monitor_enter -hythread_monitor_notify_all -hythread_attach -hythread_attach_ex -hythread_monitor_destroy -hythread_monitor_num_waiting -hythread_interrupted -hythread_park -hythread_monitor_init_with_name -hythread_monitor_try_enter -hythread_self -hythread_self_slow -hythread_tls_free -hythread_yield -hythread_suspend -hythread_interrupt -hythread_tls_set -hythread_create -hythread_monitor_wait -hythread_monitor_wait_interruptable -hythread_monitor_exit -hythread_set_priority -hythread_unpark -hythread_sleep -hythread_global -hythread_tls_alloc_with_finalizer -hythread_monitor_wait_timed -hythread_resume -hythread_monitor_notify -hythread_get_priority -hythread_tls_get -hythread_tls_get_request_offset -hythread_tls_get_offset -hythread_global_lock -hythread_global_unlock -hythread_attach_to_group -hythread_create_with_group -hythread_clear_interrupted_other -hythread_join -hythread_join_timed -hythread_join_interruptable -hythread_get_self_id -hythread_get_id -hythread_get_thread -hythread_get_thread_times -hythread_struct_init -hythread_cancel_all -hythread_group_create -hythread_group_release -hythread_group_get_list -hythread_get_private_data -hythread_set_private_data -hythread_is_suspend_enabled -hythread_suspend_enable -hythread_suspend_disable -hythread_exception_safe_point -hythread_safe_point -hythread_safe_point_other -hythread_suspend_other -hythread_set_safepoint_callback -hythread_suspend_all -hythread_resume_all -hythread_iterator_create -hythread_iterator_release -hythread_iterator_reset -hythread_iterator_next -hythread_iterator_has_next -hythread_iterator_size -hythread_thin_monitor_create -hythread_thin_monitor_enter -hythread_thin_monitor_try_enter -hythread_thin_monitor_exit -hythread_thin_monitor_wait -hythread_thin_monitor_wait_timed -hythread_thin_monitor_wait_interruptable -hythread_thin_monitor_notify -hythread_thin_monitor_notify_all -hythread_thin_monitor_destroy -hythread_thin_monitor_get_owner - -hysem_post -hysem_wait -hysem_destroy -hycond_create -hycond_wait -hycond_wait_timed -hycond_wait_timed_raw -hycond_wait_interruptable -hycond_notify -hycond_notify_all -hycond_destroy -hylatch_create -hylatch_wait -hylatch_wait_timed -hylatch_wait_interruptable -hylatch_set -hylatch_count_down -hylatch_get_count -hylatch_destroy -hysem_create -hysem_wait_timed -hysem_wait_interruptable -hysem_getvalue -hysem_set -hymutex_create -hymutex_lock -hymutex_trylock -hymutex_unlock -hymutex_destroy - - -hythread_is_alive -hythread_is_terminated -hythread_init -hythread_shutdown -hythread_lib_create -hythread_lib_destroy -hythread_lib_lock -hythread_lib_unlock - -release_start_lock -acquire_start_lock -inflate_lock -is_fat_lock -owns_thin_lock -unreserve_lock -set_suspend_disable -reset_suspend_disable -hythread_is_blocked_on_monitor_enter -hythread_is_waiting -hythread_is_in_native -hythread_is_suspended -hythread_is_parked -hythread_is_in_monitor_wait -hythread_is_sleeping -hythread_is_waiting_with_timeout -hythread_is_waiting_indefinitely -hythread_is_runnable -hythread_thin_monitor_get_recursion -hythread_exit -array_add -array_create -array_delete -array_get -get_java_thread_group - - -Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset +LIBRARY HYTHR + +EXPORTS + +hythread_detach +hythread_detach_shutdownthread +hythread_tls_alloc +hythread_sleep_interruptable +hythread_cancel +hythread_monitor_enter +hythread_monitor_notify_all +hythread_attach +hythread_attach_ex +hythread_monitor_destroy +hythread_monitor_num_waiting +hythread_interrupted +hythread_park +hythread_monitor_init_with_name +hythread_monitor_try_enter +hythread_self +hythread_self_slow +hythread_tls_free +hythread_yield +hythread_suspend +hythread_interrupt +hythread_tls_set +hythread_create +hythread_monitor_wait +hythread_monitor_wait_interruptable +hythread_monitor_exit +hythread_set_priority +hythread_unpark +hythread_sleep +hythread_global +hythread_tls_alloc_with_finalizer +hythread_monitor_wait_timed +hythread_resume +hythread_monitor_notify +hythread_get_priority +hythread_tls_get +hythread_tls_get_request_offset +hythread_tls_get_offset +hythread_global_lock +hythread_global_unlock +hythread_attach_to_group +hythread_create_with_group +hythread_clear_interrupted_other +hythread_join +hythread_join_timed +hythread_join_interruptable +hythread_get_self_id +hythread_get_id +hythread_get_thread +hythread_get_thread_times +hythread_struct_init +hythread_cancel_all +hythread_group_create +hythread_group_release +hythread_group_get_list +hythread_get_private_data +hythread_set_private_data +hythread_is_suspend_enabled +hythread_suspend_enable +hythread_suspend_disable +hythread_exception_safe_point +hythread_safe_point +hythread_safe_point_other +hythread_suspend_other +hythread_set_safepoint_callback +hythread_suspend_all +hythread_resume_all +hythread_iterator_create +hythread_iterator_release +hythread_iterator_reset +hythread_iterator_next +hythread_iterator_has_next +hythread_iterator_size +hythread_thin_monitor_create +hythread_thin_monitor_enter +hythread_thin_monitor_try_enter +hythread_thin_monitor_exit +hythread_thin_monitor_wait +hythread_thin_monitor_wait_timed +hythread_thin_monitor_wait_interruptable +hythread_thin_monitor_notify +hythread_thin_monitor_notify_all +hythread_thin_monitor_destroy +hythread_thin_monitor_get_owner + +hysem_post +hysem_wait +hysem_destroy +hycond_create +hycond_wait +hycond_wait_timed +hycond_wait_timed_raw +hycond_wait_interruptable +hycond_notify +hycond_notify_all +hycond_destroy +hylatch_create +hylatch_wait +hylatch_wait_timed +hylatch_wait_interruptable +hylatch_set +hylatch_count_down +hylatch_get_count +hylatch_destroy +hysem_create +hysem_wait_timed +hysem_wait_interruptable +hysem_getvalue +hysem_set +hymutex_create +hymutex_lock +hymutex_trylock +hymutex_unlock +hymutex_destroy + + +hythread_is_alive +hythread_is_terminated +hythread_init +hythread_shutdown +hythread_lib_create +hythread_lib_destroy +hythread_lib_lock +hythread_lib_unlock + +release_start_lock +acquire_start_lock +inflate_lock +is_fat_lock +owns_thin_lock +unreserve_lock +set_suspend_disable +reset_suspend_disable +hythread_is_blocked_on_monitor_enter +hythread_is_waiting +hythread_is_in_native +hythread_is_suspended +hythread_is_parked +hythread_is_in_monitor_wait +hythread_is_sleeping +hythread_is_waiting_with_timeout +hythread_is_waiting_indefinitely +hythread_is_runnable +hythread_thin_monitor_get_recursion +hythread_exit +array_add +array_create +array_delete +array_get +get_java_thread_group + + +Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset Index: working_vm/vm/thread/src/thread_native_basic.c =================================================================== --- working_vm/vm/thread/src/thread_native_basic.c (revision 524976) +++ working_vm/vm/thread/src/thread_native_basic.c (working copy) @@ -287,6 +287,44 @@ } /** + * Detaches a thread from the threading library when in shutdown. + * + * @note Assumes that the thread being detached is already attached.
+ * + * If the thread is an attached thread, then detach should only be called by the thread + * itself. Internal resources associated with the thread are freed. + * + * If the thread is already dead, this call will destroy it. + * + * @param[in] thread a hythread_t representing the thread to be detached. + * If this is NULL, the current thread is detached. + * @return none + * + * @see hythread_attach + */ +void VMCALL hythread_detach_shutdownthread(hythread_t thread) { + + if (thread == NULL) { + thread = hythread_self(); + } + + + + // No actions required in case the specified thread is detached already. + if (thread->group != NULL) { + assert(thread == tm_self_tls); + + thread_set_self(NULL); + fast_thread_array[thread->thread_id] = NULL; + + thread->prev->next = thread->next; + thread->next->prev = thread->prev; + thread->group->threads_count--; + thread->group = NULL; + } + +} +/** * Waits until the selected thread finishes execution. * * @param[in] t thread to join Index: working_vm/vm/thread/src/thread_java_basic.c =================================================================== --- working_vm/vm/thread/src/thread_java_basic.c (revision 524976) +++ working_vm/vm/thread/src/thread_java_basic.c (working copy) @@ -269,7 +269,7 @@ * * @param[in] java_thread Java thread to be detached */ -IDATA jthread_detach(jthread java_thread) { +IDATA jthread_detach(jthread java_thread ) { IDATA status; hythread_t tm_native_thread; jvmti_thread_t tm_jvmti_thread; @@ -284,8 +284,7 @@ tm_native_thread = jthread_get_native_thread(java_thread); tm_jvmti_thread = hythread_get_private_data(tm_native_thread); jni_env = tm_jvmti_thread->jenv; - - if (!tm_jvmti_thread->daemon) { + if (!tm_jvmti_thread->daemon ) { countdown_nondaemon_threads(tm_native_thread); } @@ -308,6 +307,51 @@ return TM_ERROR_NONE; } +/** + * Detaches the shutdown thread from java VM. + * + * This function will release any resources associated with the given thread. + * + * @param[in] java_thread Java thread to be detached + */ +IDATA jthread_detach_shutdownthread(jthread java_thread ) { + IDATA status; + hythread_t tm_native_thread; + jvmti_thread_t tm_jvmti_thread; + JNIEnv * jni_env; + + assert(hythread_is_suspend_enabled()); + + // Check input arg + assert(java_thread); + TRACE(("TM: jthread_detach %x", hythread_self())); + + tm_native_thread = jthread_get_native_thread(java_thread); + tm_jvmti_thread = hythread_get_private_data(tm_native_thread); + jni_env = tm_jvmti_thread->jenv; + // at this stage we don't careabout the countdown + // if (!tm_jvmti_thread->daemon ) { + // countdown_nondaemon_threads(tm_native_thread); + // } + + // Detach from VM. + status = vm_detach(java_thread); + if (status != JNI_OK) return TM_ERROR_INTERNAL; + + // Delete global reference to current thread object. + (*jni_env)->DeleteGlobalRef(jni_env, tm_jvmti_thread->thread_object); + // jthread_self() will return NULL now. + tm_jvmti_thread->thread_object = NULL; + + // Decrease alive thread counter + thread_end_count(); + + // Deallocate tm_jvmti_thread + //apr_pool_destroy(tm_jvmti_thread->pool); + + assert(hythread_is_suspend_enabled()); + return TM_ERROR_NONE; +} IDATA associate_native_and_java_thread(JNIEnv * jni_env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref) { IDATA status; Index: working_classlib/modules/portlib/src/main/native/include/shared/hythread.h =================================================================== --- working_classlib/modules/portlib/src/main/native/include/shared/hythread.h (revision 524970) +++ working_classlib/modules/portlib/src/main/native/include/shared/hythread.h (working copy) @@ -99,6 +99,7 @@ } HyThreadMonitorTracing; extern HY_CFUNC void VMCALL hythread_detach PROTOTYPE ((hythread_t thread)); + extern HY_CFUNC void VMCALL hythread_detach_shutdownthread PROTOTYPE ((hythread_t thread)); extern HY_CFUNC UDATA VMCALL hythread_lib_set_flags PROTOTYPE ((UDATA flags)); extern HY_CFUNC IDATA VMCALL Index: working_classlib/modules/portlib/src/main/native/port/shared/hyport.c =================================================================== --- working_classlib/modules/portlib/src/main/native/port/shared/hyport.c (revision 524970) +++ working_classlib/modules/portlib/src/main/native/port/shared/hyport.c (working copy) @@ -106,8 +106,11 @@ hyport_tls_shutdown (portLibrary); portLibrary->mem_shutdown (portLibrary); - hythread_detach (portLibrary->attached_thread); + //hythread_detach (portLibrary->attached_thread); + // call the shutdown version of detach + hythread_detach_shutdownthread (portLibrary->attached_thread); + /* Last thing to do. If this port library was self allocated free this memory */ if (NULL != portLibrary->self_handle) { Index: working_classlib/modules/portlib/src/main/native/thread/unix/exports.txt =================================================================== --- working_classlib/modules/portlib/src/main/native/thread/unix/exports.txt (revision 524970) +++ working_classlib/modules/portlib/src/main/native/thread/unix/exports.txt (working copy) @@ -39,6 +39,7 @@ hythread_yield hythread_exit hythread_detach +hythread_detach_shutdownthread hythread_global hythread_get_flags hythread_monitor_walk Index: working_classlib/modules/portlib/src/main/native/thread/shared/hythread.c =================================================================== --- working_classlib/modules/portlib/src/main/native/thread/shared/hythread.c (revision 524970) +++ working_classlib/modules/portlib/src/main/native/thread/shared/hythread.c (working copy) @@ -1512,6 +1512,76 @@ #undef CDEV_CURRENT_FUNCTION +#define CDEV_CURRENT_FUNCTION hythread_detach_shutdownthread +/** + * Detach a thread from the threading library, shutdown version. + * + * @note Assumes that the thread being detached is already attached.
+ * + * If the thread is an attached thread, then detach should only be called by the thread + * itself. Internal resources associated with the thread are freed. + * + * If the thread is already dead, this call will destroy it. + * + * @param[in] thread a hythread_t representing the thread to be detached. + * If this is NULL, the current thread is detached. + * @return none + * + * @see hythread_attach + */ +void VMCALL +hythread_detach_shutdownthread (hythread_t thread) +{ + UDATA destroy = 0; + UDATA attached = 0; + hythread_t self = MACRO_SELF (); + + if (thread == NULL) + { + thread = self; + } + ASSERT (thread); + + THREAD_LOCK (self, thread, CALLER_DETACH); + if (thread->attachcount < 1) + { + /* error! */ + } + else + { + if (--thread->attachcount == 0) + { + if (thread->flags & HYTHREAD_FLAG_ATTACHED) + { + /* this is an attached thread, and it is now fully + detached. Mark it dead so that it can be destroyed */ + thread->flags |= HYTHREAD_FLAG_DEAD; + attached = destroy = 1; + } + else + { + destroy = thread->flags & HYTHREAD_FLAG_DEAD; + } + } + } + THREAD_UNLOCK (self, thread); + + if (destroy) + { + hythread_library_t library = thread->library; + + tls_finalize (thread); + + destroy_thread (thread, GLOBAL_NOT_LOCKED); + if (attached) + { + TLS_SET (library->self_ptr, NULL); + } + } +} + +#undef CDEV_CURRENT_FUNCTION + #define CDEV_CURRENT_FUNCTION hythread_exit /** * Exit the current thread. Index: working_classlib/modules/portlib/src/main/native/thread/windows/hythr.def =================================================================== --- working_classlib/modules/portlib/src/main/native/thread/windows/hythr.def (revision 524970) +++ working_classlib/modules/portlib/src/main/native/thread/windows/hythr.def (working copy) @@ -45,6 +45,7 @@ hythread_yield hythread_exit hythread_detach + hythread_detach_shutdownthread hythread_global hythread_get_flags hythread_monitor_walk Index: working_classlib/modules/portlib/src/main/native/thrstub/shared/hythread.h =================================================================== --- working_classlib/modules/portlib/src/main/native/thrstub/shared/hythread.h (revision 524970) +++ working_classlib/modules/portlib/src/main/native/thrstub/shared/hythread.h (working copy) @@ -201,6 +201,7 @@ #define hythread_attach(param1) privateThreadLibrary->thread_attach(privateThreadLibrary,param1) #define hythread_create(param1,param2,param3,param4,param5,param6) privateThreadLibrary->thread_create(privateThreadLibrary,param1,param2,param3,param4,param5,param6) #define hythread_detach(param1) privateThreadLibrary->thread_detach(privateThreadLibrary,param1) +#define hythread_detach_shutdownthread(param1) privateThreadLibrary->thread_detach(privateThreadLibrary,param1) #define hythread_exit(param1) privateThreadLibrary->thread_exit(privateThreadLibrary,param1) #define hythread_global(param1) privateThreadLibrary->thread_global(privateThreadLibrary,param1)