[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