Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/Progmasoft/Runner/Process.cpp
diff options
context:
space:
mode:
authorLeitwolf2026-11-14 16:46:04 +0300
committerGitHub2026-11-14 16:46:04 +0300
commit94a996a3ceafa9f0004ffc28a7de5c543cdb51c2 (patch)
treee8db06877788de36d3fd4166472c4511f0c0412a /src/Progmasoft/Runner/Process.cpp
parent586a42e35788d269871dcadbed2ec59b6b8a9203 (diff)
parent5ad02bccfcb925df02d1273901b6e248d477c5fa (diff)
downloadcatch3-94a996a3ceafa9f0004ffc28a7de5c543cdb51c2.tar.gz
Merge pull request #39 from Progmasoft/feature/per-test-coverageHEADdevel
Keep per-test coverage with --coverage (roadmap step 4)
Diffstat (limited to 'src/Progmasoft/Runner/Process.cpp')
-rw-r--r--src/Progmasoft/Runner/Process.cpp24
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())
{