diff --git a/src/main.cpp b/src/main.cpp index 89cf7a8b..e69e0aa8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -594,6 +594,11 @@ main(int argc, char *argv[]) { BOOST_LOG(error) << "Platform failed to initialize"sv; } + auto proc_deinit_guard = proc::init(); + if (!proc_deinit_guard) { + BOOST_LOG(error) << "Proc failed to initialize"sv; + } + reed_solomon_init(); auto input_deinit_guard = input::init(); if (video::probe_encoders()) { diff --git a/src/process.cpp b/src/process.cpp index 42b94d1a..1a0f8e53 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -40,6 +40,22 @@ namespace proc { proc_t proc; + class deinit_t: public platf::deinit_t { + public: + ~deinit_t() { + proc.terminate(); + } + }; + + /** + * @brief Initializes proc functions + * @return Unique pointer to `deinit_t` to manage cleanup + */ + std::unique_ptr + init() { + return std::make_unique(); + } + void process_end(bp::child &proc, bp::group &proc_handle) { if (!proc.running()) { @@ -266,7 +282,12 @@ namespace proc { } proc_t::~proc_t() { - terminate(); + // It's not safe to call terminate() here because our proc_t is a static variable + // that may be destroyed after the Boost loggers have been destroyed. Instead, + // we return a deinit_t to main() to handle termination when we're exiting. + // Once we reach this point here, termination must have already happened. + assert(!placebo); + assert(!_process.running()); } std::string_view::iterator diff --git a/src/process.h b/src/process.h index b05e46e8..038e86f0 100644 --- a/src/process.h +++ b/src/process.h @@ -14,6 +14,7 @@ #include #include "config.h" +#include "platform/common.h" #include "utility.h" namespace proc { @@ -116,5 +117,8 @@ namespace proc { std::optional parse(const std::string &file_name); + std::unique_ptr + init(); + extern proc_t proc; } // namespace proc