[Lldb-commits] [lldb] r236702 - Remove quit hook in CMIDriver::DoMainLoop (MI)
Ilia K
ki.stfu at gmail.com
Wed May 6 23:45:42 PDT 2015
Author: ki.stfu
Date: Thu May 7 01:45:42 2015
New Revision: 236702
URL: http://llvm.org/viewvc/llvm-project?rev=236702&view=rev
Log:
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
Modified:
lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp
lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h
lldb/trunk/tools/lldb-mi/MIDriver.cpp
Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp?rev=236702&r1=236701&r2=236702&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.cpp Thu May 7 01:45:42 2015
@@ -222,6 +222,28 @@ CMICmnLLDBDebugger::GetDriver(void) cons
}
//++ ------------------------------------------------------------------------------------
+// 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.
// Args: None.
@@ -642,39 +664,48 @@ CMICmnLLDBDebugger::MonitorSBListenerEve
{
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;
+ return MIstatus::success;
}
//++ ------------------------------------------------------------------------------------
Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h?rev=236702&r1=236701&r2=236702&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBDebugger.h Thu May 7 01:45:42 2015
@@ -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 CMICmn
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 CMICmn
const CMIUtilString m_constStrThisThreadId;
MapBroadcastClassNameToEventMask_t m_mapBroadcastClassNameToEventMask;
MapIdToEventMask_t m_mapIdToEventMask;
+ std::mutex m_mutexEventQueue;
+ std::condition_variable m_conditionEventQueueEmpty;
};
Modified: lldb/trunk/tools/lldb-mi/MIDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriver.cpp?rev=236702&r1=236701&r2=236702&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriver.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIDriver.cpp Thu May 7 01:45:42 2015
@@ -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();
}
}
}
More information about the lldb-commits
mailing list