void Driver::ProcessEvent(SBEvent& event) { if (!event.GetBroadcaster().IsValid()) return; uint32_t event_type = event.GetType(); if (event.BroadcasterMatchesRef (*m_io_channel_ap)) { if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) || (event_type & IOChannel::eBroadcastBitThreadDidExit)) { SetIsDone(); if (event_type & IOChannel::eBroadcastBitThreadDidExit) iochannel_thread_exited = true; } else { if (HandleIOEvent (event)) SetIsDone(); } } else if (SBProcess::EventIsProcessEvent (event)) { HandleProcessEvent (event); } else if (SBBreakpoint::EventIsBreakpointEvent (event)) { HandleBreakpointEvent (event); } else if (event.BroadcasterMatchesRef (m_interpreter->GetBroadcaster())) { // TODO: deprecate the eBroadcastBitQuitCommandReceived event // now that we have SBCommandInterpreter::SetCommandOverrideCallback() // that can take over a command if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived) { SetIsDone(); } else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData) { const char *data = SBEvent::GetCStringFromEvent (event); m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC); } else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData) { const char *data = SBEvent::GetCStringFromEvent (event); m_io_channel_ap->OutWrite (data, strlen(data), ASYNC); } } }
void IOChannel::Run () { SBListener listener("IOChannel::Run"); std::string new_line; SBBroadcaster interpreter_broadcaster (m_driver->GetDebugger().GetCommandInterpreter().GetBroadcaster()); listener.StartListeningForEvents (interpreter_broadcaster, SBCommandInterpreter::eBroadcastBitResetPrompt | SBCommandInterpreter::eBroadcastBitThreadShouldExit | SBCommandInterpreter::eBroadcastBitQuitCommandReceived); listener.StartListeningForEvents (*this, IOChannel::eBroadcastBitThreadShouldExit); listener.StartListeningForEvents (*m_driver, Driver::eBroadcastBitReadyForInput | Driver::eBroadcastBitThreadShouldExit); // Let anyone know that the IO channel is up and listening and ready for events BroadcastEventByType (eBroadcastBitThreadDidStart); bool done = false; while (!done) { SBEvent event; listener.WaitForEvent (UINT32_MAX, event); if (!event.IsValid()) continue; const uint32_t event_type = event.GetType(); if (event.GetBroadcaster().IsValid()) { if (event.BroadcasterMatchesPtr (m_driver)) { if (event_type & Driver::eBroadcastBitReadyForInput) { std::string line; if (CommandQueueIsEmpty()) { if (LibeditGetInput(line) == false) { // EOF or some other file error occurred done = true; continue; } } else { GetCommandFromQueue (line); } // TO BE DONE: FIGURE OUT WHICH COMMANDS SHOULD NOT BE REPEATED IF USER PRESSES PLAIN 'RETURN' // AND TAKE CARE OF THAT HERE. SBEvent line_event(IOChannel::eBroadcastBitHasUserInput, line.c_str(), line.size()); BroadcastEvent (line_event); } else if (event_type & Driver::eBroadcastBitThreadShouldExit) { done = true; break; } } else if (event.BroadcasterMatchesRef (interpreter_broadcaster)) { switch (event_type) { case SBCommandInterpreter::eBroadcastBitResetPrompt: { const char *new_prompt = SBEvent::GetCStringFromEvent (event); if (new_prompt) g_prompt_map[m_edit_line] = new_prompt; } break; case SBCommandInterpreter::eBroadcastBitThreadShouldExit: case SBCommandInterpreter::eBroadcastBitQuitCommandReceived: done = true; break; } } else if (event.BroadcasterMatchesPtr (this)) { if (event_type & IOChannel::eBroadcastBitThreadShouldExit) { done = true; break; } } } } BroadcastEventByType (IOChannel::eBroadcastBitThreadDidExit); m_driver = NULL; m_read_thread = NULL; }