On 08/09/2012 10:38 PM, Peter Hutterer wrote:
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.hutte...@who-t.net>
---
  include/xorg/gtest/xorg-gtest-process.h | 20 ++++++++++++++++++++
  src/process.cpp                         | 12 ++++++++++++
  2 files changed, 32 insertions(+)

diff --git a/include/xorg/gtest/xorg-gtest-process.h 
b/include/xorg/gtest/xorg-gtest-process.h
index 402be49..ae471ec 100644
--- a/include/xorg/gtest/xorg-gtest-process.h
+++ b/include/xorg/gtest/xorg-gtest-process.h
@@ -37,6 +37,19 @@ namespace xorg {
  namespace testing {

  /**
+ * Describes the state of a process. Note that the state describes the state
+ * as seen by this library and may not reflect the
+ * state as seen by the operating system. For example, a Process may still
+ * be in state RUNNING when the actual process spawned has finished.
+ */
+enum ProcessState {
+  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 */
+};
+
+/**
   * @class Process xorg-gtest-process.h xorg/gtest/xorg-gtest-process.h
   *
   * Class that abstracts child process creation and termination.
@@ -179,6 +192,13 @@ class Process {
     */
    pid_t Pid() const;

+  /**
+   * Return the state of the process.
+   *
+   * @return The current state of the process
+   */
+  enum ProcessState GetState();
+
   private:
    struct Private;
    std::auto_ptr<Private> d_;
diff --git a/src/process.cpp b/src/process.cpp
index 7df2b84..7c5ac74 100644
--- a/src/process.cpp
+++ b/src/process.cpp
@@ -42,10 +42,16 @@

  struct xorg::testing::Process::Private {
    pid_t pid;
+  enum ProcessState state;
  };

  xorg::testing::Process::Process() : d_(new Private) {
    d_->pid = -1;
+  d_->state = NONE;
+}
+
+enum xorg::testing::ProcessState xorg::testing::Process::GetState() {
+  return d_->state;
  }

You could call wait*() with WNOHANG in GetState() if the state is currently RUNNING. This will allow for detection of erroring out or successful completion.

It may not be needed for your particular task, but I think this would be a more complete and well-defined implementation.


  void xorg::testing::Process::Start(const std::string &program, const 
std::vector<std::string> &argv) {
@@ -55,6 +61,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 +80,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) {
@@ -120,12 +130,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;
  }



_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to