1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.harmony.jpda.tests.jdwp.share.debuggee; 20 21 import org.apache.harmony.jpda.tests.jdwp.share.JDWPInvokeMethodWithSuspensionTestCase; 22 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 23 import org.apache.harmony.jpda.tests.share.SyncDebuggee; 24 25 /** 26 * Debuggee for subclasses of {@link JDWPInvokeMethodWithSuspensionTestCase}. 27 */ 28 public class InvokeMethodWithSuspensionDebuggee extends SyncDebuggee { 29 // Information for the test. 30 public static final String STATIC_METHOD_NAME = "invokedStaticMethod"; 31 public static final String INSTANCE_METHOD_NAME = "invokedInstanceMethod"; 32 public static final String BREAKPOINT_EVENT_THREAD_METHOD_NAME = "breakpointEventThread"; 33 public static final String BREAKPOINT_ALL_THREADS_METHOD_NAME = "breakpointAllThreads"; 34 35 private static volatile boolean testThreadFinished = false; 36 private static Thread testThread = null; 37 private static boolean enableThreadSuspensionForTesting = false; 38 39 private class TestThread extends Thread { TestThread()40 public TestThread() { 41 super("TestThread"); 42 } 43 44 @Override run()45 public void run() { 46 logWriter.println("TestThread starts"); 47 48 // We're going to suspend all threads in the method below. 49 logWriter.println("Breakpoint for event thread #2"); 50 breakpointAllThreads(); 51 52 // The test needs to resume us so the invoke in progress in event thread #1 can 53 // complete. 54 testThreadFinished = true; 55 56 logWriter.println("TestThread ends"); 57 } 58 } 59 60 // Invoked to suspend main thread (event thread #1) on a breakpoint. breakpointEventThread()61 public void breakpointEventThread() { 62 } 63 64 // Invoked to suspend test thread (event thread #2) and all others threads on a breakpoint. breakpointAllThreads()65 public void breakpointAllThreads() { 66 } 67 68 // Invoked in event thread #1. This will unblock event thread #2 that will suspend all threads 69 // including event thread #1. This helps us check that the debugger is not blocked waiting for 70 // this invoke. causeEventThreadSuspension()71 private static void causeEventThreadSuspension() { 72 if (enableThreadSuspensionForTesting) { 73 // Start event thread #2. It's going to hit a breakpoint and suspend us. 74 testThread.start(); 75 76 // We don't use wait/notify pattern to be sure our loop is active. 77 while (!testThreadFinished) { 78 try { 79 Thread.sleep(100); 80 } catch (InterruptedException e) { 81 e.printStackTrace(); 82 } 83 } 84 } 85 } 86 87 // Static method to test ClassType.InvokeMethod. invokedStaticMethod()88 public static void invokedStaticMethod() { 89 causeEventThreadSuspension(); 90 } 91 92 // Constructor to test ClassType.NewInstance. InvokeMethodWithSuspensionDebuggee()93 public InvokeMethodWithSuspensionDebuggee() { 94 causeEventThreadSuspension(); 95 } 96 97 // Instance method to test ObjectReference.InvokeMethod. invokedInstanceMethod()98 public void invokedInstanceMethod() { 99 causeEventThreadSuspension(); 100 } 101 102 @Override run()103 public void run() { 104 logWriter.println("InvokeMethodWithThreadSuspensionDebuggee starts"); 105 106 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY); 107 108 // Create test thread but do not start it now. It will be started by the invoke from 109 // the test through JDWP. 110 testThread = new TestThread(); 111 112 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 113 114 enableThreadSuspensionForTesting = true; 115 116 // We want to suspend the main thread on a breakpoint. 117 logWriter.println("Breakpoint for event thread #1"); 118 breakpointEventThread(); 119 120 // Ensure tested thread is finished. 121 try { 122 testThread.join(); 123 } catch (InterruptedException e) { 124 logWriter.printError("Failed to join tested thread", e); 125 } 126 testThread = null; 127 128 logWriter.println("InvokeMethodWithThreadSuspensionDebuggee ends"); 129 } 130 main(String[] args)131 public static void main(String[] args) { 132 runDebuggee(InvokeMethodWithSuspensionDebuggee.class); 133 } 134 } 135