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:
Mike Gelfand
2016-01-09 02:16:55 +03:00
parent 279ea9d0e2
commit 0425866486
4 changed files with 82 additions and 11 deletions

View File

@@ -21,6 +21,9 @@
#include "Poco/Foundation.h"
#include "Poco/Event.h"
#include "Poco/Mutex.h"
#include "Poco/Optional.h"
#include "Poco/RefCountedObject.h"
#include <unistd.h>
#include <vector>
@@ -41,9 +44,13 @@ public:
pid_t id() const;
int wait() const;
int wait(int options) const;
private:
pid_t _pid;
const pid_t _pid;
mutable FastMutex _mutex;
mutable Event _event;
mutable Optional<int> _status;
};