diff options
| author | Leitwolf | 2026-11-14 16:46:04 +0300 |
|---|---|---|
| committer | GitHub | 2026-11-14 16:46:04 +0300 |
| commit | 94a996a3ceafa9f0004ffc28a7de5c543cdb51c2 (patch) | |
| tree | e8db06877788de36d3fd4166472c4511f0c0412a /src/Progmasoft/Runner/Process.cpp | |
| parent | 586a42e35788d269871dcadbed2ec59b6b8a9203 (diff) | |
| parent | 5ad02bccfcb925df02d1273901b6e248d477c5fa (diff) | |
| download | catch3-94a996a3ceafa9f0004ffc28a7de5c543cdb51c2.tar.gz | |
Keep per-test coverage with --coverage (roadmap step 4)
Diffstat (limited to 'src/Progmasoft/Runner/Process.cpp')
| -rw-r--r-- | src/Progmasoft/Runner/Process.cpp | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/Progmasoft/Runner/Process.cpp b/src/Progmasoft/Runner/Process.cpp index 85987210..e3b0997b 100644 --- a/src/Progmasoft/Runner/Process.cpp +++ b/src/Progmasoft/Runner/Process.cpp @@ -6,6 +6,7 @@ #include <cstdlib> #include <cstring> #include <iterator> +#include <mutex> #include <string_view> #include <thread> @@ -611,6 +612,22 @@ namespace Progmasoft::Catch3::Runner #endif } + namespace + { + /// Held while a child starts. Starting changes what the whole process + /// shares: the working directory on POSIX, and the handles a child + /// inherits; two threads starting children at once would see each + /// other's directory or hand their pipes to each other's child. + std::mutex & + StartLock() + { + // Never destroyed, so no exit-time destructor runs while a + // detached thread may still start a child. + static std::mutex *const lock = new std::mutex; + return *lock; + } + } // namespace + #if defined(_WIN32) Expected<std::unique_ptr<ChildProcess>> ChildProcess::Start(const ChildOptions &options) @@ -619,6 +636,7 @@ namespace Progmasoft::Catch3::Runner { return Error{ "no program to start" }; } + const std::lock_guard<std::mutex> starting{ StartLock() }; SECURITY_ATTRIBUTES inheritable{}; inheritable.nLength = sizeof(inheritable); inheritable.bInheritHandle = TRUE; @@ -981,6 +999,7 @@ namespace Progmasoft::Catch3::Runner { return Error{ "no program to start" }; } + const std::lock_guard<std::mutex> starting{ StartLock() }; int input[2] = { -1, -1 }; int output[2] = { -1, -1 }; int errors[2] = { -1, -1 }; @@ -1072,7 +1091,10 @@ namespace Progmasoft::Catch3::Runner arguments.push_back(nullptr); // posix_spawn has no working-directory action everywhere, so the - // directory changes around the call; only this thread spawns. + // directory changes around the call, under StartLock. A thread that + // reads a relative path meanwhile would read it from there, so + // callers that start children from several threads use absolute + // paths or no working directory. std::filesystem::path previousDirectory; if (!options.workingDirectory.empty()) { |