/*
 * Copyright (c) 1998, 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.  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.
 */
/*
 * eventHandler
 *
 * This module handles events as they come in directly from JVMTI
 * and also maps them to JDI events.  JDI events are those requested
 * at the JDI or JDWP level and seen on those levels.  Mapping is
 * one-to-many, a JVMTI event may map to several JDI events, or
 * to none.  Part of that mapping process is filteration, which
 * eventFilter sub-module handles.  A JDI EventRequest corresponds
 * to a HandlerNode and a JDI filter to the hidden HandlerNode data
 * used by eventFilter.  For example, if at the JDI level the user
 * executed:
 *
 *   EventRequestManager erm = vm.eventRequestManager();
 *   BreakpointRequest bp = erm.createBreakpointRequest();
 *   bp.enable();
 *   ClassPrepareRequest req = erm.createClassPrepareRequest();
 *   req.enable();
 *   req = erm.createClassPrepareRequest();
 *   req.addClassFilter("Foo*");
 *   req.enable();
 *
 * Three handlers would be created, the first with a LocationOnly
 * filter and the last with a ClassMatch  filter.
 * When a JVMTI class prepare event for "Foobar"
 * comes in, the second handler will create one JDI event, the
 * third handler will compare the class signature, and since
 * it matchs create a second event.  There may also be internal
 * events as there are in this case, one created by the front-end
 * and one by the back-end.
 *
 * Each event kind has a handler chain, which is a doublely linked
 * list of handlers for that kind of event.
 */
#include "util.h"
#include "eventHandler.h"
#include "eventHandlerRestricted.h"
#include "eventFilter.h"
#include "eventFilterRestricted.h"
#include "standardHandlers.h"
#include "threadControl.h"
#include "eventHelper.h"
#include "classTrack.h"
#include "commonRef.h"
#include "debugLoop.h"

static HandlerID requestIdCounter;
static jbyte currentSessionID;

/* Counter of active callbacks and flag for vm_death */
static int      active_callbacks   = 0;
static jboolean vm_death_callback_active = JNI_FALSE;
static jrawMonitorID callbackLock;
static jrawMonitorID callbackBlock;

/* Macros to surround callback code (non-VM_DEATH callbacks).
 *   Note that this just keeps a count of the non-VM_DEATH callbacks that
 *   are currently active, it does not prevent these callbacks from
 *   operating in parallel. It's the VM_DEATH callback that will wait
 *   for all these callbacks to finish up, so that it can report the
 *   VM_DEATH in a clean state.
 *   If the VM_DEATH callback is active in the BEGIN macro then this
 *   callback just blocks until released by the VM_DEATH callback.
 *   If the VM_DEATH callback is active in the END macro, then this
 *   callback will notify the VM_DEATH callback if it's the last one,
 *   and then block until released by the VM_DEATH callback.
 *   Why block? These threads are often the threads of the Java program,
 *   not blocking might mean that a return would continue execution of
 *   some java thread in the middle of VM_DEATH, this seems troubled.
 *
 *   WARNING: No not 'return' or 'goto' out of the BEGIN_CALLBACK/END_CALLBACK
 *            block, this will mess up the count.
 */

#define BEGIN_CALLBACK()                                                \
{ /* BEGIN OF CALLBACK */                                               \
    jboolean bypass = JNI_TRUE;                                         \
    debugMonitorEnter(callbackLock); {                                  \
        if (vm_death_callback_active) {                                 \
            /* allow VM_DEATH callback to finish */                     \
            debugMonitorExit(callbackLock);                             \
            /* Now block because VM is about to die */                  \
            debugMonitorEnter(callbackBlock);                           \
            debugMonitorExit(callbackBlock);                            \
        } else {                                                        \
            active_callbacks++;                                         \
            bypass = JNI_FALSE;                                         \
            debugMonitorExit(callbackLock);                             \
        }                                                               \
    }                                                                   \
    if ( !bypass ) {                                                    \
        /* BODY OF CALLBACK CODE */

#define END_CALLBACK() /* Part of bypass if body */                     \
        debugMonitorEnter(callbackLock); {                              \
            active_callbacks--;                                         \
            if (active_callbacks < 0) {                                 \
                EXIT_ERROR(0, "Problems tracking active callbacks");    \
            }                                                           \
            if (vm_death_callback_active) {                             \
                if (active_callbacks == 0) {                            \
                    debugMonitorNotifyAll(callbackLock);                \
                }                                                       \
                /* allow VM_DEATH callback to finish */                 \
                debugMonitorExit(callbackLock);                         \
                /* Now block because VM is about to die */              \
                debugMonitorEnter(callbackBlock);                       \
                debugMonitorExit(callbackBlock);                        \
            } else {                                                    \
                debugMonitorExit(callbackLock);                         \
            }                                                           \
        }                                                               \
    }                                                                   \
} /* END OF CALLBACK */

/*
 * We are starting with a very simple locking scheme
 * for event handling.  All readers and writers of data in
 * the handlers[] chain must own this lock for the duration
 * of its use. If contention becomes a problem, we can:
 *
 * 1) create a lock per event type.
 * 2) move to a readers/writers approach where multiple threads
 * can access the chains simultaneously while reading (the
 * normal activity of an event callback).
 */
static jrawMonitorID handlerLock;

typedef struct HandlerChain_ {
    HandlerNode *first;
    /* add lock here */
} HandlerChain;

/*
 * This array maps event kinds to handler chains.
 * Protected by handlerLock.
 */

static HandlerChain __handlers[EI_max-EI_min+1];

/* Given a HandlerNode, these access our private data.
 */
#define PRIVATE_DATA(node) \
       (&(((EventHandlerRestricted_HandlerNode*)(void*)(node))->private_ehpd))

#define NEXT(node) (PRIVATE_DATA(node)->private_next)
#define PREV(node) (PRIVATE_DATA(node)->private_prev)
#define CHAIN(node) (PRIVATE_DATA(node)->private_chain)
#define HANDLER_FUNCTION(node) (PRIVATE_DATA(node)->private_handlerFunction)

static jclass getObjectClass(jobject object);
static jvmtiError freeHandler(HandlerNode *node);

static jvmtiError freeHandlerChain(HandlerChain *chain);

static HandlerChain *
getHandlerChain(EventIndex i)
{
    if ( i < EI_min || i > EI_max ) {
        EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"bad index for handler");
    }
    return &(__handlers[i-EI_min]);
}

static void
insert(HandlerChain *chain, HandlerNode *node)
{
    HandlerNode *oldHead = chain->first;
    NEXT(node) = oldHead;
    PREV(node) = NULL;
    CHAIN(node) = chain;
    if (oldHead != NULL) {
        PREV(oldHead) = node;
    }
    chain->first = node;
}

static HandlerNode *
findInChain(HandlerChain *chain, HandlerID handlerID)
{
    HandlerNode *node = chain->first;
    while (node != NULL) {
        if (node->handlerID == handlerID) {
            return node;
        }
        node = NEXT(node);
    }
    return NULL;
}

static HandlerNode *
find(EventIndex ei, HandlerID handlerID)
{
    return findInChain(getHandlerChain(ei), handlerID);
}

/**
 * Deinsert.  Safe for non-inserted nodes.
 */
static void
deinsert(HandlerNode *node)
{
    HandlerChain *chain = CHAIN(node);

    if (chain == NULL) {
        return;
    }
    if (chain->first == node) {
        chain->first = NEXT(node);
    }
    if (NEXT(node) != NULL) {
        PREV(NEXT(node)) = PREV(node);
    }
    if (PREV(node) != NULL) {
        NEXT(PREV(node)) = NEXT(node);
    }
    CHAIN(node) = NULL;
}

jboolean
eventHandlerRestricted_iterator(EventIndex ei,
                              IteratorFunction func, void *arg)
{
    HandlerChain *chain;
    HandlerNode *node;
    JNIEnv *env;

    chain = getHandlerChain(ei);
    node = chain->first;
    env = getEnv();

    if ( func == NULL ) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL,"iterator function NULL");
    }

    while (node != NULL) {
        if (((func)(env, node, arg))) {
            return JNI_TRUE;
        }
        node = NEXT(node);
    }
    return JNI_FALSE;
}

/* BREAKPOINT, METHOD_ENTRY and SINGLE_STEP events are covered by
 * the co-location of events policy. Of these three co-located
 * events, METHOD_ENTRY is  always reported first and BREAKPOINT
 * is always reported last. Here are the possible combinations and
 * their order:
 *
 * (p1) METHOD_ENTRY, BREAKPOINT (existing)
 * (p2) METHOD_ENTRY, BREAKPOINT (new)
 * (p1) METHOD_ENTRY, SINGLE_STEP
 * (p1) METHOD_ENTRY, SINGLE_STEP, BREAKPOINT (existing)
 * (p1/p2) METHOD_ENTRY, SINGLE_STEP, BREAKPOINT (new)
 * (p1) SINGLE_STEP, BREAKPOINT (existing)
 * (p2) SINGLE_STEP, BREAKPOINT (new)
 *
 * BREAKPOINT (existing) indicates a BREAKPOINT that is set before
 * the other co-located event is posted. BREAKPOINT (new) indicates
 * a BREAKPOINT that is set after the other co-located event is
 * posted and before the thread has resumed execution.
 *
 * Co-location of events policy used to be implemented via
 * temporary BREAKPOINTs along with deferring the reporting of
 * non-BREAKPOINT co-located events, but the temporary BREAKPOINTs
 * caused performance problems on VMs where setting or clearing
 * BREAKPOINTs is expensive, e.g., HotSpot.
 *
 * The policy is now implemented in two phases. Phase 1: when a
 * METHOD_ENTRY or SINGLE_STEP event is received, if there is an
 * existing co-located BREAKPOINT, then the current event is
 * deferred. When the BREAKPOINT event is processed, the event
 * bag will contain the deferred METHOD_ENTRY and/or SINGLE_STEP
 * events along with the BREAKPOINT event. For a METHOD_ENTRY
 * event where there is not an existing co-located BREAKPOINT,
 * if SINGLE_STEP events are also enabled for the thread, then
 * the METHOD_ENTRY event is deferred. When the SINGLE_STEP event
 * is processed, the event bag will also contain the deferred
 * METHOD_ENTRY event. This covers each of the combinations
 * marked with 'p1' above.
 *
 * Phase 2: if there is no existing co-located BREAKPOINT, then the
 * location information for the METHOD_ENTRY or SINGLE_STEP event
 * is recorded in the ThreadNode. If the next event for the thread
 * is a co-located BREAKPOINT, then the first BREAKPOINT event will
 * be skipped since it cannot be delivered in the same event set.
 * This covers each of the combinations marked with 'p2' above.
 *
 * For the combination marked p1/p2, part of the case is handled
 * during phase 1 and the rest is handled during phase 2.
 *
 * The recording of information in the ThreadNode is handled in
 * this routine. The special handling of the next event for the
 * thread is handled in skipEventReport().
 */

static jboolean
deferEventReport(JNIEnv *env, jthread thread,
            EventIndex ei, jclass clazz, jmethodID method, jlocation location)
{
    jboolean deferring = JNI_FALSE;

    switch (ei) {
        case EI_METHOD_ENTRY:
            if (!isMethodNative(method)) {
                jvmtiError error;
                jlocation start;
                jlocation end;
                error = methodLocation(method, &start, &end);
                if (error == JVMTI_ERROR_NONE) {
                    deferring = isBreakpointSet(clazz, method, start) ||
                                threadControl_getInstructionStepMode(thread)
                                    == JVMTI_ENABLE;
                    if (!deferring) {
                        threadControl_saveCLEInfo(env, thread, ei,
                                                  clazz, method, start);
                    }
                }
            }
            break;
        case EI_SINGLE_STEP:
            deferring = isBreakpointSet(clazz, method, location);
            if (!deferring) {
                threadControl_saveCLEInfo(env, thread, ei,
                                          clazz, method, location);
            }
            break;
        default:
            break;
    }
    /* TO DO: Once JVMTI supports a way to know if we're
     * at the end of a method, we should check here for
     * break and step events which precede a method exit
     * event.
     */
    return deferring;
}

/* Handle phase 2 of the co-located events policy. See detailed
 * comments in deferEventReport() above.
 */
static jboolean
skipEventReport(JNIEnv *env, jthread thread, EventIndex ei,
                        jclass clazz, jmethodID method, jlocation location)
{
    jboolean skipping = JNI_FALSE;

    if (ei == EI_BREAKPOINT) {
        if (threadControl_cmpCLEInfo(env, thread, clazz, method, location)) {
            LOG_MISC(("Co-located breakpoint event found: "
                "%s,thread=%p,clazz=%p,method=%p,location=%d",
                eventText(ei), thread, clazz, method, location));
            skipping = JNI_TRUE;
        }
    }

    threadControl_clearCLEInfo(env, thread);

    return skipping;
}

static void
reportEvents(JNIEnv *env, jbyte sessionID, jthread thread, EventIndex ei,
             jclass clazz, jmethodID method, jlocation location,
             struct bag *eventBag)
{
    jbyte suspendPolicy;
    jboolean invoking;

    if (bagSize(eventBag) < 1) {
        return;
    }

    /*
     * Never report events before initialization completes
     */
    if (!debugInit_isInitComplete()) {
        return;
    }

    /*
     * Check to see if we should skip reporting this event due to
     * co-location of events policy.
     */
    if (thread != NULL &&
           skipEventReport(env, thread, ei, clazz, method, location)) {
        LOG_MISC(("event report being skipped: "
            "ei=%s,thread=%p,clazz=%p,method=%p,location=%d",
            eventText(ei), thread, clazz, method, location));
        bagDeleteAll(eventBag);
        return;
    }

    /* We delay the reporting of some events so that they can be
     * properly grouped into event sets with upcoming events. If
     * the reporting is to be deferred, the event commands remain
     * in the event bag until a subsequent event occurs.  Event is
     * NULL for synthetic events (e.g. unload).
     */
    if (thread == NULL
         || !deferEventReport(env, thread, ei,
                        clazz, method, location)) {
        struct bag *completedBag = bagDup(eventBag);
        bagDeleteAll(eventBag);
        if (completedBag == NULL) {
            /*
             * TO DO: Report, but don't terminate?
             */
            return;
        } else {
            suspendPolicy = eventHelper_reportEvents(sessionID, completedBag);
            if (thread != NULL && suspendPolicy != JDWP_SUSPEND_POLICY(NONE)) {
                do {
                    /* The events have been reported and this
                     * thread is about to continue, but it may
                     * have been started up up just to perform a
                     * requested method invocation. If so, we do
                     * the invoke now and then stop again waiting
                     * for another continue. By then another
                     * invoke request can be in place, so there is
                     * a loop around this code.
                     */
                    invoking = invoker_doInvoke(thread);
                    if (invoking) {
                        eventHelper_reportInvokeDone(sessionID, thread);
                    }
                } while (invoking);
            }
            bagDestroyBag(completedBag);
        }
    }
}

/* A bagEnumerateFunction.  Create a synthetic class unload event
 * for every class no longer present.  Analogous to event_callback
 * combined with a handler in a unload specific (no event
 * structure) kind of way.
 */
static jboolean
synthesizeUnloadEvent(void *signatureVoid, void *envVoid)
{
    JNIEnv *env = (JNIEnv *)envVoid;
    char *signature = *(char **)signatureVoid;
    char *classname;
    HandlerNode *node;
    jbyte eventSessionID = currentSessionID;
    struct bag *eventBag = eventHelper_createEventBag();

    if (eventBag == NULL) {
        /* TO DO: Report, but don't die
         */
        JDI_ASSERT(eventBag != NULL);
    }

    /* Signature needs to last, so convert extra copy to
     * classname
     */
    classname = jvmtiAllocate((int)strlen(signature)+1);
    (void)strcpy(classname, signature);
    convertSignatureToClassname(classname);

    debugMonitorEnter(handlerLock);

    node = getHandlerChain(EI_GC_FINISH)->first;
    while (node != NULL) {
        /* save next so handlers can remove themselves */
        HandlerNode *next = NEXT(node);
        jboolean shouldDelete;

        if (eventFilterRestricted_passesUnloadFilter(env, classname,
                                                     node,
                                                     &shouldDelete)) {
            /* There may be multiple handlers, the signature will
             * be freed when the event helper thread has written
             * it.  So each event needs a separate allocation.
             */
            char *durableSignature = jvmtiAllocate((int)strlen(signature)+1);
            (void)strcpy(durableSignature, signature);

            eventHelper_recordClassUnload(node->handlerID,
                                          durableSignature,
                                          eventBag);
        }
        if (shouldDelete) {
            /* We can safely free the node now that we are done
             * using it.
             */
            (void)freeHandler(node);
        }
        node = next;
    }

    debugMonitorExit(handlerLock);

    if (eventBag != NULL) {
        reportEvents(env, eventSessionID, (jthread)NULL, 0,
                            (jclass)NULL, (jmethodID)NULL, 0, eventBag);

        /*
         * bag was created locally, destroy it here.
         */
        bagDestroyBag(eventBag);
    }

    jvmtiDeallocate(signature);
    jvmtiDeallocate(classname);

    return JNI_TRUE;
}

/* Garbage Collection Happened */
static unsigned int garbageCollected = 0;

/* The JVMTI generic event callback. Each event is passed to a sequence of
 * handlers in a chain until the chain ends or one handler
 * consumes the event.
 */
static void
event_callback(JNIEnv *env, EventInfo *evinfo)
{
    struct bag *eventBag;
    jbyte eventSessionID = currentSessionID; /* session could change */
    jthrowable currentException;
    jthread thread;

    LOG_MISC(("event_callback(): ei=%s", eventText(evinfo->ei)));
    log_debugee_location("event_callback()", evinfo->thread, evinfo->method, evinfo->location);

    /* We want to preserve any current exception that might get
     * wiped out during event handling (e.g. JNI calls). We have
     * to rely on space for the local reference on the current
     * frame because doing a PushLocalFrame here might itself
     * generate an exception.
     */
    currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
    JNI_FUNC_PTR(env,ExceptionClear)(env);

    /* See if a garbage collection finish event happened earlier.
     *
     * Note: The "if" is an optimization to avoid entering the lock on every
     *       event; garbageCollected may be zapped before we enter
     *       the lock but then this just becomes one big no-op.
     */
    if ( garbageCollected > 0 ) {
        struct bag *unloadedSignatures = NULL;

        /* We want to compact the hash table of all
         * objects sent to the front end by removing objects that have
         * been collected.
         */
        commonRef_compact();

        /* We also need to simulate the class unload events. */

        debugMonitorEnter(handlerLock);

        /* Clear garbage collection counter */
        garbageCollected = 0;

        /* Analyze which class unloads occurred */
        unloadedSignatures = classTrack_processUnloads(env);

        debugMonitorExit(handlerLock);

        /* Generate the synthetic class unload events and/or just cleanup.  */
        if ( unloadedSignatures != NULL ) {
            (void)bagEnumerateOver(unloadedSignatures, synthesizeUnloadEvent,
                             (void *)env);
            bagDestroyBag(unloadedSignatures);
        }
    }

    thread = evinfo->thread;
    if (thread != NULL) {
        /*
         * Record the fact that we're entering an event
         * handler so that thread operations (status, interrupt,
         * stop) can be done correctly and so that thread
         * resources can be allocated.  This must be done before
         * grabbing any locks.
         */
        eventBag = threadControl_onEventHandlerEntry(eventSessionID,
                                 evinfo->ei, thread, currentException);
        if ( eventBag == NULL ) {
            jboolean invoking;
            do {
                /* The event has been 'handled' and this
                 * thread is about to continue, but it may
                 * have been started up just to perform a
                 * requested method invocation. If so, we do
                 * the invoke now and then stop again waiting
                 * for another continue. By then another
                 * invoke request can be in place, so there is
                 * a loop around this code.
                 */
                invoking = invoker_doInvoke(thread);
                if (invoking) {
                    eventHelper_reportInvokeDone(eventSessionID, thread);
                }
            } while (invoking);
            return; /* Do nothing, event was consumed */
        }
    } else {
        eventBag = eventHelper_createEventBag();
        if (eventBag == NULL) {
            /*
             * TO DO: Report, but don't die
             */
            eventBag = NULL;  /* to shut up lint */
        }
    }

    debugMonitorEnter(handlerLock);
    {
        HandlerNode *node;
        char        *classname;

        /* We must keep track of all classes prepared to know what's unloaded */
        if (evinfo->ei == EI_CLASS_PREPARE) {
            classTrack_addPreparedClass(env, evinfo->clazz);
        }

        node = getHandlerChain(evinfo->ei)->first;
        classname = getClassname(evinfo->clazz);

        while (node != NULL) {
            /* save next so handlers can remove themselves */
            HandlerNode *next = NEXT(node);
            jboolean shouldDelete;

            if (eventFilterRestricted_passesFilter(env, classname,
                                                   evinfo, node,
                                                   &shouldDelete)) {
                HandlerFunction func;

                func = HANDLER_FUNCTION(node);
                if ( func == NULL ) {
                    EXIT_ERROR(AGENT_ERROR_INTERNAL,"handler function NULL");
                }
                (*func)(env, evinfo, node, eventBag);
            }
            if (shouldDelete) {
                /* We can safely free the node now that we are done
                 * using it.
                 */
                (void)freeHandler(node);
            }
            node = next;
        }
        jvmtiDeallocate(classname);
    }
    debugMonitorExit(handlerLock);

    if (eventBag != NULL) {
        reportEvents(env, eventSessionID, thread, evinfo->ei,
                evinfo->clazz, evinfo->method, evinfo->location, eventBag);
    }

    /* we are continuing after VMDeathEvent - now we are dead */
    if (evinfo->ei == EI_VM_DEATH) {
        gdata->vmDead = JNI_TRUE;
    }

    /*
     * If the bag was created locally, destroy it here.
     */
    if (thread == NULL) {
        bagDestroyBag(eventBag);
    }

    /* Always restore any exception that was set beforehand.  If
     * there is a pending async exception, StopThread will be
     * called from threadControl_onEventHandlerExit immediately
     * below.  Depending on VM implementation and state, the async
     * exception might immediately overwrite the currentException,
     * or it might be delayed until later.  */
    if (currentException != NULL) {
        JNI_FUNC_PTR(env,Throw)(env, currentException);
    } else {
        JNI_FUNC_PTR(env,ExceptionClear)(env);
    }

    /*
     * Release thread resources and perform any delayed operations.
     */
    if (thread != NULL) {
        threadControl_onEventHandlerExit(evinfo->ei, thread, eventBag);
    }
}

/* Returns a local ref to the declaring class for an object. */
static jclass
getObjectClass(jobject object)
{
    jclass clazz;
    JNIEnv *env = getEnv();

    clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);

    return clazz;
}

/* Returns a local ref to the declaring class for a method, or NULL. */
jclass
getMethodClass(jvmtiEnv *jvmti_env, jmethodID method)
{
    jclass clazz = NULL;
    jvmtiError error;

    if ( method == NULL ) {
        return NULL;
    }
    error = methodClass(method, &clazz);
    if ( error != JVMTI_ERROR_NONE ) {
        EXIT_ERROR(error,"Can't get jclass for a methodID, invalid?");
        return NULL;
    }
    return clazz;
}

/* Event callback for JVMTI_EVENT_SINGLE_STEP */
static void JNICALL
cbSingleStep(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jmethodID method, jlocation location)
{
    EventInfo info;

    LOG_CB(("cbSingleStep: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_SINGLE_STEP;
        info.thread     = thread;
        info.clazz      = getMethodClass(jvmti_env, method);
        info.method     = method;
        info.location   = location;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbSingleStep"));
}

/* Event callback for JVMTI_EVENT_BREAKPOINT */
static void JNICALL
cbBreakpoint(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jmethodID method, jlocation location)
{
    EventInfo info;

    LOG_CB(("cbBreakpoint: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_BREAKPOINT;
        info.thread     = thread;
        info.clazz      = getMethodClass(jvmti_env, method);
        info.method     = method;
        info.location   = location;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbBreakpoint"));
}

/* Event callback for JVMTI_EVENT_FRAME_POP */
static void JNICALL
cbFramePop(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jmethodID method,
                        jboolean wasPoppedByException)
{
    EventInfo info;

    /* JDWP does not return these events when popped due to an exception. */
    if ( wasPoppedByException ) {
        return;
    }

    LOG_CB(("cbFramePop: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_FRAME_POP;
        info.thread     = thread;
        info.clazz      = getMethodClass(jvmti_env, method);
        info.method     = method;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbFramePop"));
}

/* Event callback for JVMTI_EVENT_EXCEPTION */
static void JNICALL
cbException(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jmethodID method,
                        jlocation location, jobject exception,
                        jmethodID catch_method, jlocation catch_location)
{
    EventInfo info;

    LOG_CB(("cbException: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei                         = EI_EXCEPTION;
        info.thread                     = thread;
        info.clazz                      = getMethodClass(jvmti_env, method);
        info.method                     = method;
        info.location                   = location;
        info.object                     = exception;
        info.u.exception.catch_clazz    = getMethodClass(jvmti_env, catch_method);
        info.u.exception.catch_method   = catch_method;
        info.u.exception.catch_location = catch_location;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbException"));
}

/* Event callback for JVMTI_EVENT_THREAD_START */
static void JNICALL
cbThreadStart(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread)
{
    EventInfo info;

    LOG_CB(("cbThreadStart: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_THREAD_START;
        info.thread     = thread;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbThreadStart"));
}

/* Event callback for JVMTI_EVENT_THREAD_END */
static void JNICALL
cbThreadEnd(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread)
{
    EventInfo info;

    LOG_CB(("cbThreadEnd: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_THREAD_END;
        info.thread     = thread;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbThreadEnd"));
}

/* Event callback for JVMTI_EVENT_CLASS_PREPARE */
static void JNICALL
cbClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jclass klass)
{
    EventInfo info;

    LOG_CB(("cbClassPrepare: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_CLASS_PREPARE;
        info.thread     = thread;
        info.clazz      = klass;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbClassPrepare"));
}

/* Event callback for JVMTI_EVENT_GARBAGE_COLLECTION_FINISH */
static void JNICALL
cbGarbageCollectionFinish(jvmtiEnv *jvmti_env)
{
    LOG_CB(("cbGarbageCollectionFinish"));
    ++garbageCollected;
    LOG_MISC(("END cbGarbageCollectionFinish"));
}

/* Event callback for JVMTI_EVENT_CLASS_LOAD */
static void JNICALL
cbClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jclass klass)
{
    EventInfo info;

    LOG_CB(("cbClassLoad: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_CLASS_LOAD;
        info.thread     = thread;
        info.clazz      = klass;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbClassLoad"));
}

/* Event callback for JVMTI_EVENT_FIELD_ACCESS */
static void JNICALL
cbFieldAccess(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jmethodID method,
                        jlocation location, jclass field_klass,
                        jobject object, jfieldID field)
{
    EventInfo info;

    LOG_CB(("cbFieldAccess: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei                         = EI_FIELD_ACCESS;
        info.thread                     = thread;
        info.clazz                      = getMethodClass(jvmti_env, method);
        info.method                     = method;
        info.location                   = location;
        info.u.field_access.field_clazz = field_klass;
        info.object                     = object;
        info.u.field_access.field       = field;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbFieldAccess"));
}

/* Event callback for JVMTI_EVENT_FIELD_MODIFICATION */
static void JNICALL
cbFieldModification(jvmtiEnv *jvmti_env, JNIEnv *env,
        jthread thread, jmethodID method,
        jlocation location, jclass field_klass, jobject object, jfieldID field,
        char signature_type, jvalue new_value)
{
    EventInfo info;

    LOG_CB(("cbFieldModification: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei                                 = EI_FIELD_MODIFICATION;
        info.thread                             = thread;
        info.clazz                              = getMethodClass(jvmti_env, method);
        info.method                             = method;
        info.location                           = location;
        info.u.field_modification.field         = field;
        info.u.field_modification.field_clazz   = field_klass;
        info.object                             = object;
        info.u.field_modification.signature_type= signature_type;
        info.u.field_modification.new_value     = new_value;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbFieldModification"));
}

/* Event callback for JVMTI_EVENT_EXCEPTION_CATCH */
static void JNICALL
cbExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread,
        jmethodID method, jlocation location, jobject exception)
{
    EventInfo info;

    LOG_CB(("cbExceptionCatch: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_EXCEPTION_CATCH;
        info.thread     = thread;
        info.clazz      = getMethodClass(jvmti_env, method);
        info.method     = method;
        info.location   = location;
        info.object     = exception;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbExceptionCatch"));
}

/* Event callback for JVMTI_EVENT_METHOD_ENTRY */
static void JNICALL
cbMethodEntry(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jmethodID method)
{
    EventInfo info;

    LOG_CB(("cbMethodEntry: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_METHOD_ENTRY;
        info.thread     = thread;
        info.clazz      = getMethodClass(jvmti_env, method);
        info.method     = method;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbMethodEntry"));
}

/* Event callback for JVMTI_EVENT_METHOD_EXIT */
static void JNICALL
cbMethodExit(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jmethodID method,
                        jboolean wasPoppedByException, jvalue return_value)
{
    EventInfo info;

    /* JDWP does not return these events when popped due to an exception. */
    if ( wasPoppedByException ) {
        return;
    }

    LOG_CB(("cbMethodExit: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_METHOD_EXIT;
        info.thread     = thread;
        info.clazz      = getMethodClass(jvmti_env, method);
        info.method     = method;
        info.u.method_exit.return_value = return_value;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbMethodExit"));
}

/* Event callback for JVMTI_EVENT_MONITOR_CONTENDED_ENTER */
static void JNICALL
cbMonitorContendedEnter(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jobject object)
{
    EventInfo info;
    jvmtiError error;
    jmethodID  method;
    jlocation  location;

    LOG_CB(("cbMonitorContendedEnter: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_MONITOR_CONTENDED_ENTER;
        info.thread     = thread;
        info.object     = object;
        /* get current location of contended monitor enter */
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
                (gdata->jvmti, thread, 0, &method, &location);
        if (error == JVMTI_ERROR_NONE) {
            info.location = location;
            info.method   = method;
            info.clazz    = getMethodClass(jvmti_env, method);
        } else {
            info.location = -1;
        }
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbMonitorContendedEnter"));
}

/* Event callback for JVMTI_EVENT_MONITOR_CONTENDED_ENTERED */
static void JNICALL
cbMonitorContendedEntered(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jobject object)
{
    EventInfo info;
    jvmtiError error;
    jmethodID  method;
    jlocation  location;

    LOG_CB(("cbMonitorContendedEntered: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_MONITOR_CONTENDED_ENTERED;
        info.thread     = thread;
        info.object     = object;
        /* get current location of contended monitor enter */
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
                (gdata->jvmti, thread, 0, &method, &location);
        if (error == JVMTI_ERROR_NONE) {
            info.location = location;
            info.method   = method;
            info.clazz    = getMethodClass(jvmti_env, method);
        } else {
            info.location = -1;
        }
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbMonitorContendedEntered"));
}

/* Event callback for JVMTI_EVENT_MONITOR_WAIT */
static void JNICALL
cbMonitorWait(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jobject object,
                        jlong timeout)
{
    EventInfo info;
    jvmtiError error;
    jmethodID  method;
    jlocation  location;

    LOG_CB(("cbMonitorWait: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_MONITOR_WAIT;
        info.thread     = thread;
        info.object     = object;
        /* The info.clazz is used for both class filtering and for location info.
         * For monitor wait event the class filtering is done for class of monitor
         * object. So here info.clazz is set to class of monitor object here and it
         * is reset to class of method before writing location info.
         * See writeMonitorEvent in eventHelper.c
         */
        info.clazz      = getObjectClass(object);
        info.u.monitor.timeout = timeout;

        /* get location of monitor wait() method. */
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
                (gdata->jvmti, thread, 0, &method, &location);
        if (error == JVMTI_ERROR_NONE) {
            info.location = location;
            info.method   = method;
        } else {
            info.location = -1;
        }
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbMonitorWait"));
}

/* Event callback for JVMTI_EVENT_MONITOR_WAIT */
static void JNICALL
cbMonitorWaited(jvmtiEnv *jvmti_env, JNIEnv *env,
                        jthread thread, jobject object,
                        jboolean timed_out)
{
    EventInfo info;
    jvmtiError error;
    jmethodID  method;
    jlocation  location;

    LOG_CB(("cbMonitorWaited: thread=%p", thread));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_MONITOR_WAITED;
        info.thread     = thread;
        info.object     = object;
        /* The info.clazz is used for both class filtering and for location info.
         * For monitor waited event the class filtering is done for class of monitor
         * object. So here info.clazz is set to class of monitor object here and it
         * is reset to class of method before writing location info.
         * See writeMonitorEvent in eventHelper.c
         */
        info.clazz      = getObjectClass(object);
        info.u.monitor.timed_out = timed_out;

        /* get location of monitor wait() method */
        error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
                (gdata->jvmti, thread, 0, &method, &location);
        if (error == JVMTI_ERROR_NONE) {
            info.location = location;
            info.method   = method;
        } else {
            info.location = -1;
        }
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbMonitorWaited"));
}

/* Event callback for JVMTI_EVENT_VM_INIT */
static void JNICALL
cbVMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread)
{
    EventInfo info;

    LOG_CB(("cbVMInit"));

    BEGIN_CALLBACK() {
        (void)memset(&info,0,sizeof(info));
        info.ei         = EI_VM_INIT;
        info.thread     = thread;
        event_callback(env, &info);
    } END_CALLBACK();

    LOG_MISC(("END cbVMInit"));
}

/* Event callback for JVMTI_EVENT_VM_DEATH */
static void JNICALL
cbVMDeath(jvmtiEnv *jvmti_env, JNIEnv *env)
{
    jvmtiError error;
    EventInfo info;
    LOG_CB(("cbVMDeath"));

    /* Clear out ALL callbacks at this time, we don't want any more. */
    /*    This should prevent any new BEGIN_CALLBACK() calls. */
    (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks));
    error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
                (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks));
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"Can't clear event callbacks on vm death");
    }

    /* Now that no new callbacks will be made, we need to wait for the ones
     *   that are still active to complete.
     *   The BEGIN_CALLBACK/END_CALLBACK macros implement the VM_DEATH
     *   callback protocol. Once the callback table is cleared (above),
     *   we can have callback threads in different stages:
     *   1) after callback function entry and before BEGIN_CALLBACK
     *      macro; we catch these threads with callbackBlock in the
     *      BEGIN_CALLBACK macro
     *   2) after BEGIN_CALLBACK macro and before END_CALLBACK macro; we
     *      catch these threads with callbackBlock in the END_CALLBACK
     *      macro
     *   3) after END_CALLBACK macro; these threads have made it past
     *      callbackBlock and callbackLock and don't count as active
     *
     *   Since some of the callback threads could be blocked or suspended
     *   we will resume all threads suspended by the debugger for a short
     *   time to flush out all callbacks. Note that the callback threads
     *   will block from returning to the VM in both macros. Some threads
     *   not associated with callbacks, but suspended by the debugger may
     *   continue on, but not for long.
     *   Once the last callback finishes, it will notify this thread and
     *   we fall out of the loop below and actually process the VM_DEATH
     *   event.
     */
    debugMonitorEnter(callbackBlock); {
        debugMonitorEnter(callbackLock); {
            vm_death_callback_active = JNI_TRUE;
            (void)threadControl_resumeAll();
            while (active_callbacks > 0) {
                /* wait for active CALLBACKs to check in (and block) */
                debugMonitorWait(callbackLock);
            }
        } debugMonitorExit(callbackLock);

        /* Only now should we actually process the VM death event */
        (void)memset(&info,0,sizeof(info));
        info.ei                 = EI_VM_DEATH;
        event_callback(env, &info);

        /* Here we unblock all the callbacks and let them return to the
         *   VM.  It's not clear this is necessary, but leaving threads
         *   blocked doesn't seem like a good idea. They don't have much
         *   life left anyway.
         */
    } debugMonitorExit(callbackBlock);

    /*
     * The VM will die soon after the completion of this callback - we
     * may need to do a final synchronization with the command loop to
     * avoid the VM terminating with replying to the final (resume)
     * command.
     */
    debugLoop_sync();

    LOG_MISC(("END cbVMDeath"));
}

/**
 * Delete this handler (do not delete permanent handlers):
 * Deinsert handler from active list,
 * make it inactive, and free it's memory
 * Assumes handlerLock held.
 */
static jvmtiError
freeHandler(HandlerNode *node) {
    jvmtiError error = JVMTI_ERROR_NONE;

    /* deinsert the handler node before disableEvents() to make
     * sure the event will be disabled when no other event
     * handlers are installed.
     */
    if (node != NULL && (!node->permanent)) {
        deinsert(node);
        error = eventFilterRestricted_deinstall(node);
        jvmtiDeallocate(node);
    }

    return error;
}

/**
 * Delete all the handlers on this chain (do not delete permanent handlers).
 * Assumes handlerLock held.
 */
static jvmtiError
freeHandlerChain(HandlerChain *chain)
{
    HandlerNode *node;
    jvmtiError   error;

    error = JVMTI_ERROR_NONE;
    node  = chain->first;
    while ( node != NULL ) {
        HandlerNode *next;
        jvmtiError   singleError;

        next = NEXT(node);
        singleError = freeHandler(node);
        if ( singleError != JVMTI_ERROR_NONE ) {
            error = singleError;
        }
        node = next;
    }
    return error;
}

/**
 * Deinsert and free all memory.  Safe for non-inserted nodes.
 */
jvmtiError
eventHandler_free(HandlerNode *node)
{
    jvmtiError error;

    debugMonitorEnter(handlerLock);

    error = freeHandler(node);

    debugMonitorExit(handlerLock);

    return error;
}

/**
 * Free all handlers of this kind created by the JDWP client,
 * that is, doesn't free handlers internally created by back-end.
 */
jvmtiError
eventHandler_freeAll(EventIndex ei)
{
    jvmtiError error = JVMTI_ERROR_NONE;
    HandlerNode *node;

    debugMonitorEnter(handlerLock);
    node = getHandlerChain(ei)->first;
    while (node != NULL) {
        HandlerNode *next = NEXT(node);    /* allows node removal */
        if (node->handlerID != 0) {        /* don't free internal handlers */
            error = freeHandler(node);
            if (error != JVMTI_ERROR_NONE) {
                break;
            }
        }
        node = next;
    }
    debugMonitorExit(handlerLock);
    return error;
}

/***
 * Delete all breakpoints on "clazz".
 */
void
eventHandler_freeClassBreakpoints(jclass clazz)
{
    HandlerNode *node;
    JNIEnv *env = getEnv();

    debugMonitorEnter(handlerLock);
    node = getHandlerChain(EI_BREAKPOINT)->first;
    while (node != NULL) {
        HandlerNode *next = NEXT(node); /* allows node removal */
        if (eventFilterRestricted_isBreakpointInClass(env, clazz,
                                                      node)) {
            (void)freeHandler(node);
        }
        node = next;
    }
    debugMonitorExit(handlerLock);
}

jvmtiError
eventHandler_freeByID(EventIndex ei, HandlerID handlerID)
{
    jvmtiError error;
    HandlerNode *node;

    debugMonitorEnter(handlerLock);
    node = find(ei, handlerID);
    if (node != NULL) {
        error = freeHandler(node);
    } else {
        /* already freed */
        error = JVMTI_ERROR_NONE;
    }
    debugMonitorExit(handlerLock);
    return error;
}

void
eventHandler_initialize(jbyte sessionID)
{
    jvmtiError error;
    jint i;

    requestIdCounter = 1;
    currentSessionID = sessionID;

    /* This is for BEGIN_CALLBACK/END_CALLBACK handling, make sure this
     *   is done while none of these callbacks are active.
     */
    active_callbacks = 0;
    vm_death_callback_active = JNI_FALSE;
    callbackLock = debugMonitorCreate("JDWP Callback Lock");
    callbackBlock = debugMonitorCreate("JDWP Callback Block");

    handlerLock = debugMonitorCreate("JDWP Event Handler Lock");

    for (i = EI_min; i <= EI_max; ++i) {
        getHandlerChain(i)->first = NULL;
    }

    /*
     * Permanently enabled some events.
     */
    error = threadControl_setEventMode(JVMTI_ENABLE,
                                      EI_VM_INIT, NULL);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"Can't enable vm init events");
    }
    error = threadControl_setEventMode(JVMTI_ENABLE,
                                      EI_VM_DEATH, NULL);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"Can't enable vm death events");
    }
    error = threadControl_setEventMode(JVMTI_ENABLE,
                                      EI_THREAD_START, NULL);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"Can't enable thread start events");
    }
    error = threadControl_setEventMode(JVMTI_ENABLE,
                                       EI_THREAD_END, NULL);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"Can't enable thread end events");
    }
    error = threadControl_setEventMode(JVMTI_ENABLE,
                                       EI_CLASS_PREPARE, NULL);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"Can't enable class prepare events");
    }
    error = threadControl_setEventMode(JVMTI_ENABLE,
                                       EI_GC_FINISH, NULL);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"Can't enable garbage collection finish events");
    }

    (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks));
    /* Event callback for JVMTI_EVENT_SINGLE_STEP */
    gdata->callbacks.SingleStep                 = &cbSingleStep;
    /* Event callback for JVMTI_EVENT_BREAKPOINT */
    gdata->callbacks.Breakpoint                 = &cbBreakpoint;
    /* Event callback for JVMTI_EVENT_FRAME_POP */
    gdata->callbacks.FramePop                   = &cbFramePop;
    /* Event callback for JVMTI_EVENT_EXCEPTION */
    gdata->callbacks.Exception                  = &cbException;
    /* Event callback for JVMTI_EVENT_THREAD_START */
    gdata->callbacks.ThreadStart                = &cbThreadStart;
    /* Event callback for JVMTI_EVENT_THREAD_END */
    gdata->callbacks.ThreadEnd                  = &cbThreadEnd;
    /* Event callback for JVMTI_EVENT_CLASS_PREPARE */
    gdata->callbacks.ClassPrepare               = &cbClassPrepare;
    /* Event callback for JVMTI_EVENT_CLASS_LOAD */
    gdata->callbacks.ClassLoad                  = &cbClassLoad;
    /* Event callback for JVMTI_EVENT_FIELD_ACCESS */
    gdata->callbacks.FieldAccess                = &cbFieldAccess;
    /* Event callback for JVMTI_EVENT_FIELD_MODIFICATION */
    gdata->callbacks.FieldModification          = &cbFieldModification;
    /* Event callback for JVMTI_EVENT_EXCEPTION_CATCH */
    gdata->callbacks.ExceptionCatch             = &cbExceptionCatch;
    /* Event callback for JVMTI_EVENT_METHOD_ENTRY */
    gdata->callbacks.MethodEntry                = &cbMethodEntry;
    /* Event callback for JVMTI_EVENT_METHOD_EXIT */
    gdata->callbacks.MethodExit                 = &cbMethodExit;
    /* Event callback for JVMTI_EVENT_MONITOR_CONTENDED_ENTER */
    gdata->callbacks.MonitorContendedEnter      = &cbMonitorContendedEnter;
    /* Event callback for JVMTI_EVENT_MONITOR_CONTENDED_ENTERED */
    gdata->callbacks.MonitorContendedEntered    = &cbMonitorContendedEntered;
    /* Event callback for JVMTI_EVENT_MONITOR_WAIT */
    gdata->callbacks.MonitorWait                = &cbMonitorWait;
    /* Event callback for JVMTI_EVENT_MONITOR_WAITED */
    gdata->callbacks.MonitorWaited              = &cbMonitorWaited;
    /* Event callback for JVMTI_EVENT_VM_INIT */
    gdata->callbacks.VMInit                     = &cbVMInit;
    /* Event callback for JVMTI_EVENT_VM_DEATH */
    gdata->callbacks.VMDeath                    = &cbVMDeath;
    /* Event callback for JVMTI_EVENT_GARBAGE_COLLECTION_FINISH */
    gdata->callbacks.GarbageCollectionFinish    = &cbGarbageCollectionFinish;

    error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
                (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks));
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"Can't set event callbacks");
    }

    /* Notify other modules that the event callbacks are in place */
    threadControl_onHook();

    /* Get the event helper thread initialized */
    eventHelper_initialize(sessionID);
}

void
eventHandler_reset(jbyte sessionID)
{
    int i;

    debugMonitorEnter(handlerLock);

    /* We must do this first so that if any invokes complete,
     * there will be no attempt to send them to the front
     * end. Waiting for threadControl_reset leaves a window where
     * the invoke completions can sneak through.
     */
    threadControl_detachInvokes();

    /* Reset the event helper thread, purging all queued and
     * in-process commands.
     */
    eventHelper_reset(sessionID);

    /* delete all handlers */
    for (i = EI_min; i <= EI_max; i++) {
        (void)freeHandlerChain(getHandlerChain(i));
    }

    requestIdCounter = 1;
    currentSessionID = sessionID;

    debugMonitorExit(handlerLock);
}

void
eventHandler_lock(void)
{
    debugMonitorEnter(handlerLock);
}

void
eventHandler_unlock(void)
{
    debugMonitorExit(handlerLock);
}

/***** handler creation *****/

HandlerNode *
eventHandler_alloc(jint filterCount, EventIndex ei, jbyte suspendPolicy)
{
    HandlerNode *node = eventFilterRestricted_alloc(filterCount);

    if (node != NULL) {
        node->ei = ei;
        node->suspendPolicy = suspendPolicy;
        node->permanent = JNI_FALSE;
    }

    return node;
}


HandlerID
eventHandler_allocHandlerID(void)
{
    jint handlerID;
    debugMonitorEnter(handlerLock);
    handlerID = ++requestIdCounter;
    debugMonitorExit(handlerLock);
    return handlerID;
}


static jvmtiError
installHandler(HandlerNode *node,
              HandlerFunction func,
              jboolean external)
{
    jvmtiError error;

    if ( func == NULL ) {
        return AGENT_ERROR_INVALID_EVENT_TYPE;
    }

    debugMonitorEnter(handlerLock);

    HANDLER_FUNCTION(node) = func;

    node->handlerID = external? ++requestIdCounter : 0;
    error = eventFilterRestricted_install(node);
    if (error == JVMTI_ERROR_NONE) {
        insert(getHandlerChain(node->ei), node);
    }

    debugMonitorExit(handlerLock);

    return error;
}

static HandlerNode *
createInternal(EventIndex ei, HandlerFunction func,
               jthread thread, jclass clazz, jmethodID method,
               jlocation location, jboolean permanent)
{
    jint index = 0;
    jvmtiError error = JVMTI_ERROR_NONE;
    HandlerNode *node;

    /*
     * Start with necessary allocations
     */
    node = eventHandler_alloc(
        ((thread == NULL)? 0 : 1) + ((clazz == NULL)? 0 : 1),
        ei, JDWP_SUSPEND_POLICY(NONE));
    if (node == NULL) {
        return NULL;
    }

    node->permanent = permanent;

    if (thread != NULL) {
        error = eventFilter_setThreadOnlyFilter(node, index++, thread);
    }

    if ((error == JVMTI_ERROR_NONE) && (clazz != NULL)) {
        error = eventFilter_setLocationOnlyFilter(node, index++, clazz,
                                                  method, location);
    }
    /*
     * Create the new handler node
     */
    error = installHandler(node, func, JNI_FALSE);

    if (error != JVMTI_ERROR_NONE) {
        (void)eventHandler_free(node);
        node = NULL;
    }
    return node;
}

HandlerNode *
eventHandler_createPermanentInternal(EventIndex ei, HandlerFunction func)
{
    return createInternal(ei, func, NULL,
                          NULL, NULL, (jlocation)NULL, JNI_TRUE);
}

HandlerNode *
eventHandler_createInternalThreadOnly(EventIndex ei,
                                      HandlerFunction func,
                                      jthread thread)
{
    return createInternal(ei, func, thread,
                          NULL, NULL, (jlocation)NULL, JNI_FALSE);
}

HandlerNode *
eventHandler_createInternalBreakpoint(HandlerFunction func,
                                      jthread thread,
                                      jclass clazz,
                                      jmethodID method,
                                      jlocation location)
{
    return createInternal(EI_BREAKPOINT, func, thread,
                          clazz, method, location, JNI_FALSE);
}

jvmtiError
eventHandler_installExternal(HandlerNode *node)
{
    return installHandler(node,
                          standardHandlers_defaultHandler(node->ei),
                          JNI_TRUE);
}
