[Lldb-commits] [lldb] SBDebugger: Add new APIs `AddDestroyCallback` and `RemoveDestroyCallback` (PR #89868)

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Thu May 2 09:21:24 PDT 2024


================
@@ -743,9 +743,24 @@ DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback,
 }
 
 void Debugger::HandleDestroyCallback() {
-  if (m_destroy_callback) {
-    m_destroy_callback(GetID(), m_destroy_callback_baton);
-    m_destroy_callback = nullptr;
+  std::lock_guard<std::recursive_mutex> guard(m_destroy_callback_mutex);
+  const lldb::user_id_t user_id = GetID();
+  // This loop handles the case where callbacks are added/removed by existing
+  // callbacks during the loop, as the following:
+  // - Added callbacks will always be invoked.
+  // - Removed callbacks will never be invoked. That is *unless* the loop
+  //   happens to invoke the said callbacks first, before they get removed.
+  //   In this case, the callbacks gets invoked, and the removal return false.
+  //
+  // In the removal case, because the order of the container (`unordered_map`)
+  // is random, it's wise to not depend on the order and instead implement
+  // logic inside the callbacks to decide if their work should be skipped.
+  while (m_destroy_callback_and_baton.size()) {
+    auto iter = m_destroy_callback_and_baton.begin();
+    const auto &callback = iter->second.first;
+    const auto &baton = iter->second.second;
----------------
JDevlieghere wrote:

Using `auto` for the iterator is fine, but it's not obvious from context what the types are of `.first` and `.second`. The  [LLVM Coding Standards](https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable) have a paragraph on when to use (and no use) `auto`. A few more instances of that below. 

https://github.com/llvm/llvm-project/pull/89868


More information about the lldb-commits mailing list