Commit 4af3040b authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Let ProcessReturnCode be publicly constructible

Summary:
[Folly] Let `ProcessReturnCode` be publicly constructible.

Via provided constructor functions, which limit how it may be constructed so that it is only constructible into a valid state.

Differential Revision: D5898739

fbshipit-source-id: 7490018adfc39408b4290248ef1220e8fd0238cb
parent 91da2e5a
......@@ -51,6 +51,14 @@ constexpr int kChildFailure = 126;
namespace folly {
ProcessReturnCode ProcessReturnCode::make(int status) {
if (!WIFEXITED(status) && !WIFSIGNALED(status)) {
throw std::runtime_error(
to<std::string>("Invalid ProcessReturnCode: ", status));
}
return ProcessReturnCode(status);
}
ProcessReturnCode::ProcessReturnCode(ProcessReturnCode&& p) noexcept
: rawStatus_(p.rawStatus_) {
p.rawStatus_ = ProcessReturnCode::RV_NOT_STARTED;
......@@ -68,8 +76,7 @@ ProcessReturnCode::State ProcessReturnCode::state() const {
if (rawStatus_ == RV_RUNNING) return RUNNING;
if (WIFEXITED(rawStatus_)) return EXITED;
if (WIFSIGNALED(rawStatus_)) return KILLED;
throw std::runtime_error(to<std::string>(
"Invalid ProcessReturnCode: ", rawStatus_));
assume_unreachable();
}
void ProcessReturnCode::enforce(State expected) const {
......@@ -427,7 +434,7 @@ void Subprocess::spawnInternal(
// child has exited and can be immediately waited for. In all other cases,
// we have no way of cleaning up the child.
pid_ = pid;
returnCode_ = ProcessReturnCode(RV_RUNNING);
returnCode_ = ProcessReturnCode::makeRunning();
}
int Subprocess::prepareChild(const Options& options,
......@@ -562,7 +569,7 @@ ProcessReturnCode Subprocess::poll(struct rusage* ru) {
if (found != 0) {
// Though the child process had quit, this call does not close the pipes
// since its descendants may still be using them.
returnCode_ = ProcessReturnCode(status);
returnCode_ = ProcessReturnCode::make(status);
pid_ = -1;
}
return returnCode_;
......@@ -590,7 +597,7 @@ ProcessReturnCode Subprocess::wait() {
// Though the child process had quit, this call does not close the pipes
// since its descendants may still be using them.
DCHECK_EQ(found, pid_);
returnCode_ = ProcessReturnCode(status);
returnCode_ = ProcessReturnCode::make(status);
pid_ = -1;
return returnCode_;
}
......
......@@ -127,7 +127,6 @@ namespace folly {
*/
class Subprocess;
class ProcessReturnCode {
friend class Subprocess;
public:
enum State {
// Subprocess starts in the constructor, so this state designates only
......@@ -135,12 +134,22 @@ class ProcessReturnCode {
NOT_STARTED,
RUNNING,
EXITED,
KILLED
KILLED,
};
static ProcessReturnCode makeNotStarted() {
return ProcessReturnCode(RV_NOT_STARTED);
}
static ProcessReturnCode makeRunning() {
return ProcessReturnCode(RV_RUNNING);
}
static ProcessReturnCode make(int status);
// Default-initialized for convenience. Subprocess::returnCode() will
// never produce this value.
ProcessReturnCode() : ProcessReturnCode(RV_NOT_STARTED) {}
ProcessReturnCode() : rawStatus_(RV_NOT_STARTED) {}
// Trivially copyable
ProcessReturnCode(const ProcessReturnCode& p) = default;
......@@ -813,9 +822,6 @@ class Subprocess {
std::vector<ChildPipe> takeOwnershipOfPipes();
private:
static const int RV_RUNNING = ProcessReturnCode::RV_RUNNING;
static const int RV_NOT_STARTED = ProcessReturnCode::RV_NOT_STARTED;
// spawn() sets up a pipe to read errors from the child,
// then calls spawnInternal() to do the bulk of the work. Once
// spawnInternal() returns it reads the error pipe to see if the child
......@@ -851,7 +857,7 @@ class Subprocess {
size_t findByChildFd(const int childFd) const;
pid_t pid_{-1};
ProcessReturnCode returnCode_{RV_NOT_STARTED};
ProcessReturnCode returnCode_;
/**
* Represents a pipe between this process, and the child process (or its
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment