void RequestManager::ControlEvent()

in modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp [256:361]


void RequestManager::ControlEvent(JNIEnv* jni,
        AgentEventRequest* request, bool enable)
    throw(AgentException)
{
    JDWP_TRACE_ENTRY("ControlEvent(" << jni << ',' << request << ',' << enable << ")");

    jvmtiEvent eventType;
    bool nullThreadForSetEventNotificationMode = false;
    switch (request->GetEventKind()) {
    case JDWP_EVENT_SINGLE_STEP:
        // manually controlled inside StepRequest
        //eventType = JVMTI_EVENT_SINGLE_STEP;
        //break;
        return;
    case JDWP_EVENT_BREAKPOINT:
        eventType = JVMTI_EVENT_BREAKPOINT;
        ControlBreakpoint(jni, request, enable);
        break;
    case JDWP_EVENT_FRAME_POP:
        eventType = JVMTI_EVENT_FRAME_POP;
        break;
    case JDWP_EVENT_EXCEPTION:
        eventType = JVMTI_EVENT_EXCEPTION;
        break;
    case JDWP_EVENT_CLASS_PREPARE:
        eventType = JVMTI_EVENT_CLASS_PREPARE;
        break;
    case JDWP_EVENT_CLASS_LOAD:
        eventType = JVMTI_EVENT_CLASS_LOAD;
        break;
    case JDWP_EVENT_CLASS_UNLOAD:
        eventType = static_cast<jvmtiEvent>(
            ControlClassUnload(jni, request, enable));
        // avoid standard event enable/disable technique
        return;
    case JDWP_EVENT_FIELD_ACCESS:
        eventType = JVMTI_EVENT_FIELD_ACCESS;
        ControlWatchpoint(jni, request, enable);
        break;
    case JDWP_EVENT_FIELD_MODIFICATION:
        eventType = JVMTI_EVENT_FIELD_MODIFICATION;
        ControlWatchpoint(jni, request, enable);
        break;
    case JDWP_EVENT_EXCEPTION_CATCH:
        eventType = JVMTI_EVENT_EXCEPTION_CATCH;
        break;
    case JDWP_EVENT_METHOD_ENTRY:
        eventType = JVMTI_EVENT_METHOD_ENTRY;
        break;
    case JDWP_EVENT_METHOD_EXIT:
        eventType = JVMTI_EVENT_METHOD_EXIT;
        break;
    case JDWP_EVENT_THREAD_START:
        eventType = JVMTI_EVENT_THREAD_START;
        nullThreadForSetEventNotificationMode = true;
        break;
    case JDWP_EVENT_THREAD_END:
        eventType = JVMTI_EVENT_THREAD_END;
        nullThreadForSetEventNotificationMode = true;
        break;
    default:
        return;
    }

    jthread thread = request->GetThread();
    RequestList& rl = GetRequestList(request->GetEventKind());
    for (RequestListIterator i = rl.begin(); i != rl.end(); i++) {
        if (nullThreadForSetEventNotificationMode) {
            //
            // SetEventNotificationMode() for some events must be called with
            // jthread = 0, even if we need request only for specified thread.
            // Thus, if there is already any request for such events 
            // it is for all threads and SetEventNotificationMode() should not 
            // be called. 
            //
            return;
        }
        AgentEventRequest* req = *i;
        if (JNI_TRUE == jni->IsSameObject(thread, req->GetThread())) {
            // there is similar request, so do nothing
            return;
        }
    }

    JDWP_TRACE_EVENT("ControlEvent: request " << GetEventKindName(request->GetEventKind())
        << "[" << request->GetEventKind() << "] "
        << (enable ? "on" : "off") << ", thread=" << thread);
    jvmtiError err;
    if (nullThreadForSetEventNotificationMode) {
        //
        // SetEventNotificationMode() for some events must be called with
        // jthread = 0, even if we need request only for specified thread.
        // Thus, if request is for such event, SetEventNotificationMode() 
        // should be called with jthread = 0 and generated events will be
        // filtered later 
        //
        thread = 0;
    }
    JVMTI_TRACE(err, GetJvmtiEnv()->SetEventNotificationMode(
        (enable) ? JVMTI_ENABLE : JVMTI_DISABLE, eventType, thread));
    if (err != JVMTI_ERROR_NONE &&
        (err != JVMTI_ERROR_THREAD_NOT_ALIVE || enable))
    {
        throw AgentException(err);
    }
}