/*
 * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 *  @test
 *  @bug 6293795
 *  @summary  Backend hangs when invokeMethod is called from a JDI eventHandler
 *
 *  @author jjh
 *
 *  @run build TestScaffold VMConnection TargetListener TargetAdapter
 *  @run compile -g InvokeHangTest.java
 *  @run main InvokeHangTest
 */
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;

import java.util.*;

/*
 * This debuggee basically runs two threads each of
 * which loop, hitting a bkpt in each iteration.
 *
 */
class InvokeHangTarg extends Thread {
    static boolean one = false;
    static String name1 = "Thread 1";
    static String name2 = "Thread 2";
    static int count = 100;

    public static void main(String[] args) {
        System.out.println("Howdy!");
        InvokeHangTarg t1 = new InvokeHangTarg(name1);
        InvokeHangTarg t2 = new InvokeHangTarg(name2);

        t1.start();
        t2.start();
    }

    // This is called from the debugger via invokeMethod
    public double invokeee() {
        System.out.println("Debuggee: invokeee in thread "+Thread.currentThread().toString());
        yield();
        return longMethod(2);
    }
    public double longMethod(int n) {
        double a = 0;
        double s = 0;
        for (int i = 0; i < n; i++) {
            a += i;
            for (int j = -1000*i; j < 1000*i; j++) {
                a = a*(1 + i/(j + 0.5));
                s += Math.sin(a);
            }
        }
        System.out.println("Debuggee: invokeee finished");
        return s;
    }

    public InvokeHangTarg(String name) {
        super(name);
    }

    public void run() {
        if (getName().equals(name1)) {
            run1();
        } else {
            run2();
        }
    }

    public void bkpt1(int i) {
        System.out.println("Debuggee: " + Thread.currentThread() +" is running:" + i);
        try {
            Thread.currentThread().sleep(2);
        } catch (InterruptedException iex) {}
        //yield();
    }

    public void run1() {
        int i = 0;
        while (i < count) {
            i++;
            bkpt1(i);
        }
    }

    public void bkpt2(int i) {
        System.out.println("Debuggee: " + Thread.currentThread() +" is running:" + i);
        try {
            Thread.currentThread().sleep(2);
        } catch (InterruptedException iex) {}
            //yield();
    }

    public void run2() {
        int i = 0;
        while (i < count) {
            i++;
            bkpt2(i);
        }
    }
}

/********** test program **********/

public class InvokeHangTest extends TestScaffold {
    ReferenceType targetClass;
    ThreadReference mainThread;
    BreakpointRequest request1;
    BreakpointRequest request2;
    static volatile int bkpts = 0;
    Thread timerThread;
    static int waitTime = 20000;

    InvokeHangTest (String args[]) {
        super(args);
    }

    public static void main(String[] args)      throws Exception {
        new InvokeHangTest(args).startTests();
    }

    void doInvoke(ThreadReference thread, ObjectReference ref, String methodName) {
        List methods = ref.referenceType().methodsByName(methodName);
        Method method = (Method) methods.get(0);
        try {
            System.err.println("  Debugger: Invoking in thread" + thread);
            ref.invokeMethod(thread, method, new ArrayList(), ref.INVOKE_NONVIRTUAL);
            System.err.println("  Debugger: Invoke done");
        } catch (Exception ex) {
            ex.printStackTrace();
            failure("failure: Exception");
        }
    }

    // BreakpointEvent handler
    public void breakpointReached(BreakpointEvent event) {
        if (bkpts == 0) {
            /*
             * This thread will watch for n secs to go by with no
             * calls to this method.
             */
            timerThread.start();
        }

        synchronized("abc") {
            /*
             * Note that this will most likely never get to
             * the number of times the two bkpt lines in the debuggee
             * are hit because bkpts are lost while they are disabled.
             */
            bkpts++;
        }

        /*
         * The bug occurs when the requests are disabled
         * and then an invoke is done in the event handler.  In some cases
         * the other thread has hit a bkpt and the back-end is waiting
         * to send it.  When the back-end resumes the debuggee to do the
         * invokeMethod, this 2nd bkpt is released, the debuggee is suspended, including
         * the thread on which the invoke was done (because it is a SUSPEND_ALL bkpt),
         * the bkpt is sent to the front-end, but the client event handler is sitting
         * here waiting for the invoke to finish, so it doesn't get the 2nd bkpt and
         * do the resume for it.  Thus, the debuggee is suspended waiting for a resume
         * that never comes.
         */
        request1.disable();
        request2.disable();

        ThreadReference thread = event.thread();
        try {
            StackFrame sf = thread.frame(0);
            System.err.println("  Debugger: Breakpoint hit at "+sf.location());
            doInvoke(thread, sf.thisObject(), "invokeee");
        } catch (IncompatibleThreadStateException itsex) {
            itsex.printStackTrace();
            failure("failure: Exception");
        }
        request1.enable();
        request2.enable();

    }

    /********** test core **********/

    protected void runTests() throws Exception {

        /*
         * Get to the top of main()
         * to determine targetClass and mainThread
         */
        BreakpointEvent bpe = startToMain("InvokeHangTarg");
        targetClass = bpe.location().declaringType();
        mainThread = bpe.thread();
        EventRequestManager erm = vm().eventRequestManager();
        final Thread mainThread = Thread.currentThread();

        /*
         * Set event requests
         */
        Location loc1 = findMethod(targetClass, "bkpt1", "(I)V").location();
        Location loc2 = findMethod(targetClass, "bkpt2", "(I)V").location();
        request1 = erm.createBreakpointRequest(loc1);
        request2 = erm.createBreakpointRequest(loc2);
        request1.enable();
        request2.enable();

        /*
         * This thread will be started when we get the first bkpt.
         * (Which we always expect to get).
         * It awakens every n seconds and checks to see if we
         * got any breakpoint events while it was asleep.  If not, then
         * we assume the debuggee is hung and fail the test.
         */
        timerThread = new Thread("test timer") {
                public void run() {
                    int myBkpts = bkpts;
                    while (true) {
                        try {
                            Thread.sleep(waitTime);
                            System.out.println("bkpts = " + bkpts);
                            if (myBkpts == bkpts) {
                                // no bkpt for 'waitTime' msecs
                                failure("failure: Debuggee appears to be hung");
                                vmDisconnected = true;
                                // This awakens the main thread which is
                                // waiting for a VMDisconnect.
                                mainThread.interrupt();
                                break;
                            }
                            myBkpts = bkpts;
                        } catch (InterruptedException ee) {
                            // If the test completes, this occurs.
                            println("timer Interrupted");
                            break;
                        }
                    }
                }
            };

        /*
         * resume the target, listening for events
         */
        listenUntilVMDisconnect();
        timerThread.interrupt();
        /*
         * deal with results of test
         * if anything has called failure("foo") testFailed will be true
         */
        if (!testFailed) {
            println("InvokeHangTest: passed; bkpts = " + bkpts);
        } else {
            throw new Exception("InvokeHangTest: failed; bkpts = " + bkpts);
        }
    }
}
