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

via lldb-commits lldb-commits at lists.llvm.org
Mon May 13 14:00:16 PDT 2024


================
@@ -743,9 +743,28 @@ 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 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 lldb::destroy_callback_token_t &token = iter->first;
+    const lldb_private::DebuggerDestroyCallback &callback = iter->second.first;
+    void *const &baton = iter->second.second;
+    callback(user_id, baton);
+    // Using `token` to erase, because elements may have been added/removed, and
+    // that will cause error "invalid iterator access!" if `iter` is used
+    // instead.
+    m_destroy_callback_and_baton.erase(token);
----------------
royitaqi wrote:

The callbacks can add/remove other callbacks while this loop is being executed. I.e. the content in the container can change during the loop.

To handle this, the loop always take the first element, call it, then remove it, so that the next "first element" will be a new one.

If we don't remove, I wonder how we can make sure that the callbacks which are added during the loop are executed.

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


More information about the lldb-commits mailing list