This revision was automatically updated to reflect the committed changes.
Closed by commit rG5b04eb23ae1a: [lldb] [MainLoop] Support "pending 
callbacks", to be called once (authored by mgorny).
Herald added a project: LLDB.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128253/new/

https://reviews.llvm.org/D128253

Files:
  lldb/include/lldb/Host/MainLoop.h
  lldb/include/lldb/Host/MainLoopBase.h
  lldb/source/Host/common/MainLoop.cpp
  lldb/unittests/Host/MainLoopTest.cpp

Index: lldb/unittests/Host/MainLoopTest.cpp
===================================================================
--- lldb/unittests/Host/MainLoopTest.cpp
+++ lldb/unittests/Host/MainLoopTest.cpp
@@ -98,6 +98,56 @@
   ASSERT_EQ(1u, callback_count);
 }
 
+TEST_F(MainLoopTest, PendingCallback) {
+  char X = 'X';
+  size_t len = sizeof(X);
+  ASSERT_TRUE(socketpair[0]->Write(&X, len).Success());
+
+  MainLoop loop;
+  Status error;
+  auto handle = loop.RegisterReadObject(
+      socketpair[1],
+      [&](MainLoopBase &loop) {
+        // Both callbacks should be called before the loop terminates.
+        loop.AddPendingCallback(make_callback());
+        loop.AddPendingCallback(make_callback());
+        loop.RequestTermination();
+      },
+      error);
+  ASSERT_TRUE(error.Success());
+  ASSERT_TRUE(handle);
+  ASSERT_TRUE(loop.Run().Success());
+  ASSERT_EQ(2u, callback_count);
+}
+
+TEST_F(MainLoopTest, PendingCallbackCalledOnlyOnce) {
+  char X = 'X';
+  size_t len = sizeof(X);
+  ASSERT_TRUE(socketpair[0]->Write(&X, len).Success());
+
+  MainLoop loop;
+  Status error;
+  auto handle = loop.RegisterReadObject(
+      socketpair[1],
+      [&](MainLoopBase &loop) {
+        // Add one pending callback on the first iteration.
+        if (callback_count == 0) {
+          loop.AddPendingCallback([&](MainLoopBase &loop) {
+            callback_count++;
+          });
+        }
+        // Terminate the loop on second iteration.
+        if (callback_count++ >= 1)
+          loop.RequestTermination();
+      },
+      error);
+  ASSERT_TRUE(error.Success());
+  ASSERT_TRUE(handle);
+  ASSERT_TRUE(loop.Run().Success());
+  // 2 iterations of read callback + 1 call of pending callback.
+  ASSERT_EQ(3u, callback_count);
+}
+
 #ifdef LLVM_ON_UNIX
 TEST_F(MainLoopTest, DetectsEOF) {
 
Index: lldb/source/Host/common/MainLoop.cpp
===================================================================
--- lldb/source/Host/common/MainLoop.cpp
+++ lldb/source/Host/common/MainLoop.cpp
@@ -347,6 +347,10 @@
 #endif
 }
 
+void MainLoop::AddPendingCallback(const Callback &callback) {
+  m_pending_callbacks.push_back(callback);
+}
+
 void MainLoop::UnregisterReadObject(IOObject::WaitableHandle handle) {
   bool erased = m_read_fds.erase(handle);
   UNUSED_IF_ASSERT_DISABLED(erased);
@@ -401,6 +405,10 @@
       return error;
 
     impl.ProcessEvents();
+
+    for (const Callback &callback : m_pending_callbacks)
+      callback(*this);
+    m_pending_callbacks.clear();
   }
   return Status();
 }
Index: lldb/include/lldb/Host/MainLoopBase.h
===================================================================
--- lldb/include/lldb/Host/MainLoopBase.h
+++ lldb/include/lldb/Host/MainLoopBase.h
@@ -46,6 +46,13 @@
     llvm_unreachable("Not implemented");
   }
 
+  // Add a pending callback that will be executed once after all the pending
+  // events are processed. The callback will be executed even if termination
+  // was requested.
+  virtual void AddPendingCallback(const Callback &callback) {
+    llvm_unreachable("Not implemented");
+  }
+
   // Waits for registered events and invoke the proper callbacks. Returns when
   // all callbacks deregister themselves or when someone requests termination.
   virtual Status Run() { llvm_unreachable("Not implemented"); }
Index: lldb/include/lldb/Host/MainLoop.h
===================================================================
--- lldb/include/lldb/Host/MainLoop.h
+++ lldb/include/lldb/Host/MainLoop.h
@@ -14,6 +14,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include <csignal>
 #include <list>
+#include <vector>
 
 #if !HAVE_PPOLL && !HAVE_SYS_EVENT_H && !defined(__ANDROID__)
 #define SIGNAL_POLLING_UNSUPPORTED 1
@@ -59,6 +60,11 @@
   SignalHandleUP RegisterSignal(int signo, const Callback &callback,
                                 Status &error);
 
+  // Add a pending callback that will be executed once after all the pending
+  // events are processed. The callback will be executed even if termination
+  // was requested.
+  void AddPendingCallback(const Callback &callback) override;
+
   Status Run() override;
 
   // This should only be performed from a callback. Do not attempt to terminate
@@ -104,6 +110,7 @@
 
   llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds;
   llvm::DenseMap<int, SignalInfo> m_signals;
+  std::vector<Callback> m_pending_callbacks;
 #if HAVE_SYS_EVENT_H
   int m_kqueue;
 #endif
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] D12... Michał Górny via Phabricator via lldb-commits
    • [Lldb-commits] [PATCH... Michał Górny via Phabricator via lldb-commits

Reply via email to