Allow for mutable lambdas with Future::ensure()
[folly.git] / folly / Subprocess.h
index da2b560241fdf80eb9160648d6f5746487b18cc4..4f970082fee6485f48e8b5398056ea166a87f1dc 100644 (file)
@@ -126,12 +126,18 @@ class ProcessReturnCode {
   friend class Subprocess;
  public:
   enum State {
+    // Subprocess starts in the constructor, so this state designates only
+    // default-initialized or moved-out ProcessReturnCodes.
     NOT_STARTED,
     RUNNING,
     EXITED,
     KILLED
   };
 
+  // Default-initialized for convenience. Subprocess::returnCode() will
+  // never produce this value.
+  ProcessReturnCode() : ProcessReturnCode(RV_NOT_STARTED) {}
+
   // Trivially copyable
   ProcessReturnCode(const ProcessReturnCode& p) = default;
   ProcessReturnCode& operator=(const ProcessReturnCode& p) = default;
@@ -208,7 +214,7 @@ class SubprocessError : public std::exception {};
 class CalledProcessError : public SubprocessError {
  public:
   explicit CalledProcessError(ProcessReturnCode rc);
-  ~CalledProcessError() throw() { }
+  ~CalledProcessError() throw() = default;
   const char* what() const throw() FOLLY_OVERRIDE { return what_.c_str(); }
   ProcessReturnCode returnCode() const { return returnCode_; }
  private:
@@ -222,7 +228,7 @@ class CalledProcessError : public SubprocessError {
 class SubprocessSpawnError : public SubprocessError {
  public:
   SubprocessSpawnError(const char* executable, int errCode, int errnoValue);
-  ~SubprocessSpawnError() throw() {}
+  ~SubprocessSpawnError() throw() = default;
   const char* what() const throw() FOLLY_OVERRIDE { return what_.c_str(); }
   int errnoValue() const { return errnoValue_; }
 
@@ -410,11 +416,12 @@ class Subprocess {
   ProcessReturnCode returnCode() const { return returnCode_; }
 
   /**
-   * Poll the child's status and return it, return -1 if the process
-   * is still running.  NOTE that it is illegal to call poll again after
-   * poll indicated that the process has terminated, or to call poll on a
-   * process that hasn't been successfully started (the constructor threw an
-   * exception).
+   * Poll the child's status and return it. Return the exit status if the
+   * subprocess had quit, or RUNNING otherwise.  Throws an std::logic_error
+   * if called on a Subprocess whose status is no longer RUNNING.  No other
+   * exceptions are possible.  Aborts on egregious violations of contract,
+   * e.g. if you wait for the underlying process without going through this
+   * Subprocess instance.
    */
   ProcessReturnCode poll();
 
@@ -426,9 +433,10 @@ class Subprocess {
   bool pollChecked();
 
   /**
-   * Wait for the process to terminate and return its status.
-   * Similarly to poll, it is illegal to call wait after the process
-   * has already been reaped or if the process has not successfully started.
+   * Wait for the process to terminate and return its status.  Like poll(),
+   * the only exception this can throw is std::logic_error if you call this
+   * on a Subprocess whose status is RUNNING.  Aborts on egregious
+   * violations of contract, like an out-of-band waitpid(p.pid(), 0, 0).
    */
   ProcessReturnCode wait();
 
@@ -714,6 +722,7 @@ class Subprocess {
    * No, you may NOT call this from a communicate() callback.
    */
   struct ChildPipe {
+    ChildPipe(int fd, folly::File&& ppe) : childFd(fd), pipe(std::move(ppe)) {}
     int childFd;
     folly::File pipe;  // Owns the parent FD
   };