/*
 * Copyright (c) 1998, 2006, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */

#include "util.h"
#include "outStream.h"
#include "eventHandler.h"
#include "threadControl.h"
#include "invoker.h"

/*
 * Event helper thread command commandKinds
 */
#define COMMAND_REPORT_EVENT_COMPOSITE          1
#define COMMAND_REPORT_INVOKE_DONE              2
#define COMMAND_REPORT_VM_INIT                  3
#define COMMAND_SUSPEND_THREAD                  4

/*
 * Event helper thread command singleKinds
 */
#define COMMAND_SINGLE_EVENT                    11
#define COMMAND_SINGLE_UNLOAD                   12
#define COMMAND_SINGLE_FRAME_EVENT              13

typedef struct EventCommandSingle {
    jbyte suspendPolicy; /* NOTE: Must be the first field */
    jint id;
    EventInfo info;
} EventCommandSingle;

typedef struct UnloadCommandSingle {
    char *classSignature;
    jint id;
} UnloadCommandSingle;

typedef struct FrameEventCommandSingle {
    jbyte suspendPolicy; /* NOTE: Must be the first field */
    jint id;
    EventIndex ei;
    jthread thread;
    jclass clazz;
    jmethodID method;
    jlocation location;
    char typeKey;         /* Not used for method entry events */
                          /* If typeKey is 0, then no return value is needed */
    jvalue returnValue;   /* Not used for method entry events */
} FrameEventCommandSingle;

typedef struct CommandSingle {
    jint singleKind;
    union {
        EventCommandSingle eventCommand;
        UnloadCommandSingle unloadCommand;
        FrameEventCommandSingle frameEventCommand;
    } u;
} CommandSingle;

typedef struct ReportInvokeDoneCommand {
    jthread thread;
} ReportInvokeDoneCommand;

typedef struct ReportVMInitCommand {
    jbyte suspendPolicy; /* NOTE: Must be the first field */
    jthread thread;
} ReportVMInitCommand;

typedef struct SuspendThreadCommand {
    jthread thread;
} SuspendThreadCommand;

typedef struct ReportEventCompositeCommand {
    jbyte suspendPolicy; /* NOTE: Must be the first field */
    jint eventCount;
    CommandSingle singleCommand[1]; /* variable length */
} ReportEventCompositeCommand;

typedef struct HelperCommand {
    jint commandKind;
    jboolean done;
    jboolean waiting;
    jbyte sessionID;
    struct HelperCommand *next;
    union {
        /* NOTE: Each of the structs below must have the same first field */
        ReportEventCompositeCommand reportEventComposite;
        ReportInvokeDoneCommand     reportInvokeDone;
        ReportVMInitCommand         reportVMInit;
        SuspendThreadCommand        suspendThread;
    } u;
    /* composite array expand out, put nothing after */
} HelperCommand;

typedef struct {
    HelperCommand *head;
    HelperCommand *tail;
} CommandQueue;

static CommandQueue commandQueue;
static jrawMonitorID commandQueueLock;
static jrawMonitorID commandCompleteLock;
static jrawMonitorID blockCommandLoopLock;
static jint maxQueueSize = 50 * 1024; /* TO DO: Make this configurable */
static jboolean holdEvents;
static jint currentQueueSize = 0;
static jint currentSessionID;

static void saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo);
static void tossEventInfoRefs(JNIEnv *env, EventInfo *evinfo);

static jint
commandSize(HelperCommand *command)
{
    jint size = sizeof(HelperCommand);
    if (command->commandKind == COMMAND_REPORT_EVENT_COMPOSITE) {
        /*
         * One event is accounted for in the Helper Command. If there are
         * more, add to size here.
         */
        /*LINTED*/
        size += ((int)sizeof(CommandSingle) *
                     (command->u.reportEventComposite.eventCount - 1));
    }
    return size;
}

static void
freeCommand(HelperCommand *command)
{
    if ( command == NULL )
        return;
    jvmtiDeallocate(command);
}

static void
enqueueCommand(HelperCommand *command,
               jboolean wait, jboolean reportingVMDeath)
{
    static jboolean vmDeathReported = JNI_FALSE;
    CommandQueue *queue = &commandQueue;
    jint size = commandSize(command);

    command->done = JNI_FALSE;
    command->waiting = wait;
    command->next = NULL;

    debugMonitorEnter(commandQueueLock);
    while (size + currentQueueSize > maxQueueSize) {
        debugMonitorWait(commandQueueLock);
    }
    log_debugee_location("enqueueCommand(): HelperCommand being processed", NULL, NULL, 0);
    if (vmDeathReported) {
        /* send no more events after VMDeath and don't wait */
        wait = JNI_FALSE;
    } else {
        currentQueueSize += size;

        if (queue->head == NULL) {
            queue->head = command;
        } else {
            queue->tail->next = command;
        }
        queue->tail = command;

        if (reportingVMDeath) {
            vmDeathReported = JNI_TRUE;
        }
    }
    debugMonitorNotifyAll(commandQueueLock);
    debugMonitorExit(commandQueueLock);

    if (wait) {
        debugMonitorEnter(commandCompleteLock);
        while (!command->done) {
            log_debugee_location("enqueueCommand(): HelperCommand wait", NULL, NULL, 0);
            debugMonitorWait(commandCompleteLock);
        }
        freeCommand(command);
        debugMonitorExit(commandCompleteLock);
    }
}

static void
completeCommand(HelperCommand *command)
{
    if (command->waiting) {
        debugMonitorEnter(commandCompleteLock);
        command->done = JNI_TRUE;
        log_debugee_location("completeCommand(): HelperCommand done waiting", NULL, NULL, 0);
        debugMonitorNotifyAll(commandCompleteLock);
        debugMonitorExit(commandCompleteLock);
    } else {
        freeCommand(command);
    }
}

static HelperCommand *
dequeueCommand(void)
{
    HelperCommand *command = NULL;
    CommandQueue *queue = &commandQueue;
    jint size;

    debugMonitorEnter(commandQueueLock);

    while (command == NULL) {
        while (holdEvents || (queue->head == NULL)) {
            debugMonitorWait(commandQueueLock);
        }

        JDI_ASSERT(queue->head);
        command = queue->head;
        queue->head = command->next;
        if (queue->tail == command) {
            queue->tail = NULL;
        }

        log_debugee_location("dequeueCommand(): command being dequeued", NULL, NULL, 0);

        size = commandSize(command);
        /*
         * Immediately close out any commands enqueued from a
         * previously attached debugger.
         */
        if (command->sessionID != currentSessionID) {
            log_debugee_location("dequeueCommand(): command session removal", NULL, NULL, 0);
            completeCommand(command);
            command = NULL;
        }

        /*
         * There's room in the queue for more.
         */
        currentQueueSize -= size;
        debugMonitorNotifyAll(commandQueueLock);
    }

    debugMonitorExit(commandQueueLock);

    return command;
}

void eventHelper_holdEvents(void)
{
    debugMonitorEnter(commandQueueLock);
    holdEvents = JNI_TRUE;
    debugMonitorNotifyAll(commandQueueLock);
    debugMonitorExit(commandQueueLock);
}

void eventHelper_releaseEvents(void)
{
    debugMonitorEnter(commandQueueLock);
    holdEvents = JNI_FALSE;
    debugMonitorNotifyAll(commandQueueLock);
    debugMonitorExit(commandQueueLock);
}

static void
writeSingleStepEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
    (void)outStream_writeObjectRef(env, out, evinfo->thread);
    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
}

static void
writeBreakpointEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
    (void)outStream_writeObjectRef(env, out, evinfo->thread);
    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
}

static void
writeFieldAccessEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
    jbyte fieldClassTag;

    fieldClassTag = referenceTypeTag(evinfo->u.field_access.field_clazz);

    (void)outStream_writeObjectRef(env, out, evinfo->thread);
    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
    (void)outStream_writeByte(out, fieldClassTag);
    (void)outStream_writeObjectRef(env, out, evinfo->u.field_access.field_clazz);
    (void)outStream_writeFieldID(out, evinfo->u.field_access.field);
    (void)outStream_writeObjectTag(env, out, evinfo->object);
    (void)outStream_writeObjectRef(env, out, evinfo->object);
}

static void
writeFieldModificationEvent(JNIEnv *env, PacketOutputStream *out,
                            EventInfo *evinfo)
{
    jbyte fieldClassTag;

    fieldClassTag = referenceTypeTag(evinfo->u.field_modification.field_clazz);

    (void)outStream_writeObjectRef(env, out, evinfo->thread);
    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
    (void)outStream_writeByte(out, fieldClassTag);
    (void)outStream_writeObjectRef(env, out, evinfo->u.field_modification.field_clazz);
    (void)outStream_writeFieldID(out, evinfo->u.field_modification.field);
    (void)outStream_writeObjectTag(env, out, evinfo->object);
    (void)outStream_writeObjectRef(env, out, evinfo->object);
    (void)outStream_writeValue(env, out, (jbyte)evinfo->u.field_modification.signature_type,
                         evinfo->u.field_modification.new_value);
}

static void
writeExceptionEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
    (void)outStream_writeObjectRef(env, out, evinfo->thread);
    writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
    (void)outStream_writeObjectTag(env, out, evinfo->object);
    (void)outStream_writeObjectRef(env, out, evinfo->object);
    writeCodeLocation(out, evinfo->u.exception.catch_clazz,
                      evinfo->u.exception.catch_method, evinfo->u.exception.catch_location);
}

static void
writeThreadEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
    (void)outStream_writeObjectRef(env, out, evinfo->thread);
}

static void
writeMonitorEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
    jclass klass;
    (void)outStream_writeObjectRef(env, out, evinfo->thread);
    (void)outStream_writeObjectTag(env, out, evinfo->object);
    (void)outStream_writeObjectRef(env, out, evinfo->object);
    if (evinfo->ei == EI_MONITOR_WAIT || evinfo->ei == EI_MONITOR_WAITED) {
        /* clazz of evinfo was set to class of monitor object for monitor wait event class filtering.
         * So get the method class to write location info.
         * See cbMonitorWait() and cbMonitorWaited() function in eventHandler.c.
         */
        klass=getMethodClass(gdata->jvmti, evinfo->method);
        writeCodeLocation(out, klass, evinfo->method, evinfo->location);
        if (evinfo->ei == EI_MONITOR_WAIT) {
            (void)outStream_writeLong(out, evinfo->u.monitor.timeout);
        } else  if (evinfo->ei == EI_MONITOR_WAITED) {
            (void)outStream_writeBoolean(out, evinfo->u.monitor.timed_out);
        }
        /* This runs in a command loop and this thread may not return to java.
         * So we need to delete the local ref created by jvmti GetMethodDeclaringClass.
         */
        JNI_FUNC_PTR(env,DeleteLocalRef)(env, klass);
    } else {
        writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
    }
}

static void
writeClassEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
    jbyte classTag;
    jint status;
    char *signature = NULL;
    jvmtiError error;

    classTag = referenceTypeTag(evinfo->clazz);
    error = classSignature(evinfo->clazz, &signature, NULL);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"signature");
    }
    status = classStatus(evinfo->clazz);

    (void)outStream_writeObjectRef(env, out, evinfo->thread);
    (void)outStream_writeByte(out, classTag);
    (void)outStream_writeObjectRef(env, out, evinfo->clazz);
    (void)outStream_writeString(out, signature);
    (void)outStream_writeInt(out, map2jdwpClassStatus(status));
    jvmtiDeallocate(signature);
}

static void
writeVMDeathEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
}

static void
handleEventCommandSingle(JNIEnv *env, PacketOutputStream *out,
                           EventCommandSingle *command)
{
    EventInfo *evinfo = &command->info;

    (void)outStream_writeByte(out, eventIndex2jdwp(evinfo->ei));
    (void)outStream_writeInt(out, command->id);

    switch (evinfo->ei) {
        case EI_SINGLE_STEP:
            writeSingleStepEvent(env, out, evinfo);
            break;
        case EI_BREAKPOINT:
            writeBreakpointEvent(env, out, evinfo);
            break;
        case EI_FIELD_ACCESS:
            writeFieldAccessEvent(env, out, evinfo);
            break;
        case EI_FIELD_MODIFICATION:
            writeFieldModificationEvent(env, out, evinfo);
            break;
        case EI_EXCEPTION:
            writeExceptionEvent(env, out, evinfo);
            break;
        case EI_THREAD_START:
        case EI_THREAD_END:
            writeThreadEvent(env, out, evinfo);
            break;
        case EI_CLASS_LOAD:
        case EI_CLASS_PREPARE:
            writeClassEvent(env, out, evinfo);
            break;
        case EI_MONITOR_CONTENDED_ENTER:
        case EI_MONITOR_CONTENDED_ENTERED:
        case EI_MONITOR_WAIT:
        case EI_MONITOR_WAITED:
            writeMonitorEvent(env, out, evinfo);
            break;
        case EI_VM_DEATH:
            writeVMDeathEvent(env, out, evinfo);
            break;
        default:
            EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"unknown event index");
            break;
    }
    tossEventInfoRefs(env, evinfo);
}

static void
handleUnloadCommandSingle(JNIEnv* env, PacketOutputStream *out,
                           UnloadCommandSingle *command)
{
    (void)outStream_writeByte(out, JDWP_EVENT(CLASS_UNLOAD));
    (void)outStream_writeInt(out, command->id);
    (void)outStream_writeString(out, command->classSignature);
    jvmtiDeallocate(command->classSignature);
    command->classSignature = NULL;
}

static void
handleFrameEventCommandSingle(JNIEnv* env, PacketOutputStream *out,
                              FrameEventCommandSingle *command)
{
    if (command->typeKey) {
        (void)outStream_writeByte(out, JDWP_EVENT(METHOD_EXIT_WITH_RETURN_VALUE));
    } else {
        (void)outStream_writeByte(out, eventIndex2jdwp(command->ei));
    }
    (void)outStream_writeInt(out, command->id);
    (void)outStream_writeObjectRef(env, out, command->thread);
    writeCodeLocation(out, command->clazz, command->method, command->location);
    if (command->typeKey) {
        (void)outStream_writeValue(env, out, command->typeKey, command->returnValue);
        if (isObjectTag(command->typeKey) &&
            command->returnValue.l != NULL) {
            tossGlobalRef(env, &(command->returnValue.l));
        }
    }
    tossGlobalRef(env, &(command->thread));
    tossGlobalRef(env, &(command->clazz));
}

static void
suspendWithInvokeEnabled(jbyte policy, jthread thread)
{
    invoker_enableInvokeRequests(thread);

    if (policy == JDWP_SUSPEND_POLICY(ALL)) {
        (void)threadControl_suspendAll();
    } else {
        (void)threadControl_suspendThread(thread, JNI_FALSE);
    }
}

static void
handleReportEventCompositeCommand(JNIEnv *env,
                                  ReportEventCompositeCommand *recc)
{
    PacketOutputStream out;
    jint count = recc->eventCount;
    jint i;

    if (recc->suspendPolicy != JDWP_SUSPEND_POLICY(NONE)) {
        /* must determine thread to interrupt before writing */
        /* since writing destroys it */
        jthread thread = NULL;
        for (i = 0; i < count; i++) {
            CommandSingle *single = &(recc->singleCommand[i]);
            switch (single->singleKind) {
                case COMMAND_SINGLE_EVENT:
                    thread = single->u.eventCommand.info.thread;
                    break;
                case COMMAND_SINGLE_FRAME_EVENT:
                    thread = single->u.frameEventCommand.thread;
                    break;
            }
            if (thread != NULL) {
                break;
            }
        }

        if (thread == NULL) {
            (void)threadControl_suspendAll();
        } else {
            suspendWithInvokeEnabled(recc->suspendPolicy, thread);
        }
    }

    outStream_initCommand(&out, uniqueID(), 0x0,
                          JDWP_COMMAND_SET(Event),
                          JDWP_COMMAND(Event, Composite));
    (void)outStream_writeByte(&out, recc->suspendPolicy);
    (void)outStream_writeInt(&out, count);

    for (i = 0; i < count; i++) {
        CommandSingle *single = &(recc->singleCommand[i]);
        switch (single->singleKind) {
            case COMMAND_SINGLE_EVENT:
                handleEventCommandSingle(env, &out,
                                         &single->u.eventCommand);
                break;
            case COMMAND_SINGLE_UNLOAD:
                handleUnloadCommandSingle(env, &out,
                                          &single->u.unloadCommand);
                break;
            case COMMAND_SINGLE_FRAME_EVENT:
                handleFrameEventCommandSingle(env, &out,
                                              &single->u.frameEventCommand);
                break;
        }
    }

    outStream_sendCommand(&out);
    outStream_destroy(&out);
}

static void
handleReportInvokeDoneCommand(JNIEnv* env, ReportInvokeDoneCommand *command)
{
    invoker_completeInvokeRequest(command->thread);
    tossGlobalRef(env, &(command->thread));
}

static void
handleReportVMInitCommand(JNIEnv* env, ReportVMInitCommand *command)
{
    PacketOutputStream out;

    if (command->suspendPolicy == JDWP_SUSPEND_POLICY(ALL)) {
        (void)threadControl_suspendAll();
    } else if (command->suspendPolicy == JDWP_SUSPEND_POLICY(EVENT_THREAD)) {
        (void)threadControl_suspendThread(command->thread, JNI_FALSE);
    }

    outStream_initCommand(&out, uniqueID(), 0x0,
                          JDWP_COMMAND_SET(Event),
                          JDWP_COMMAND(Event, Composite));
    (void)outStream_writeByte(&out, command->suspendPolicy);
    (void)outStream_writeInt(&out, 1);   /* Always one component */
    (void)outStream_writeByte(&out, JDWP_EVENT(VM_INIT));
    (void)outStream_writeInt(&out, 0);    /* Not in response to an event req. */

    (void)outStream_writeObjectRef(env, &out, command->thread);

    outStream_sendCommand(&out);
    outStream_destroy(&out);
    /* Why aren't we tossing this: tossGlobalRef(env, &(command->thread)); */
}

static void
handleSuspendThreadCommand(JNIEnv* env, SuspendThreadCommand *command)
{
    /*
     * For the moment, there's  nothing that can be done with the
     * return code, so we don't check it here.
     */
    (void)threadControl_suspendThread(command->thread, JNI_TRUE);
    tossGlobalRef(env, &(command->thread));
}

static void
handleCommand(JNIEnv *env, HelperCommand *command)
{
    switch (command->commandKind) {
        case COMMAND_REPORT_EVENT_COMPOSITE:
            handleReportEventCompositeCommand(env,
                                        &command->u.reportEventComposite);
            break;
        case COMMAND_REPORT_INVOKE_DONE:
            handleReportInvokeDoneCommand(env, &command->u.reportInvokeDone);
            break;
        case COMMAND_REPORT_VM_INIT:
            handleReportVMInitCommand(env, &command->u.reportVMInit);
            break;
        case COMMAND_SUSPEND_THREAD:
            handleSuspendThreadCommand(env, &command->u.suspendThread);
            break;
        default:
            EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"Event Helper Command");
            break;
    }
}

/*
 * There was an assumption that only one event with a suspend-all
 * policy could be processed by commandLoop() at one time. It was
 * assumed that native thread suspension from the first suspend-all
 * event would prevent the second suspend-all event from making it
 * into the command queue. For the Classic VM, this was a reasonable
 * assumption. However, in HotSpot all thread suspension requires a
 * VM operation and VM operations take time.
 *
 * The solution is to add a mechanism to prevent commandLoop() from
 * processing more than one event with a suspend-all policy. This is
 * accomplished by forcing commandLoop() to wait for either
 * ThreadReferenceImpl.c: resume() or VirtualMachineImpl.c: resume()
 * when an event with a suspend-all policy has been completed.
 */
static jboolean blockCommandLoop = JNI_FALSE;

/*
 * We wait for either ThreadReferenceImpl.c: resume() or
 * VirtualMachineImpl.c: resume() to be called.
 */
static void
doBlockCommandLoop(void) {
    debugMonitorEnter(blockCommandLoopLock);
    while (blockCommandLoop == JNI_TRUE) {
        debugMonitorWait(blockCommandLoopLock);
    }
    debugMonitorExit(blockCommandLoopLock);
}

/*
 * If the command that we are about to execute has a suspend-all
 * policy, then prepare for either ThreadReferenceImpl.c: resume()
 * or VirtualMachineImpl.c: resume() to be called.
 */
static jboolean
needBlockCommandLoop(HelperCommand *cmd) {
    if (cmd->commandKind == COMMAND_REPORT_EVENT_COMPOSITE
    && cmd->u.reportEventComposite.suspendPolicy == JDWP_SUSPEND_POLICY(ALL)) {
        debugMonitorEnter(blockCommandLoopLock);
        blockCommandLoop = JNI_TRUE;
        debugMonitorExit(blockCommandLoopLock);

        return JNI_TRUE;
    }

    return JNI_FALSE;
}

/*
 * Used by either ThreadReferenceImpl.c: resume() or
 * VirtualMachineImpl.c: resume() to resume commandLoop().
 */
void
unblockCommandLoop(void) {
    debugMonitorEnter(blockCommandLoopLock);
    blockCommandLoop = JNI_FALSE;
    debugMonitorNotifyAll(blockCommandLoopLock);
    debugMonitorExit(blockCommandLoopLock);
}

/*
 * The event helper thread. Dequeues commands and processes them.
 */
static void JNICALL
commandLoop(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg)
{
    LOG_MISC(("Begin command loop thread"));

    while (JNI_TRUE) {
        HelperCommand *command = dequeueCommand();
        if (command != NULL) {
            /*
             * Setup for a potential doBlockCommand() call before calling
             * handleCommand() to prevent any races.
             */
            jboolean doBlock = needBlockCommandLoop(command);
            log_debugee_location("commandLoop(): command being handled", NULL, NULL, 0);
            handleCommand(jni_env, command);
            completeCommand(command);
            /* if we just finished a suspend-all cmd, then we block here */
            if (doBlock) {
                doBlockCommandLoop();
            }
        }
    }
    /* This loop never ends, even as connections come and go with server=y */
}

void
eventHelper_initialize(jbyte sessionID)
{
    jvmtiStartFunction func;

    currentSessionID = sessionID;
    holdEvents = JNI_FALSE;
    commandQueue.head = NULL;
    commandQueue.tail = NULL;

    commandQueueLock = debugMonitorCreate("JDWP Event Helper Queue Monitor");
    commandCompleteLock = debugMonitorCreate("JDWP Event Helper Completion Monitor");
    blockCommandLoopLock = debugMonitorCreate("JDWP Event Block CommandLoop Monitor");

    /* Start the event handler thread */
    func = &commandLoop;
    (void)spawnNewThread(func, NULL, "JDWP Event Helper Thread");
}

void
eventHelper_reset(jbyte newSessionID)
{
    debugMonitorEnter(commandQueueLock);
    currentSessionID = newSessionID;
    holdEvents = JNI_FALSE;
    debugMonitorNotifyAll(commandQueueLock);
    debugMonitorExit(commandQueueLock);
}

/*
 * Provide a means for threadControl to ensure that crucial locks are not
 * held by suspended threads.
 */
void
eventHelper_lock(void)
{
    debugMonitorEnter(commandQueueLock);
    debugMonitorEnter(commandCompleteLock);
}

void
eventHelper_unlock(void)
{
    debugMonitorExit(commandCompleteLock);
    debugMonitorExit(commandQueueLock);
}

/* Change all references to global in the EventInfo struct */
static void
saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo)
{
    jthread *pthread;
    jclass *pclazz;
    jobject *pobject;
    jthread thread;
    jclass clazz;
    jobject object;
    char sig;

    JNI_FUNC_PTR(env,ExceptionClear)(env);

    if ( evinfo->thread != NULL ) {
        pthread = &(evinfo->thread);
        thread = *pthread;
        *pthread = NULL;
        saveGlobalRef(env, thread, pthread);
    }
    if ( evinfo->clazz != NULL ) {
        pclazz = &(evinfo->clazz);
        clazz = *pclazz;
        *pclazz = NULL;
        saveGlobalRef(env, clazz, pclazz);
    }
    if ( evinfo->object != NULL ) {
        pobject = &(evinfo->object);
        object = *pobject;
        *pobject = NULL;
        saveGlobalRef(env, object, pobject);
    }

    switch (evinfo->ei) {
        case EI_FIELD_MODIFICATION:
            if ( evinfo->u.field_modification.field_clazz != NULL ) {
                pclazz = &(evinfo->u.field_modification.field_clazz);
                clazz = *pclazz;
                *pclazz = NULL;
                saveGlobalRef(env, clazz, pclazz);
            }
            sig = evinfo->u.field_modification.signature_type;
            if ((sig == JDWP_TAG(ARRAY)) || (sig == JDWP_TAG(OBJECT))) {
                if ( evinfo->u.field_modification.new_value.l != NULL ) {
                    pobject = &(evinfo->u.field_modification.new_value.l);
                    object = *pobject;
                    *pobject = NULL;
                    saveGlobalRef(env, object, pobject);
                }
            }
            break;
        case EI_FIELD_ACCESS:
            if ( evinfo->u.field_access.field_clazz != NULL ) {
                pclazz = &(evinfo->u.field_access.field_clazz);
                clazz = *pclazz;
                *pclazz = NULL;
                saveGlobalRef(env, clazz, pclazz);
            }
            break;
        case EI_EXCEPTION:
            if ( evinfo->u.exception.catch_clazz != NULL ) {
                pclazz = &(evinfo->u.exception.catch_clazz);
                clazz = *pclazz;
                *pclazz = NULL;
                saveGlobalRef(env, clazz, pclazz);
            }
            break;
        default:
            break;
    }

    if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
        EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"ExceptionOccurred");
    }
}

static void
tossEventInfoRefs(JNIEnv *env, EventInfo *evinfo)
{
    char sig;
    if ( evinfo->thread != NULL ) {
        tossGlobalRef(env, &(evinfo->thread));
    }
    if ( evinfo->clazz != NULL ) {
        tossGlobalRef(env, &(evinfo->clazz));
    }
    if ( evinfo->object != NULL ) {
        tossGlobalRef(env, &(evinfo->object));
    }
    switch (evinfo->ei) {
        case EI_FIELD_MODIFICATION:
            if ( evinfo->u.field_modification.field_clazz != NULL ) {
                tossGlobalRef(env, &(evinfo->u.field_modification.field_clazz));
            }
            sig = evinfo->u.field_modification.signature_type;
            if ((sig == JDWP_TAG(ARRAY)) || (sig == JDWP_TAG(OBJECT))) {
                if ( evinfo->u.field_modification.new_value.l != NULL ) {
                    tossGlobalRef(env, &(evinfo->u.field_modification.new_value.l));
                }
            }
            break;
        case EI_FIELD_ACCESS:
            if ( evinfo->u.field_access.field_clazz != NULL ) {
                tossGlobalRef(env, &(evinfo->u.field_access.field_clazz));
            }
            break;
        case EI_EXCEPTION:
            if ( evinfo->u.exception.catch_clazz != NULL ) {
                tossGlobalRef(env, &(evinfo->u.exception.catch_clazz));
            }
            break;
        default:
            break;
    }
}

struct bag *
eventHelper_createEventBag(void)
{
    return bagCreateBag(sizeof(CommandSingle), 5 /* events */ );
}

/* Return the combined suspend policy for the event set
 */
static jboolean
enumForCombinedSuspendPolicy(void *cv, void *arg)
{
    CommandSingle *command = cv;
    jbyte thisPolicy;
    jbyte *policy = arg;

    switch(command->singleKind) {
        case COMMAND_SINGLE_EVENT:
            thisPolicy = command->u.eventCommand.suspendPolicy;
            break;
        case COMMAND_SINGLE_FRAME_EVENT:
            thisPolicy = command->u.frameEventCommand.suspendPolicy;
            break;
        default:
            thisPolicy = JDWP_SUSPEND_POLICY(NONE);
    }
    /* Expand running policy value if this policy demands it */
    if (*policy == JDWP_SUSPEND_POLICY(NONE)) {
        *policy = thisPolicy;
    } else if (*policy == JDWP_SUSPEND_POLICY(EVENT_THREAD)) {
        *policy = (thisPolicy == JDWP_SUSPEND_POLICY(ALL))?
                        thisPolicy : *policy;
    }

    /* Short circuit if we reached maximal suspend policy */
    if (*policy == JDWP_SUSPEND_POLICY(ALL)) {
        return JNI_FALSE;
    } else {
        return JNI_TRUE;
    }
}

/* Determine whether we are reporting VM death
 */
static jboolean
enumForVMDeath(void *cv, void *arg)
{
    CommandSingle *command = cv;
    jboolean *reportingVMDeath = arg;

    if (command->singleKind == COMMAND_SINGLE_EVENT) {
        if (command->u.eventCommand.info.ei == EI_VM_DEATH) {
            *reportingVMDeath = JNI_TRUE;
            return JNI_FALSE;
        }
    }
    return JNI_TRUE;
}

struct singleTracker {
    ReportEventCompositeCommand *recc;
    int index;
};

static jboolean
enumForCopyingSingles(void *command, void *tv)
{
    struct singleTracker *tracker = (struct singleTracker *)tv;
    (void)memcpy(&tracker->recc->singleCommand[tracker->index++],
           command,
           sizeof(CommandSingle));
    return JNI_TRUE;
}

jbyte
eventHelper_reportEvents(jbyte sessionID, struct bag *eventBag)
{
    int size = bagSize(eventBag);
    jbyte suspendPolicy = JDWP_SUSPEND_POLICY(NONE);
    jboolean reportingVMDeath = JNI_FALSE;
    jboolean wait;
    int command_size;

    HelperCommand *command;
    ReportEventCompositeCommand *recc;
    struct singleTracker tracker;

    if (size == 0) {
        return suspendPolicy;
    }
    (void)bagEnumerateOver(eventBag, enumForCombinedSuspendPolicy, &suspendPolicy);
    (void)bagEnumerateOver(eventBag, enumForVMDeath, &reportingVMDeath);

    /*LINTED*/
    command_size = (int)(sizeof(HelperCommand) +
                         sizeof(CommandSingle)*(size-1));
    command = jvmtiAllocate(command_size);
    (void)memset(command, 0, command_size);
    command->commandKind = COMMAND_REPORT_EVENT_COMPOSITE;
    command->sessionID = sessionID;
    recc = &command->u.reportEventComposite;
    recc->suspendPolicy = suspendPolicy;
    recc->eventCount = size;
    tracker.recc = recc;
    tracker.index = 0;
    (void)bagEnumerateOver(eventBag, enumForCopyingSingles, &tracker);

    /*
     * We must wait if this thread (the event thread) is to be
     * suspended or if the VM is about to die. (Waiting in the latter
     * case ensures that we get the event out before the process dies.)
     */
    wait = (jboolean)((suspendPolicy != JDWP_SUSPEND_POLICY(NONE)) ||
                      reportingVMDeath);
    enqueueCommand(command, wait, reportingVMDeath);
    return suspendPolicy;
}

void
eventHelper_recordEvent(EventInfo *evinfo, jint id, jbyte suspendPolicy,
                         struct bag *eventBag)
{
    JNIEnv *env = getEnv();
    CommandSingle *command = bagAdd(eventBag);
    if (command == NULL) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"badAdd(eventBag)");
    }

    command->singleKind = COMMAND_SINGLE_EVENT;
    command->u.eventCommand.suspendPolicy = suspendPolicy;
    command->u.eventCommand.id = id;

    /*
     * Copy the event into the command so that it can be used
     * asynchronously by the event helper thread.
     */
    (void)memcpy(&command->u.eventCommand.info, evinfo, sizeof(*evinfo));
    saveEventInfoRefs(env, &command->u.eventCommand.info);
}

void
eventHelper_recordClassUnload(jint id, char *signature, struct bag *eventBag)
{
    CommandSingle *command = bagAdd(eventBag);
    if (command == NULL) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"bagAdd(eventBag)");
    }
    command->singleKind = COMMAND_SINGLE_UNLOAD;
    command->u.unloadCommand.id = id;
    command->u.unloadCommand.classSignature = signature;
}

void
eventHelper_recordFrameEvent(jint id, jbyte suspendPolicy, EventIndex ei,
                             jthread thread, jclass clazz,
                             jmethodID method, jlocation location,
                             int needReturnValue,
                             jvalue returnValue,
                             struct bag *eventBag)
{
    JNIEnv *env = getEnv();
    FrameEventCommandSingle *frameCommand;
    CommandSingle *command = bagAdd(eventBag);
    jvmtiError err = JVMTI_ERROR_NONE;
    if (command == NULL) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"bagAdd(eventBag)");
    }

    command->singleKind = COMMAND_SINGLE_FRAME_EVENT;
    frameCommand = &command->u.frameEventCommand;
    frameCommand->suspendPolicy = suspendPolicy;
    frameCommand->id = id;
    frameCommand->ei = ei;
    saveGlobalRef(env, thread, &(frameCommand->thread));
    saveGlobalRef(env, clazz, &(frameCommand->clazz));
    frameCommand->method = method;
    frameCommand->location = location;
    if (needReturnValue) {
        err = methodReturnType(method, &frameCommand->typeKey);
        JDI_ASSERT(err == JVMTI_ERROR_NONE);

        /*
         * V or B C D F I J S Z L <classname> ;    [ ComponentType
         */
        if (isObjectTag(frameCommand->typeKey) &&
            returnValue.l != NULL) {
            saveGlobalRef(env, returnValue.l, &(frameCommand->returnValue.l));
        } else {
            frameCommand->returnValue = returnValue;
        }
    } else {
      /* This is not a JDWP METHOD_EXIT_WITH_RETURN_VALUE request,
       * so signal this by setting typeKey = 0 which is not
       * a legal typekey.
       */
       frameCommand->typeKey = 0;
    }
}

void
eventHelper_reportInvokeDone(jbyte sessionID, jthread thread)
{
    JNIEnv *env = getEnv();
    HelperCommand *command = jvmtiAllocate(sizeof(*command));
    if (command == NULL) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"HelperCommand");
    }
    (void)memset(command, 0, sizeof(*command));
    command->commandKind = COMMAND_REPORT_INVOKE_DONE;
    command->sessionID = sessionID;
    saveGlobalRef(env, thread, &(command->u.reportInvokeDone.thread));
    enqueueCommand(command, JNI_TRUE, JNI_FALSE);
}

/*
 * This, currently, cannot go through the normal event handling code
 * because the JVMTI event does not contain a thread.
 */
void
eventHelper_reportVMInit(JNIEnv *env, jbyte sessionID, jthread thread, jbyte suspendPolicy)
{
    HelperCommand *command = jvmtiAllocate(sizeof(*command));
    if (command == NULL) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"HelperCommmand");
    }
    (void)memset(command, 0, sizeof(*command));
    command->commandKind = COMMAND_REPORT_VM_INIT;
    command->sessionID = sessionID;
    saveGlobalRef(env, thread, &(command->u.reportVMInit.thread));
    command->u.reportVMInit.suspendPolicy = suspendPolicy;
    enqueueCommand(command, JNI_TRUE, JNI_FALSE);
}

void
eventHelper_suspendThread(jbyte sessionID, jthread thread)
{
    JNIEnv *env = getEnv();
    HelperCommand *command = jvmtiAllocate(sizeof(*command));
    if (command == NULL) {
        EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"HelperCommmand");
    }
    (void)memset(command, 0, sizeof(*command));
    command->commandKind = COMMAND_SUSPEND_THREAD;
    command->sessionID = sessionID;
    saveGlobalRef(env, thread, &(command->u.suspendThread.thread));
    enqueueCommand(command, JNI_TRUE, JNI_FALSE);
}
