From 1ed2779abc83f65dc22ca9cefde7a70c97b03eda Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Mon, 10 Jun 2024 15:27:14 +0200 Subject: [PATCH] Fix #122973: Subprocesses aren't closed if Blender crashes Assigns all subprocesses to a job owned by the main Blender instance, so they're closed when it ends. Pull Request: https://projects.blender.org/blender/blender/pulls/123001 --- .../blender/blenlib/intern/BLI_subprocess.cc | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/BLI_subprocess.cc b/source/blender/blenlib/intern/BLI_subprocess.cc index 06017c5f574..3c91dceb319 100644 --- a/source/blender/blenlib/intern/BLI_subprocess.cc +++ b/source/blender/blenlib/intern/BLI_subprocess.cc @@ -56,6 +56,34 @@ static void check(bool result, const char *function, const char *msg) # undef ERROR /* Defined in wingdi.h */ # define ERROR(msg) check(false, __func__, msg) +/* Owning process group that will close subprocesses assigned to it when the instance is destructed + * or the creator process ends. */ +class ProcessGroup { + private: + HANDLE handle_; + + public: + ProcessGroup() + { + handle_ = CreateJobObject(nullptr, nullptr); + CHECK(handle_); + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info = {0}; + info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + CHECK( + SetInformationJobObject(handle_, JobObjectExtendedLimitInformation, &info, sizeof(info))); + } + + ~ProcessGroup() + { + CHECK(CloseHandle(handle_)); + } + + void assign_subprocess(HANDLE subprocess) + { + CHECK(AssignProcessToJobObject(handle_, subprocess)); + } +}; + bool BlenderSubprocess::create(Span args) { BLI_assert(handle_ == nullptr); @@ -91,7 +119,7 @@ bool BlenderSubprocess::create(Span args) nullptr, nullptr, false, - 0, + CREATE_BREAKAWAY_FROM_JOB, nullptr, nullptr, &startup_info, @@ -104,6 +132,10 @@ bool BlenderSubprocess::create(Span args) handle_ = process_info.hProcess; CHECK(CloseHandle(process_info.hThread)); + static ProcessGroup group; + /* Don't let the subprocess outlive its parent. */ + group.assign_subprocess(handle_); + return true; }