Index: vmcore/include/finalize.h =================================================================== --- vmcore/include/finalize.h (revision 527782) +++ vmcore/include/finalize.h (working copy) @@ -54,5 +54,8 @@ void vm_ref_enqueue_func(void); // added for NATIVE REFERENCE ENQUEUE THREAD Boolean get_native_finalizer_thread_flag(); // added for NATIVE FINALIZER THREAD +Boolean get_native_ref_enqueue_thread_flag(); // added for NATIVE REF ENQUEUE THREAD +void wait_native_fin_threads_detached(void); // added for NATIVE FINALIZER THREAD +void wait_native_ref_thread_detached(void); // added for NATIVE REF ENQUEUE THREAD #endif Index: vmcore/include/ref_enqueue_thread.h =================================================================== --- vmcore/include/ref_enqueue_thread.h (revision 527782) +++ vmcore/include/ref_enqueue_thread.h (working copy) @@ -38,7 +38,6 @@ }Ref_Enqueue_Thread_Info; -extern Boolean get_native_ref_enqueue_thread_flag(); extern void ref_enqueue_thread_init(JavaVM *java_vm); extern void ref_enqueue_shutdown(void); extern void activate_ref_enqueue_thread(void); Index: vmcore/src/init/finalizer_thread.cpp =================================================================== --- vmcore/src/init/finalizer_thread.cpp (revision 527782) +++ vmcore/src/init/finalizer_thread.cpp (working copy) @@ -61,6 +61,7 @@ } static IDATA finalizer_thread_func(void **args); +static void wait_fin_threads_attached(void); void finalizer_threads_init(JavaVM *java_vm) { @@ -100,7 +101,7 @@ assert(status == TM_ERROR_NONE); } - while(fin_thread_info->thread_attached_num < fin_thread_info->thread_num); + wait_fin_threads_attached(); } void finalizer_shutdown(Boolean start_finalization_on_exit) @@ -121,6 +122,27 @@ activate_finalizer_threads(TRUE); } +static void inc_fin_thread_num(void) +{ atomic_inc32(&fin_thread_info->thread_attached_num); } + +static void dec_fin_thread_num(void) +{ atomic_dec32(&fin_thread_info->thread_attached_num); } + +static void wait_fin_threads_attached(void) +{ while(fin_thread_info->thread_attached_num < fin_thread_info->thread_num); } + +void wait_native_fin_threads_detached(void) +{ + hymutex_lock(&fin_thread_info->end_mutex); + while(fin_thread_info->thread_attached_num){ + atomic_inc32(&fin_thread_info->end_waiting_num); + IDATA status = hycond_wait_timed(&fin_thread_info->end_cond, &fin_thread_info->end_mutex, (I_64)1000, 0); + atomic_dec32(&fin_thread_info->end_waiting_num); + if(status != TM_ERROR_NONE) break; + } + hymutex_unlock(&fin_thread_info->end_mutex); +} + /* Restrict waiting time; Unit: msec */ static unsigned int restrict_wait_time(unsigned int wait_time, unsigned int max_time) { @@ -186,7 +208,8 @@ jni_args->group = NULL; IDATA status = AttachCurrentThreadAsDaemon(java_vm, (void**)&jni_env, jni_args); assert(status == JNI_OK); - atomic_inc32(&fin_thread_info->thread_attached_num); + inc_fin_thread_num(); + /* Choice: use VM_thread or hythread to indicate the finalizer thread ? * Now we use hythread * p_TLS_vmthread->finalize_thread_flags = thread_id; @@ -212,6 +235,7 @@ vm_heavy_finalizer_resume_mutator(); status = DetachCurrentThread(java_vm); + dec_fin_thread_num(); //status = jthread_detach(java_thread); return status; } @@ -256,3 +280,4 @@ } + Index: vmcore/src/init/ref_enqueue_thread.cpp =================================================================== --- vmcore/src/init/ref_enqueue_thread.cpp (revision 527782) +++ vmcore/src/init/ref_enqueue_thread.cpp (working copy) @@ -18,6 +18,7 @@ * @author Li-Gang Wang, 2006/11/15 */ +#include #include "ref_enqueue_thread.h" #include "finalize.h" #include "vm_threads.h" @@ -37,6 +38,7 @@ static IDATA ref_enqueue_thread_func(void **args); +static void wait_ref_thread_attached(void); void ref_enqueue_thread_init(JavaVM *java_vm) { @@ -55,7 +57,7 @@ status = hythread_create(NULL, 0, REF_ENQUEUE_THREAD_PRIORITY, 0, (hythread_entrypoint_t)ref_enqueue_thread_func, args); assert(status == TM_ERROR_NONE); - while(ref_thread_info->thread_attached == 0); + wait_ref_thread_attached(); } void ref_enqueue_shutdown(void) @@ -64,6 +66,24 @@ activate_ref_enqueue_thread(); } +static uint32 atomic_inc32(volatile apr_uint32_t *mem) +{ return (uint32)apr_atomic_inc32(mem); } + +static uint32 atomic_dec32(volatile apr_uint32_t *mem) +{ return (uint32)apr_atomic_dec32(mem); } + +static void inc_ref_thread_num(void) +{ atomic_inc32(&ref_thread_info->thread_attached); } + +static void dec_ref_thread_num(void) +{ atomic_dec32(&ref_thread_info->thread_attached); } + +static void wait_ref_thread_attached(void) +{ while(ref_thread_info->thread_attached == 0); } + +void wait_native_ref_thread_detached(void) +{ while(ref_thread_info->thread_attached); } + void activate_ref_enqueue_thread(void) { IDATA stat = hysem_set(ref_thread_info->pending_sem, REF_ENQUEUE_THREAD_NUM); @@ -94,7 +114,7 @@ jni_args->group = NULL; IDATA status = AttachCurrentThreadAsDaemon(java_vm, (void**)&jni_env, jni_args); assert(status == JNI_OK); - ref_thread_info->thread_attached = 1; + inc_ref_thread_num(); while(true){ /* Waiting for pending weak references */ @@ -108,6 +128,7 @@ } status = DetachCurrentThread(java_vm); + dec_ref_thread_num(); //status = jthread_detach(java_thread); return status; } Index: vmcore/src/init/vm_shutdown.cpp =================================================================== --- vmcore/src/init/vm_shutdown.cpp (revision 527782) +++ vmcore/src/init/vm_shutdown.cpp (working copy) @@ -36,6 +36,7 @@ #include "vm_stats.h" #include "thread_dump.h" #include "interpreter.h" +#include "finalize.h" #define LOG_DOMAIN "vm.core.shutdown" #include "cxxlog.h" @@ -182,6 +183,11 @@ // Execute pending shutdown hooks & finalizers status = exec_shutdown_sequence(jni_env); if (status != JNI_OK) return (jint)status; + + if(get_native_finalizer_thread_flag()) + wait_native_fin_threads_detached(); + if(get_native_ref_enqueue_thread_flag()) + wait_native_ref_thread_detached(); // Raise uncaught exception to current thread. // It will be properly processed in jthread_detach().