forked from OSchip/llvm-project
Remove quit hook in CMIDriver::DoMainLoop (MI)
Summary: This patch removes quit hook and fixes 1 bug: # Fix "quit" hook in CMIDriver::DoMainLoop (MI) # Fix bug when the handler thread exits without any notification (MI) # Fix a race condition in CMICmnLLDBDebugger::MonitorSBListenerEvents (MI) Test Plan: ./dotest.py -v --executable $BUILDDIR/bin/lldb tools/lldb-mi/ Reviewers: abidh Reviewed By: abidh Subscribers: lldb-commits, abidh Differential Revision: http://reviews.llvm.org/D9275 llvm-svn: 236702
This commit is contained in:
parent
43f7439cf5
commit
8913012ee9
|
@ -221,6 +221,28 @@ CMICmnLLDBDebugger::GetDriver(void) const
|
|||
return *m_pClientDriver;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Wait until all events have been handled.
|
||||
// This function works in pair with CMICmnLLDBDebugger::MonitorSBListenerEvents
|
||||
// that handles events from queue. When all events were handled and queue is
|
||||
// empty the MonitorSBListenerEvents notifies this function that it's ready to
|
||||
// go on. To synchronize them the m_mutexEventQueue and
|
||||
// m_conditionEventQueueEmpty are used.
|
||||
// Type: Method.
|
||||
// Args: None.
|
||||
// Return: None.
|
||||
// Throws: None.
|
||||
//--
|
||||
void
|
||||
CMICmnLLDBDebugger::WaitForHandleEvent(void)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutexEventQueue);
|
||||
|
||||
lldb::SBEvent event;
|
||||
if (ThreadIsActive() && m_lldbListener.PeekAtNextEvent(event))
|
||||
m_conditionEventQueueEmpty.wait(lock);
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
// Details: Initialize the LLDB Debugger object.
|
||||
// Type: Method.
|
||||
|
@ -642,39 +664,48 @@ CMICmnLLDBDebugger::MonitorSBListenerEvents(bool &vrbIsAlive)
|
|||
{
|
||||
vrbIsAlive = true;
|
||||
|
||||
// Lock the mutex of event queue
|
||||
// Note that it should be locked while we are in CMICmnLLDBDebugger::MonitorSBListenerEvents to
|
||||
// avoid a race condition with CMICmnLLDBDebugger::WaitForHandleEvent
|
||||
std::unique_lock<std::mutex> lock(m_mutexEventQueue);
|
||||
|
||||
lldb::SBEvent event;
|
||||
const bool bGotEvent = m_lldbListener.GetNextEvent(event);
|
||||
if (!bGotEvent || !event.IsValid())
|
||||
if (!bGotEvent)
|
||||
{
|
||||
// Notify that we are finished and unlock the mutex of event queue before sleeping
|
||||
m_conditionEventQueueEmpty.notify_one();
|
||||
lock.unlock();
|
||||
|
||||
// Wait a bit to reduce CPU load
|
||||
const std::chrono::milliseconds time(1);
|
||||
std::this_thread::sleep_for(time);
|
||||
return MIstatus::success;
|
||||
}
|
||||
if (!event.GetBroadcaster().IsValid())
|
||||
return MIstatus::success;
|
||||
assert(event.IsValid());
|
||||
assert(event.GetBroadcaster().IsValid());
|
||||
|
||||
// Debugging
|
||||
m_pLog->WriteLog(CMIUtilString::Format("##### An event occurred: %s", event.GetBroadcasterClass()));
|
||||
|
||||
bool bHandledEvent = false;
|
||||
|
||||
bool bOk = false;
|
||||
{
|
||||
// Lock Mutex before handling events so that we don't disturb a running cmd
|
||||
CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
|
||||
bOk = CMICmnLLDBDebuggerHandleEvents::Instance().HandleEvent(event, bHandledEvent);
|
||||
}
|
||||
|
||||
if (!bHandledEvent)
|
||||
{
|
||||
const CMIUtilString msg(CMIUtilString::Format(MIRSRC(IDS_LLDBDEBUGGER_WRN_UNKNOWN_EVENT), event.GetBroadcasterClass()));
|
||||
m_pLog->WriteLog(msg);
|
||||
}
|
||||
if (!bOk)
|
||||
{
|
||||
m_pLog->WriteLog(CMICmnLLDBDebuggerHandleEvents::Instance().GetErrorDescription());
|
||||
}
|
||||
|
||||
return bOk;
|
||||
if (!bOk)
|
||||
m_pLog->WriteLog(CMICmnLLDBDebuggerHandleEvents::Instance().GetErrorDescription());
|
||||
|
||||
return MIstatus::success;
|
||||
}
|
||||
|
||||
//++ ------------------------------------------------------------------------------------
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
#pragma once
|
||||
|
||||
// Third party headers
|
||||
#include <queue>
|
||||
#include <condition_variable>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBListener.h"
|
||||
#include "lldb/API/SBEvent.h"
|
||||
|
@ -48,6 +49,7 @@ class CMICmnLLDBDebugger : public CMICmnBase, public CMIUtilThreadActiveObjBase,
|
|||
CMIDriverBase &GetDriver(void) const;
|
||||
lldb::SBDebugger &GetTheDebugger(void);
|
||||
lldb::SBListener &GetTheListener(void);
|
||||
void WaitForHandleEvent(void);
|
||||
|
||||
// MI Commands can use these functions to listen for events they require
|
||||
bool RegisterForEvent(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, const MIuint vEventMask);
|
||||
|
@ -106,4 +108,6 @@ class CMICmnLLDBDebugger : public CMICmnBase, public CMIUtilThreadActiveObjBase,
|
|||
const CMIUtilString m_constStrThisThreadId;
|
||||
MapBroadcastClassNameToEventMask_t m_mapBroadcastClassNameToEventMask;
|
||||
MapIdToEventMask_t m_mapIdToEventMask;
|
||||
std::mutex m_mutexEventQueue;
|
||||
std::condition_variable m_conditionEventQueueEmpty;
|
||||
};
|
||||
|
|
|
@ -536,12 +536,8 @@ CMIDriver::DoMainLoop(void)
|
|||
CMIUtilString lineText(pCmd);
|
||||
if (!lineText.empty ())
|
||||
{
|
||||
if (lineText == "quit")
|
||||
{
|
||||
// We want to be exiting when receiving a quit command
|
||||
m_bExitApp = true;
|
||||
break;
|
||||
}
|
||||
// Check that the handler thread is alive (otherwise we stuck here)
|
||||
assert(CMICmnLLDBDebugger::Instance().ThreadIsActive());
|
||||
|
||||
{
|
||||
// Lock Mutex before processing commands so that we don't disturb an event
|
||||
|
@ -549,9 +545,13 @@ CMIDriver::DoMainLoop(void)
|
|||
CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
|
||||
bOk = InterpretCommand(lineText);
|
||||
}
|
||||
|
||||
// Draw prompt if desired
|
||||
if (bOk && m_rStdin.GetEnablePrompt())
|
||||
bOk = m_rStdOut.WriteMIResponse(m_rStdin.GetPrompt());
|
||||
|
||||
// Wait while the handler thread handles incoming events
|
||||
CMICmnLLDBDebugger::Instance().WaitForHandleEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue