Index: trunk/vm/interpreter/src/interpreter.cpp =================================================================== --- trunk/vm/interpreter/src/interpreter.cpp (revision 489059) +++ trunk/vm/interpreter/src/interpreter.cpp (working copy) @@ -2322,6 +2322,12 @@ uint32 ip = frame.ip - (uint8*)m->get_byte_code_addr(); DEBUG_BYTECODE("ip = " << dec << (int)ip << endl); + // When VM is in shutdown stage we need to execute final block to + // release monitors and propogate an exception to the upper frames. + if (VM_Global_State::loader_env->IsVmShutdowning()) { + *exception = VM_Global_State::loader_env->java_lang_Object->object; + } + Class *clazz = m->get_class(); for(uint32 i = 0; i < m->num_bc_exception_handlers(); i++) { @@ -2976,19 +2982,6 @@ got_exception: assert(&frame == getLastStackFrame()); - if (VM_Global_State::loader_env->IsVmShutdowning()) { - assert(!hythread_is_suspend_enabled()); - assert(exn_raised()); - if (frame.locked_monitors) { - M2N_ALLOC_MACRO; - vm_monitor_exit_wrapper(frame.locked_monitors->monitor); - M2N_FREE_MACRO; - assert(!frame.locked_monitors->next); - } - M2N_FREE_MACRO; - return; - } - clear_current_thread_exception(); if (interpreter_ti_notification_mode) { Index: trunk/vm/vmcore/src/init/vm_shutdown.cpp =================================================================== --- trunk/vm/vmcore/src/init/vm_shutdown.cpp (revision 489059) +++ trunk/vm/vmcore/src/init/vm_shutdown.cpp (working copy) @@ -254,7 +254,13 @@ // Wait for threads completion. for (int i = 0; i < size; i++) { - hythread_join(running_threads[i]); + // It should be enough to interrupt the thread only once + // but sometimes the thread just ignores our interruption. + // TODO: need to investigate why it is necessary to send several interruptions. + if (hythread_join_timed(running_threads[i], 100, 0) == TM_ERROR_TIMEOUT) { + hythread_interrupt(running_threads[i]); + --i; + } } // TODO: ups we don't stop native threads as well :-((