mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-28 11:31:53 +01:00
Allow for process termination when polling with isRunning
On *NIX, one needs to call `waitpid()` in order for process to exit the zombie state. If one uses `Process::isRunning()` to emulate non-blocking wait for child process termination, process will stay zombie and function will always return true. This commit changes `Process::isRunning()` to call `waitpid()` with `WNOHANG` instead of using `kill()` when checking for child process (i.e. the one we have ProcessHandle for), which allows for process termination. Additional trickery with mutex and event is needed to prevent exceptions when `Process::isRunning()` and/or `Process::wait()` is called concurrently on the same handle from different threads. Fixes #1097.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "Poco/Process.h"
|
||||
#include "Poco/Pipe.h"
|
||||
#include "Poco/PipeStream.h"
|
||||
#include "Poco/Thread.h"
|
||||
#include <csignal>
|
||||
|
||||
|
||||
@@ -176,6 +177,27 @@ void ProcessTest::testIsRunning()
|
||||
}
|
||||
|
||||
|
||||
void ProcessTest::testIsRunningAllowsForTermination()
|
||||
{
|
||||
#if !defined(_WIN32_WCE)
|
||||
std::string name("TestApp");
|
||||
std::string cmd;
|
||||
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
cmd = "./";
|
||||
cmd += name;
|
||||
#else
|
||||
cmd = name;
|
||||
#endif
|
||||
|
||||
std::vector<std::string> args;
|
||||
ProcessHandle ph = Process::launch(cmd, args, 0, 0, 0);
|
||||
while (Process::isRunning(ph))
|
||||
Poco::Thread::sleep(100);
|
||||
#endif // !defined(_WIN32_WCE)
|
||||
}
|
||||
|
||||
|
||||
void ProcessTest::testSignalExitCode()
|
||||
{
|
||||
#if defined(POCO_OS_FAMILY_UNIX)
|
||||
@@ -213,6 +235,7 @@ CppUnit::Test* ProcessTest::suite()
|
||||
CppUnit_addTest(pSuite, ProcessTest, testLaunchRedirectOut);
|
||||
CppUnit_addTest(pSuite, ProcessTest, testLaunchEnv);
|
||||
CppUnit_addTest(pSuite, ProcessTest, testIsRunning);
|
||||
CppUnit_addTest(pSuite, ProcessTest, testIsRunningAllowsForTermination);
|
||||
CppUnit_addTest(pSuite, ProcessTest, testSignalExitCode);
|
||||
|
||||
return pSuite;
|
||||
|
||||
Reference in New Issue
Block a user