[PATCH v2 xorg-gtest] process: add state enum and GetState()

Peter Hutterer peter.hutterer at who-t.net
Mon Aug 13 18:20:51 PDT 2012


Add a set of basic states to Process to allow callers to keep track of which
state a process is in (as seen from the library). This simplifies code that
needs to happen on certain conditions only, e.g. log file cleanup is only
needed if the process was previously started.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Changes to v1:
- Move enum to Process class to better confine it
- Check state on GetState(), update if it terminated on its own. 
- Check state on KillSelf(), return true if it already terminated anyway

 include/xorg/gtest/xorg-gtest-process.h | 17 +++++++++++++++++
 src/process.cpp                         | 25 +++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/include/xorg/gtest/xorg-gtest-process.h b/include/xorg/gtest/xorg-gtest-process.h
index 402be49..c4b2309 100644
--- a/include/xorg/gtest/xorg-gtest-process.h
+++ b/include/xorg/gtest/xorg-gtest-process.h
@@ -62,6 +62,16 @@ namespace testing {
  */
 class Process {
  public:
+   /**
+    * Describes the state of a process.
+    */
+   enum State {
+     ERROR,        /**< An error has occured, state is now unknown */
+     NONE,         /**< The process has not been started yet */
+     RUNNING,      /**< The process has been started */
+     TERMINATED,   /**< The process was terminated by this library */
+   };
+
   /**
    * Helper function to adjust the environment of the current process.
    *
@@ -179,6 +189,13 @@ class Process {
    */
   pid_t Pid() const;
 
+  /**
+   * Return the state of the process.
+   *
+   * @return The current state of the process
+   */
+  enum Process::State GetState();
+
  private:
   struct Private;
   std::auto_ptr<Private> d_;
diff --git a/src/process.cpp b/src/process.cpp
index 7df2b84..c976720 100644
--- a/src/process.cpp
+++ b/src/process.cpp
@@ -42,10 +42,26 @@
 
 struct xorg::testing::Process::Private {
   pid_t pid;
+  enum State state;
 };
 
 xorg::testing::Process::Process() : d_(new Private) {
   d_->pid = -1;
+  d_->state = NONE;
+}
+
+enum xorg::testing::Process::State xorg::testing::Process::GetState() {
+  if (d_->state == RUNNING) {
+    int status;
+    int pid = waitpid(Pid(), &status, WNOHANG);
+    if (pid == Pid()) {
+      if (WIFEXITED(status))
+        d_->pid = -1;
+        d_->state = TERMINATED;
+    }
+  }
+
+  return d_->state;
 }
 
 void xorg::testing::Process::Start(const std::string &program, const std::vector<std::string> &argv) {
@@ -55,6 +71,7 @@ void xorg::testing::Process::Start(const std::string &program, const std::vector
   d_->pid = fork();
 
   if (d_->pid == -1) {
+    d_->state = ERROR;
     throw std::runtime_error("Failed to fork child process");
   } else if (d_->pid == 0) { /* Child */
     close(0);
@@ -73,8 +90,11 @@ void xorg::testing::Process::Start(const std::string &program, const std::vector
 
     execvp(program.c_str(), &args[0]);
 
+    d_->state = ERROR;
     throw std::runtime_error("Failed to start process");
   }
+
+  d_->state = RUNNING;
 }
 
 void xorg::testing::Process::Start(const std::string& program, va_list args) {
@@ -112,6 +132,9 @@ bool xorg::testing::Process::WaitForExit(unsigned int timeout) {
 bool xorg::testing::Process::KillSelf(int signal, unsigned int timeout) {
   bool wait_success = true;
 
+  if (GetState() == TERMINATED)
+    return true;
+
   if (d_->pid == -1) {
     return false;
   } else if (d_->pid == 0) {
@@ -120,12 +143,14 @@ bool xorg::testing::Process::KillSelf(int signal, unsigned int timeout) {
   } else { /* Parent */
     if (kill(d_->pid, signal) < 0) {
       d_->pid = -1;
+      d_->state = ERROR;
       return false;
     }
     if (timeout > 0)
       wait_success = WaitForExit(timeout);
     d_->pid = -1;
   }
+  d_->state = TERMINATED;
   return wait_success;
 }
 
-- 
1.7.11.2



More information about the xorg-devel mailing list