eventhelper.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,130 行 · 第 1/3 页

C
1,130
字号
    (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 voidsuspendWithInvokeEnabled(jbyte policy, jthread thread){    invoker_enableInvokeRequests(thread);    if (policy == JDWP_SUSPEND_POLICY(ALL)) {        (void)threadControl_suspendAll();    } else {        (void)threadControl_suspendThread(thread, JNI_FALSE);    }}static voidhandleReportEventCompositeCommand(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 voidhandleReportInvokeDoneCommand(JNIEnv* env, ReportInvokeDoneCommand *command) {    invoker_completeInvokeRequest(command->thread);    tossGlobalRef(env, &(command->thread));}static voidhandleReportVMInitCommand(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 voidhandleSuspendThreadCommand(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 voidhandleCommand(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 voiddoBlockCommandLoop(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 jbooleanneedBlockCommandLoop(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(). */voidunblockCommandLoop(void) {    debugMonitorEnter(blockCommandLoopLock);    blockCommandLoop = JNI_FALSE;    debugMonitorNotifyAll(blockCommandLoopLock);    debugMonitorExit(blockCommandLoopLock);}/* * The event helper thread. Dequeues commands and processes them. */static void JNICALLcommandLoop(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();            }        } else {          JDI_ASSERT(shutdownEvents);          break;        }    }    /* 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;    shutdownEvents = 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);}voideventHelper_shutdown(void){    debugMonitorEnter(commandQueueLock);    holdEvents = JNI_FALSE;    shutdownEvents = JNI_TRUE;    debugMonitorNotifyAll(commandQueueLock);    debugMonitorExit(commandQueueLock);}/* * Provide a means for threadControl to ensure that crucial locks are not  * held by suspended threads. */void eventHelper_lock(void){

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?