================ @@ -66,3 +66,47 @@ void Progress::ReportProgress() { m_debugger_id); } } + +void ProgressManager::Initialize() { + lldbassert(!InstanceImpl() && "A progress report manager already exists."); + InstanceImpl().emplace(); +} + +void ProgressManager::Terminate() { + lldbassert(InstanceImpl() && + "A progress report manager has already been terminated."); + InstanceImpl().reset(); +} + +std::optional<ProgressManager> &ProgressManager::InstanceImpl() { + static std::optional<ProgressManager> g_progress_manager; + return g_progress_manager; +} + +ProgressManager::ProgressManager() : m_progress_map() {} + +ProgressManager::~ProgressManager() {} + +ProgressManager &ProgressManager::Instance() { return *InstanceImpl(); } ---------------- clayborg wrote:
If we want to use a static variable in `std::optional<ProgressManager> &ProgressManager::InstanceImpl()`, then we need to return a `std::optional<ProgressManager>` here and people need to check it and not use it if the optional isn't valid. If we always want to return a "ProgressManager &" here, then we need `InstanceImpl()` to look like: ``` ProgressManager &ProgressManager::InstanceImpl() { static std::once g_once_flag; static ProgressManager *g_progress_manager = nullptr; std::call_once(std::call_once(g_once_flag, { // NOTE: known leak to avoid global destructor chain issues. g_progress_manager = new ProgressManager(); }); return *g_progress_manager; } ``` And then we don't need `ProgressManager::Initialize()` or `ProgressManager::Terminate()`. The problem is when the process exits, the main thread exists and calls the C++ global destructor chain and if any threads are still running and call any of these functions that require the global instance of `ProgressManager`, it can crash the process. https://github.com/llvm/llvm-project/pull/81319 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits