27 #include "outStream.h" |
27 #include "outStream.h" |
28 #include "eventHandler.h" |
28 #include "eventHandler.h" |
29 #include "threadControl.h" |
29 #include "threadControl.h" |
30 #include "invoker.h" |
30 #include "invoker.h" |
31 |
31 |
|
32 |
|
33 #define COMMAND_LOOP_THREAD_NAME "JDWP Event Helper Thread" |
|
34 |
32 /* |
35 /* |
33 * Event helper thread command commandKinds |
36 * Event helper thread command commandKinds |
34 */ |
37 */ |
35 #define COMMAND_REPORT_EVENT_COMPOSITE 1 |
38 #define COMMAND_REPORT_EVENT_COMPOSITE 1 |
36 #define COMMAND_REPORT_INVOKE_DONE 2 |
39 #define COMMAND_REPORT_INVOKE_DONE 2 |
119 |
122 |
120 static CommandQueue commandQueue; |
123 static CommandQueue commandQueue; |
121 static jrawMonitorID commandQueueLock; |
124 static jrawMonitorID commandQueueLock; |
122 static jrawMonitorID commandCompleteLock; |
125 static jrawMonitorID commandCompleteLock; |
123 static jrawMonitorID blockCommandLoopLock; |
126 static jrawMonitorID blockCommandLoopLock; |
|
127 static jrawMonitorID vmDeathLock; |
|
128 static volatile jboolean commandLoopEnteredVmDeathLock = JNI_FALSE; |
|
129 |
124 static jint maxQueueSize = 50 * 1024; /* TO DO: Make this configurable */ |
130 static jint maxQueueSize = 50 * 1024; /* TO DO: Make this configurable */ |
125 static jboolean holdEvents; |
131 static jboolean holdEvents; |
126 static jint currentQueueSize = 0; |
132 static jint currentQueueSize = 0; |
127 static jint currentSessionID; |
133 static jint currentSessionID; |
128 |
134 |
698 /* |
704 /* |
699 * Setup for a potential doBlockCommand() call before calling |
705 * Setup for a potential doBlockCommand() call before calling |
700 * handleCommand() to prevent any races. |
706 * handleCommand() to prevent any races. |
701 */ |
707 */ |
702 jboolean doBlock = needBlockCommandLoop(command); |
708 jboolean doBlock = needBlockCommandLoop(command); |
703 log_debugee_location("commandLoop(): command being handled", NULL, NULL, 0); |
709 debugMonitorEnter(vmDeathLock); |
704 handleCommand(jni_env, command); |
710 commandLoopEnteredVmDeathLock = JNI_TRUE; |
|
711 if (!gdata->vmDead) { |
|
712 log_debugee_location("commandLoop(): command being handled", NULL, NULL, 0); |
|
713 handleCommand(jni_env, command); |
|
714 } |
705 completeCommand(command); |
715 completeCommand(command); |
|
716 debugMonitorExit(vmDeathLock); |
|
717 commandLoopEnteredVmDeathLock = JNI_FALSE; |
706 /* if we just finished a suspend-all cmd, then we block here */ |
718 /* if we just finished a suspend-all cmd, then we block here */ |
707 if (doBlock) { |
719 if (doBlock) { |
708 doBlockCommandLoop(); |
720 doBlockCommandLoop(); |
709 } |
721 } |
710 } |
722 } |
723 commandQueue.tail = NULL; |
735 commandQueue.tail = NULL; |
724 |
736 |
725 commandQueueLock = debugMonitorCreate("JDWP Event Helper Queue Monitor"); |
737 commandQueueLock = debugMonitorCreate("JDWP Event Helper Queue Monitor"); |
726 commandCompleteLock = debugMonitorCreate("JDWP Event Helper Completion Monitor"); |
738 commandCompleteLock = debugMonitorCreate("JDWP Event Helper Completion Monitor"); |
727 blockCommandLoopLock = debugMonitorCreate("JDWP Event Block CommandLoop Monitor"); |
739 blockCommandLoopLock = debugMonitorCreate("JDWP Event Block CommandLoop Monitor"); |
|
740 vmDeathLock = debugMonitorCreate("JDWP VM_DEATH CommandLoop Monitor"); |
728 |
741 |
729 /* Start the event handler thread */ |
742 /* Start the event handler thread */ |
730 func = &commandLoop; |
743 func = &commandLoop; |
731 (void)spawnNewThread(func, NULL, "JDWP Event Helper Thread"); |
744 (void)spawnNewThread(func, NULL, COMMAND_LOOP_THREAD_NAME); |
732 } |
745 } |
733 |
746 |
734 void |
747 void |
735 eventHelper_reset(jbyte newSessionID) |
748 eventHelper_reset(jbyte newSessionID) |
736 { |
749 { |
755 void |
768 void |
756 eventHelper_unlock(void) |
769 eventHelper_unlock(void) |
757 { |
770 { |
758 debugMonitorExit(commandCompleteLock); |
771 debugMonitorExit(commandCompleteLock); |
759 debugMonitorExit(commandQueueLock); |
772 debugMonitorExit(commandQueueLock); |
|
773 } |
|
774 |
|
775 void commandLoop_exitVmDeathLockOnError() |
|
776 { |
|
777 const char* MSG_BASE = "exitVmDeathLockOnError: error in JVMTI %s: %d\n"; |
|
778 jthread cur_thread = NULL; |
|
779 jvmtiThreadInfo thread_info; |
|
780 jvmtiError err = JVMTI_ERROR_NONE; |
|
781 |
|
782 err = JVMTI_FUNC_PTR(gdata->jvmti, GetCurrentThread) |
|
783 (gdata->jvmti, &cur_thread); |
|
784 if (err != JVMTI_ERROR_NONE) { |
|
785 LOG_ERROR((MSG_BASE, "GetCurrentThread", err)); |
|
786 return; |
|
787 } |
|
788 |
|
789 err = JVMTI_FUNC_PTR(gdata->jvmti, GetThreadInfo) |
|
790 (gdata->jvmti, cur_thread, &thread_info); |
|
791 if (err != JVMTI_ERROR_NONE) { |
|
792 LOG_ERROR((MSG_BASE, "GetThreadInfo", err)); |
|
793 return; |
|
794 } |
|
795 if (strcmp(thread_info.name, COMMAND_LOOP_THREAD_NAME) != 0) { |
|
796 return; |
|
797 } |
|
798 if (commandLoopEnteredVmDeathLock == JNI_TRUE) { |
|
799 debugMonitorExit(vmDeathLock); |
|
800 commandLoopEnteredVmDeathLock = JNI_FALSE; |
|
801 } |
|
802 } |
|
803 |
|
804 void |
|
805 commandLoop_sync(void) |
|
806 { |
|
807 debugMonitorEnter(vmDeathLock); |
|
808 debugMonitorExit(vmDeathLock); |
760 } |
809 } |
761 |
810 |
762 /* Change all references to global in the EventInfo struct */ |
811 /* Change all references to global in the EventInfo struct */ |
763 static void |
812 static void |
764 saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo) |
813 saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo) |