[Lldb-commits] [lldb] SBDebugger: Add new APIs `AddDestroyCallback` and `RemoveDestroyCallback` (PR #89868)
via lldb-commits
lldb-commits at lists.llvm.org
Mon May 13 10:42:50 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);
----------------
jeffreytan81 wrote:
Any reason we remove after calling the callback?
https://github.com/llvm/llvm-project/pull/89868
More information about the lldb-commits
mailing list