You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2013/05/29 19:41:07 UTC

[29/35] Renamed 'third_party' to '3rdparty'.

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/proc.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/proc.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/proc.hpp
new file mode 100644
index 0000000..b59735f
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/proc.hpp
@@ -0,0 +1,478 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PROC_HPP__
+#define __PROC_HPP__
+
+// This file contains linux-only utilities for /proc.
+#ifndef __linux__
+#error "stout/proc.hpp is only available on Linux systems."
+#endif
+
+#include <errno.h>
+#include <signal.h>
+
+#include <sys/types.h> // For pid_t.
+
+#include <fstream>
+#include <list>
+#include <queue>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "error.hpp"
+#include "foreach.hpp"
+#include "none.hpp"
+#include "numify.hpp"
+#include "option.hpp"
+#include "os.hpp"
+#include "strings.hpp"
+#include "try.hpp"
+
+namespace proc {
+
+// Snapshot of a process (modeled after /proc/[pid]/stat).
+// For more information, see:
+// http://www.kernel.org/doc/Documentation/filesystems/proc.txt
+struct ProcessStatus
+{
+  ProcessStatus(
+      pid_t _pid,
+      const std::string& _comm,
+      char _state,
+      pid_t _ppid,
+      pid_t _pgrp,
+      pid_t _session,
+      int _tty_nr,
+      pid_t _tpgid,
+      unsigned int _flags,
+      unsigned long _minflt,
+      unsigned long _cminflt,
+      unsigned long _majflt,
+      unsigned long _cmajflt,
+      unsigned long _utime,
+      unsigned long _stime,
+      long _cutime,
+      long _cstime,
+      long _priority,
+      long _nice,
+      long _num_threads,
+      long _itrealvalue,
+      unsigned long long _starttime,
+      unsigned long _vsize,
+      long _rss,
+      unsigned long _rsslim,
+      unsigned long _startcode,
+      unsigned long _endcode,
+      unsigned long _startstack,
+      unsigned long _kstkeip,
+      unsigned long _signal,
+      unsigned long _blocked,
+      unsigned long _sigcatch,
+      unsigned long _wchan,
+      unsigned long _nswap,
+      unsigned long _cnswap)
+  : pid(_pid),
+    comm(_comm),
+    state(_state),
+    ppid(_ppid),
+    pgrp(_pgrp),
+    session(_session),
+    tty_nr(_tty_nr),
+    tpgid(_tpgid),
+    flags(_flags),
+    minflt(_minflt),
+    cminflt(_cminflt),
+    majflt(_majflt),
+    cmajflt(_cmajflt),
+    utime(_utime),
+    stime(_stime),
+    cutime(_cutime),
+    cstime(_cstime),
+    priority(_priority),
+    nice(_nice),
+    num_threads(_num_threads),
+    itrealvalue(_itrealvalue),
+    starttime(_starttime),
+    vsize(_vsize),
+    rss(_rss),
+    rsslim(_rsslim),
+    startcode(_startcode),
+    endcode(_endcode),
+    startstack(_startstack),
+    kstkeip(_kstkeip),
+    signal(_signal),
+    blocked(_blocked),
+    sigcatch(_sigcatch),
+    wchan(_wchan),
+    nswap(_nswap),
+    cnswap(_cnswap) {}
+
+  const pid_t pid;
+  const std::string comm;
+  const char state;
+  const int ppid;
+  const int pgrp;
+  const int session;
+  const int tty_nr;
+  const int tpgid;
+  const unsigned int flags;
+  const unsigned long minflt;
+  const unsigned long cminflt;
+  const unsigned long majflt;
+  const unsigned long cmajflt;
+  const unsigned long utime;
+  const unsigned long stime;
+  const long cutime;
+  const long cstime;
+  const long priority;
+  const long nice;
+  const long num_threads;
+  const long itrealvalue;
+  const unsigned long long starttime;
+  const unsigned long vsize;
+  const long rss;
+  const unsigned long rsslim;
+  const unsigned long startcode;
+  const unsigned long endcode;
+  const unsigned long startstack;
+  const unsigned long kstkeip;
+  const unsigned long signal;
+  const unsigned long blocked;
+  const unsigned long sigcatch;
+  const unsigned long wchan;
+  const unsigned long nswap;
+  const unsigned long cnswap;
+};
+
+
+// Returns the process statistics from /proc/[pid]/stat.
+inline Try<ProcessStatus> status(pid_t pid)
+{
+  std::string path = "/proc/" + stringify(pid) + "/stat";
+
+  std::ifstream file(path.c_str());
+
+  if (!file.is_open()) {
+    return Error("Failed to open '" + path + "'");
+  }
+
+  std::string comm;
+  char state;
+  pid_t ppid;
+  pid_t pgrp;
+  pid_t session;
+  int tty_nr;
+  pid_t tpgid;
+  unsigned int flags;
+  unsigned long minflt;
+  unsigned long cminflt;
+  unsigned long majflt;
+  unsigned long cmajflt;
+  unsigned long utime;
+  unsigned long stime;
+  long cutime;
+  long cstime;
+  long priority;
+  long nice;
+  long num_threads;
+  long itrealvalue;
+  unsigned long long starttime;
+  unsigned long vsize;
+  long rss;
+  unsigned long rsslim;
+  unsigned long startcode;
+  unsigned long endcode;
+  unsigned long startstack;
+  unsigned long kstkeip;
+  unsigned long signal;
+  unsigned long blocked;
+  unsigned long sigcatch;
+  unsigned long wchan;
+  unsigned long nswap;
+  unsigned long cnswap;
+
+  // NOTE: The following are unused for now.
+  // int exit_signal;
+  // int processor;
+  // unsigned int rt_priority;
+  // unsigned int policy;
+  // unsigned long long delayacct_blkio_ticks;
+  // unsigned long guest_time;
+  // unsigned int cguest_time;
+
+  std::string _; // For ignoring fields.
+
+  // Parse all fields from stat.
+  file >> _ >> comm >> state >> ppid >> pgrp >> session >> tty_nr
+       >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
+       >> utime >> stime >> cutime >> cstime >> priority >> nice
+       >> num_threads >> itrealvalue >> starttime >> vsize >> rss
+       >> rsslim >> startcode >> endcode >> startstack >> kstkeip
+       >> signal >> blocked >> sigcatch >> wchan >> nswap >> cnswap;
+
+  // Check for any read/parse errors.
+  if (file.fail() && !file.eof()) {
+    file.close();
+    return Error("Failed to read/parse '" + path + "'");
+  }
+
+  file.close();
+
+  return ProcessStatus(pid, comm, state, ppid, pgrp, session, tty_nr,
+                       tpgid, flags, minflt, cminflt, majflt, cmajflt,
+                       utime, stime, cutime, cstime, priority, nice,
+                       num_threads, itrealvalue, starttime, vsize, rss,
+                       rsslim, startcode, endcode, startstack, kstkeip,
+                       signal, blocked, sigcatch, wchan, nswap, cnswap);
+}
+
+
+// Reads from /proc and returns a list of all running processes.
+inline Try<std::set<pid_t> > pids()
+{
+  std::set<pid_t> pids;
+
+  foreach (const std::string& file, os::ls("/proc")) {
+    Try<pid_t> pid = numify<pid_t>(file);
+    if (pid.isSome()) {
+      pids.insert(pid.get()); // Ignore files that can't be numified.
+    }
+  }
+
+  if (!pids.empty()) {
+    return pids;
+  }
+
+  return Error("Failed to determine pids from /proc");
+}
+
+
+// Returns all child processes of the pid, including all descendants
+// if recursive.
+inline Try<std::set<pid_t> > children(pid_t pid, bool recursive = true)
+{
+  const Try<std::set<pid_t> >& pids = proc::pids();
+  if (pids.isError()) {
+    return Error(pids.error());
+  }
+
+  // Stat all the processes.
+  std::list<ProcessStatus> processes;
+  foreach (pid_t _pid, pids.get()) {
+    const Try<ProcessStatus>& process = status(_pid);
+    if (process.isSome()) {
+      processes.push_back(process.get());
+    }
+  }
+
+  // Perform a breadth first search for descendants.
+  std::set<pid_t> descendants;
+  std::queue<pid_t> parents;
+  parents.push(pid);
+
+  do {
+    pid_t parent = parents.front();
+    parents.pop();
+
+    // Search for children of parent.
+    foreach (const ProcessStatus& process, processes) {
+      if (process.ppid == parent) {
+        // Have we seen this child yet?
+        if (descendants.insert(process.pid).second) {
+          parents.push(process.pid);
+        }
+      }
+    }
+  } while (recursive && !parents.empty());
+
+  return descendants;
+}
+
+
+// Snapshot of a system (modeled after /proc/stat).
+struct SystemStatus
+{
+  SystemStatus(unsigned long long _btime) : btime(_btime) {}
+
+  const unsigned long long btime; // Boot time.
+  // TODO(benh): Add more.
+};
+
+
+// Returns the system statistics from /proc/stat.
+inline Try<SystemStatus> status()
+{
+  unsigned long long btime = 0;
+
+  std::ifstream file("/proc/stat");
+
+  if (!file.is_open()) {
+    return Error("Failed to open /proc/stat");
+  }
+
+  std::string line;
+  while (std::getline(file, line)) {
+    if (line.find("btime ") == 0) {
+      Try<unsigned long long> number =
+        numify<unsigned long long>(line.substr(6));
+
+      if (number.isError()) {
+        return Error("Failed to parse /proc/stat: " + number.error());
+      }
+
+      btime = number.get();
+      break;
+    }
+  }
+
+  if (file.fail() && !file.eof()) {
+    file.close();
+    return Error("Failed to read /proc/stat");
+  }
+
+  file.close();
+
+  return SystemStatus(btime);
+}
+
+
+// Representation of a processor (really an execution unit since this
+// captures "hardware threads" as well) modeled after /proc/cpuinfo.
+struct CPU
+{
+  CPU(unsigned int _id, unsigned int _core, unsigned int _socket)
+    : id(_id), core(_core), socket(_socket) {}
+
+  // These are non-const because we need the default assignment operator.
+  unsigned int id; // "processor"
+  unsigned int core; // "core id"
+  unsigned int socket; // "physical id"
+};
+
+
+inline bool operator == (const CPU& lhs, const CPU& rhs)
+{
+  return (lhs.id == rhs.id) && (lhs.core == rhs.core) &&
+    (lhs.socket == rhs.socket);
+}
+
+
+inline bool operator < (const CPU& lhs, const CPU& rhs)
+{
+  // Sort by (socket, core, id).
+  if (lhs.socket != rhs.socket) {
+    return lhs.socket < rhs.socket;
+  }
+
+  // On the same socket.
+  if (lhs.core != rhs.core) {
+    return lhs.core < rhs.core;
+  }
+
+  // On the same core.
+  return lhs.id < rhs.id;
+}
+
+
+inline std::ostream& operator << (std::ostream& out, const CPU& cpu)
+{
+  return out << "CPU (id:" << cpu.id << ", "
+             << "core:" << cpu.core << ", "
+             << "socket:" << cpu.socket << ")";
+}
+
+
+// Reads from /proc/cpuinfo and returns a list of CPUs.
+inline Try<std::list<CPU> > cpus()
+{
+  std::list<CPU> results;
+
+  std::ifstream file("/proc/cpuinfo");
+
+  if (!file.is_open()) {
+    return Error("Failed to open /proc/cpuinfo");
+  }
+
+  // Placeholders as we parse the file.
+  Option<unsigned int> id;
+  Option<unsigned int> core;
+  Option<unsigned int> socket;
+
+  std::string line;
+  while (std::getline(file, line)) {
+    if (line.find("processor") == 0 ||
+        line.find("physical id") == 0 ||
+        line.find("core id") == 0) {
+      // Get out and parse the value.
+      std::vector<std::string> tokens = strings::tokenize(line, ": ");
+      CHECK(tokens.size() >= 2) << stringify(tokens);
+      Try<unsigned int> value = numify<unsigned int>(tokens.back());
+      if (value.isError()) {
+        return Error(value.error());
+      }
+
+      // Now save the value.
+      if (line.find("processor") == 0) {
+        if (id.isSome()) {
+          // The physical id and core id are not present in this case.
+          results.push_back(CPU(id.get(), 0, 0));
+        }
+        id = value.get();
+      } else if (line.find("physical id") == 0) {
+        if (socket.isSome()) {
+          return Error("Unexpected format of /proc/cpuinfo");
+        }
+        socket = value.get();
+      } else if (line.find("core id") == 0) {
+        if (core.isSome()) {
+          return Error("Unexpected format of /proc/cpuinfo");
+        }
+        core = value.get();
+      }
+
+      // And finally create a CPU if we have all the information.
+      if (id.isSome() && core.isSome() && socket.isSome()) {
+        results.push_back(CPU(id.get(), core.get(), socket.get()));
+        id = None();
+        core = None();
+        socket = None();
+      }
+    }
+  }
+
+  // Add the last processor if the physical id and core id were not present.
+  if (id.isSome()) {
+    // The physical id and core id are not present.
+    results.push_back(CPU(id.get(), 0, 0));
+  }
+
+  if (file.fail() && !file.eof()) {
+    file.close();
+    return Error("Failed to read /proc/cpuinfo");
+  }
+
+  file.close();
+
+  return results;
+}
+
+} // namespace proc {
+
+#endif // __PROC_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/protobuf.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/protobuf.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/protobuf.hpp
new file mode 100644
index 0000000..eb79e7b
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/protobuf.hpp
@@ -0,0 +1,159 @@
+#ifndef __STOUT_PROTOBUF_HPP__
+#define __STOUT_PROTOBUF_HPP__
+
+#include <errno.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+
+#include <glog/logging.h>
+
+#include <google/protobuf/message.h>
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+#include <string>
+
+#include <boost/lexical_cast.hpp>
+
+#include "error.hpp"
+#include "none.hpp"
+#include "os.hpp"
+#include "result.hpp"
+#include "try.hpp"
+
+namespace protobuf {
+
+// Write out the given protobuf to the specified file descriptor by
+// first writing out the length of the protobuf followed by the contents.
+// NOTE: On error, this may have written partial data to the file.
+inline Try<Nothing> write(int fd, const google::protobuf::Message& message)
+{
+  if (!message.IsInitialized()) {
+    return Error("Uninitialized protocol buffer");
+  }
+
+  // First write the size of the protobuf.
+  uint32_t size = message.ByteSize();
+  std::string bytes = std::string((char*) &size, sizeof(size));
+
+  Try<Nothing> result = os::write(fd, bytes);
+  if (result.isError()) {
+    return Error("Failed to write size: " + result.error());
+  }
+
+  if (!message.SerializeToFileDescriptor(fd)) {
+    return Error("Failed to write/serialize message");
+  }
+
+  return Nothing();
+}
+
+
+// A wrapper function that wraps the above write with open and closing the file.
+inline Try<Nothing> write(
+    const std::string& path,
+    const google::protobuf::Message& message)
+{
+  Try<int> fd = os::open(
+      path,
+      O_WRONLY | O_CREAT | O_TRUNC,
+      S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
+
+  if (fd.isError()) {
+    return Error("Failed to open file '" + path + "': " + fd.error());
+  }
+
+  Try<Nothing> result = write(fd.get(), message);
+
+  // NOTE: We ignore the return value of close(). This is because users calling
+  // this function are interested in the return value of write(). Also an
+  // unsuccessful close() doesn't affect the write.
+  os::close(fd.get());
+
+  return result;
+}
+
+
+// Read the next protobuf of type T from the file by first reading the "size"
+// followed by the contents (as written by 'write' above).
+template <typename T>
+inline Result<T> read(int fd)
+{
+  // Save the offset so we can re-adjust if something goes wrong.
+  off_t offset = lseek(fd, 0, SEEK_CUR);
+  if (offset == -1) {
+    return ErrnoError("Failed to lseek to SEEK_CUR");
+  }
+
+  uint32_t size;
+  Result<std::string> result = os::read(fd, sizeof(size));
+
+  if (result.isNone()) {
+    return None(); // No more protobufs to read.
+  } else if (result.isError()) {
+    return Error("Failed to read size: " + result.error());
+  }
+
+  // Parse the size from the bytes.
+  memcpy((void*) &size, (void*) result.get().data(), sizeof(size));
+
+  // NOTE: Instead of specifically checking for corruption in 'size', we simply
+  // try to read 'size' bytes. If we hit EOF early, it is an indication of
+  // corruption.
+  result = os::read(fd, size);
+
+  if (result.isNone()) {
+    // Hit EOF unexpectedly. Restore the offset to before the size read.
+    lseek(fd, offset, SEEK_SET);
+    return Error(
+        "Failed to read message of size " + stringify(size) + " bytes: "
+        "hit EOF unexpectedly, possible corruption");
+  } else if (result.isError()) {
+    // Restore the offset to before the size read.
+    lseek(fd, offset, SEEK_SET);
+    return Error("Failed to read message: " + result.error());
+  }
+
+  // Parse the protobuf from the string.
+  T message;
+  google::protobuf::io::ArrayInputStream stream(
+      result.get().data(), result.get().size());
+
+  if (!message.ParseFromZeroCopyStream(&stream)) {
+    // Restore the offset to before the size read.
+    lseek(fd, offset, SEEK_SET);
+    return Error("Failed to deserialize message");
+  }
+
+  return message;
+}
+
+
+// A wrapper function that wraps the above read() with
+// open and closing the file.
+template <typename T>
+inline Result<T> read(const std::string& path)
+{
+  Try<int> fd = os::open(
+      path, O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
+
+  if (fd.isError()) {
+    return Error("Failed to open file '" + path + "': " + fd.error());
+  }
+
+  Result<T> result = read<T>(fd.get());
+
+  // NOTE: We ignore the return value of close(). This is because users calling
+  // this function are interested in the return value of read(). Also an
+  // unsuccessful close() doesn't affect the read.
+  os::close(fd.get());
+
+  return result;
+}
+
+
+} // namespace protobuf {
+
+#endif // __STOUT_PROTOBUF_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/result.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/result.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/result.hpp
new file mode 100644
index 0000000..f918f86
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/result.hpp
@@ -0,0 +1,99 @@
+#ifndef __STOUT_RESULT_HPP__
+#define __STOUT_RESULT_HPP__
+
+#include <assert.h>
+#include <stdlib.h> // For abort.
+
+#include <iostream>
+#include <string>
+
+
+template <typename T>
+class Result
+{
+public:
+  static Result<T> none()
+  {
+    return Result<T>(NONE);
+  }
+
+  static Result<T> some(const T& t)
+  {
+    return Result<T>(SOME, new T(t));
+  }
+
+  static Result<T> error(const std::string& message)
+  {
+    return Result<T>(ERROR, NULL, message);
+  }
+
+  Result(const T& _t) : state(SOME), t(new T(_t)) {}
+
+  Result(const Result<T>& that)
+  {
+    state = that.state;
+    if (that.t != NULL) {
+      t = new T(*that.t);
+    } else {
+      t = NULL;
+    }
+    message = that.message;
+  }
+
+  ~Result()
+  {
+    delete t;
+  }
+
+  Result<T>& operator = (const Result<T>& that)
+  {
+    if (this != &that) {
+      delete t;
+      state = that.state;
+      if (that.t != NULL) {
+        t = new T(*that.t);
+      } else {
+        t = NULL;
+      }
+      message = that.message;
+    }
+
+    return *this;
+  }
+
+  bool isSome() const { return state == SOME; }
+  bool isNone() const { return state == NONE; }
+  bool isError() const { return state == ERROR; }
+
+  T get() const
+  {
+    if (state != SOME) {
+      if (state == ERROR) {
+        std::cerr << "Result::get() but state == ERROR: "
+                  << error() << std::endl;
+      } else if (state == NONE) {
+        std::cerr << "Result::get() but state == NONE" << std::endl;
+      }
+      abort();
+    }
+    return *t;
+  }
+
+  std::string error() const { assert(state == ERROR); return message; }
+
+private:
+  enum State {
+    SOME,
+    NONE,
+    ERROR
+  };
+
+  Result(State _state, T* _t = NULL, const std::string& _message = "")
+    : state(_state), t(_t), message(_message) {}
+
+  State state;
+  T* t;
+  std::string message;
+};
+
+#endif // __STOUT_RESULT_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/stopwatch.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/stopwatch.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/stopwatch.hpp
new file mode 100644
index 0000000..bcff8c6
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/stopwatch.hpp
@@ -0,0 +1,70 @@
+#ifndef __STOUT_STOPWATCH_HPP__
+#define __STOUT_STOPWATCH_HPP__
+
+#include <time.h>
+
+#ifdef __MACH__
+#include <mach/clock.h>
+#include <mach/mach.h>
+#endif // __MACH__
+
+#include <sys/time.h>
+
+#include "duration.hpp"
+
+class Stopwatch
+{
+public:
+  Stopwatch() : running(false) { started.tv_sec = 0; started.tv_nsec = 0; }
+
+  void start()
+  {
+    started = now();
+    running = true;
+  }
+
+  void stop()
+  {
+    stopped = now();
+    running = false;
+  }
+
+  Nanoseconds elapsed()
+  {
+    if (!running) {
+      return Nanoseconds(diff(stopped, started));
+    }
+
+    return Nanoseconds(diff(now(), started));
+  }
+
+private:
+  static timespec now()
+  {
+    timespec ts;
+#ifdef __MACH__
+    // OS X does not have clock_gettime, use clock_get_time.
+    clock_serv_t cclock;
+    mach_timespec_t mts;
+    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
+    clock_get_time(cclock, &mts);
+    mach_port_deallocate(mach_task_self(), cclock);
+    ts.tv_sec = mts.tv_sec;
+    ts.tv_nsec = mts.tv_nsec;
+#else
+    clock_gettime(CLOCK_REALTIME, &ts);
+#endif // __MACH__
+    return ts;
+  }
+
+  static uint64_t diff(const timespec& from, const timespec& to)
+  {
+    return ((from.tv_sec - to.tv_sec) * 1000000000LL)
+      + (from.tv_nsec - to.tv_nsec);
+  }
+
+  bool running;
+  timespec started, stopped;
+};
+
+#endif // __STOUT_STOPWATCH_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/stringify.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/stringify.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/stringify.hpp
new file mode 100644
index 0000000..136316d
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/stringify.hpp
@@ -0,0 +1,124 @@
+#ifndef __STOUT_STRINGIFY_HPP__
+#define __STOUT_STRINGIFY_HPP__
+
+#include <stdlib.h> // For 'abort'.
+
+#include <iostream> // For 'std::cerr' and 'std::endl'.
+#include <list>
+#include <map>
+#include <set>
+#include <sstream> // For 'std::ostringstream'.
+#include <string>
+#include <vector>
+
+#include "hashmap.hpp"
+
+template <typename T>
+std::string stringify(T t)
+{
+  std::ostringstream out;
+  out << t;
+  if (!out.good()) {
+    std::cerr << "Failed to stringify!" << t << std::endl;
+    abort();
+  }
+  return out.str();
+}
+
+
+template <>
+inline std::string stringify(bool b)
+{
+  return b ? "true" : "false";
+}
+
+
+template <typename T>
+std::string stringify(const std::set<T>& set)
+{
+  std::ostringstream out;
+  out << "{ ";
+  typename std::set<T>::const_iterator iterator = set.begin();
+  while (iterator != set.end()) {
+    out << stringify(*iterator);
+    if (++iterator != set.end()) {
+      out << ", ";
+    }
+  }
+  out << " }";
+  return out.str();
+}
+
+
+template <typename T>
+std::string stringify(const std::list<T>& list)
+{
+  std::ostringstream out;
+  out << "[ ";
+  typename std::list<T>::const_iterator iterator = list.begin();
+  while (iterator != list.end()) {
+    out << stringify(*iterator);
+    if (++iterator != list.end()) {
+      out << ", ";
+    }
+  }
+  out << " ]";
+  return out.str();
+}
+
+
+template <typename T>
+std::string stringify(const std::vector<T>& vector)
+{
+  std::ostringstream out;
+  out << "[ ";
+  typename std::vector<T>::const_iterator iterator = vector.begin();
+  while (iterator != vector.end()) {
+    out << stringify(*iterator);
+    if (++iterator != vector.end()) {
+      out << ", ";
+    }
+  }
+  out << " ]";
+  return out.str();
+}
+
+
+template <typename K, typename V>
+std::string stringify(const std::map<K, V>& map)
+{
+  std::ostringstream out;
+  out << "{ ";
+  typename std::map<K, V>::const_iterator iterator = map.begin();
+  while (iterator != map.end()) {
+    out << stringify(iterator->first);
+    out << ": ";
+    out << stringify(iterator->second);
+    if (++iterator != map.end()) {
+      out << ", ";
+    }
+  }
+  out << " }";
+  return out.str();
+}
+
+
+template <typename K, typename V>
+std::string stringify(const hashmap<K, V>& map)
+{
+  std::ostringstream out;
+  out << "{ ";
+  typename hashmap<K, V>::const_iterator iterator = map.begin();
+  while (iterator != map.end()) {
+    out << stringify(iterator->first);
+    out << ": ";
+    out << stringify(iterator->second);
+    if (++iterator != map.end()) {
+      out << ", ";
+    }
+  }
+  out << " }";
+  return out.str();
+}
+
+#endif // __STOUT_STRINGIFY_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/strings.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/strings.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/strings.hpp
new file mode 100644
index 0000000..ed14106
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/strings.hpp
@@ -0,0 +1,263 @@
+#ifndef __STOUT_STRINGS_HPP__
+#define __STOUT_STRINGS_HPP__
+
+#include <algorithm>
+#include <string>
+#include <map>
+#include <vector>
+
+#include "foreach.hpp"
+#include "format.hpp"
+#include "stringify.hpp"
+
+namespace strings {
+
+// Flags indicating how remove should operate.
+enum Mode {
+  PREFIX,
+  SUFFIX,
+  ANY
+};
+
+
+inline std::string remove(
+    const std::string& from,
+    const std::string& substring,
+    Mode mode = ANY)
+{
+  std::string result = from;
+
+  if (mode == PREFIX) {
+    if (from.find(substring) == 0) {
+      result = from.substr(substring.size());
+    }
+  } else if (mode == SUFFIX) {
+    if (from.rfind(substring) == from.size() - substring.size()) {
+      result = from.substr(0, from.size() - substring.size());
+    }
+  } else {
+    size_t index;
+    while ((index = result.find(substring)) != std::string::npos) {
+      result = result.erase(index, substring.size());
+    }
+  }
+
+  return result;
+}
+
+
+inline std::string trim(
+    const std::string& from,
+    const std::string& chars = " \t\n\r")
+{
+  size_t start = from.find_first_not_of(chars);
+  size_t end = from.find_last_not_of(chars);
+  if (start == std::string::npos) { // Contains only characters in chars.
+    return "";
+  }
+
+  return from.substr(start, end + 1 - start);
+}
+
+
+// Replaces all the occurrences of the 'from' string with the 'to' string.
+inline std::string replace(
+    const std::string& s,
+    const std::string& from,
+    const std::string& to)
+{
+  std::string result = s;
+  size_t index = 0;
+
+  if (from.empty()) {
+    return result;
+  }
+
+  while ((index = result.find(from, index)) != std::string::npos) {
+    result.replace(index, from.length(), to);
+    index += to.length();
+  }
+  return result;
+}
+
+
+// Tokenizes the string using the delimiters.
+// Empty tokens will not be included in the result.
+inline std::vector<std::string> tokenize(
+    const std::string& s,
+    const std::string& delims)
+{
+  size_t offset = 0;
+  std::vector<std::string> tokens;
+
+  while (true) {
+    size_t i = s.find_first_not_of(delims, offset);
+    if (std::string::npos == i) {
+      offset = s.length();
+      return tokens;
+    }
+
+    size_t j = s.find_first_of(delims, i);
+    if (std::string::npos == j) {
+      tokens.push_back(s.substr(i));
+      offset = s.length();
+      continue;
+    }
+
+    tokens.push_back(s.substr(i, j - i));
+    offset = j;
+  }
+  return tokens;
+}
+
+
+// Splits the string using the provided delimiters.
+// Empty tokens are allowed in the result.
+inline std::vector<std::string> split(
+    const std::string& s,
+    const std::string& delims)
+{
+  std::vector<std::string> tokens;
+  size_t offset = 0;
+  size_t next = 0;
+
+  while (true) {
+    next = s.find_first_of(delims, offset);
+    if (next == std::string::npos) {
+      tokens.push_back(s.substr(offset));
+      break;
+    }
+
+    tokens.push_back(s.substr(offset, next - offset));
+    offset = next + 1;
+  }
+  return tokens;
+}
+
+
+// Returns a map of strings to strings based on calling tokenize
+// twice. All non-pairs are discarded. For example:
+//
+//   pairs("foo=1;bar=2;baz;foo=3;bam=1=2", ";&", "=")
+//
+// Would return a map with the following:
+//   bar: ["2"]
+//   foo: ["1", "3"]
+inline std::map<std::string, std::vector<std::string> > pairs(
+    const std::string& s,
+    const std::string& delims1,
+    const std::string& delims2)
+{
+  std::map<std::string, std::vector<std::string> > result;
+
+  const std::vector<std::string>& tokens = tokenize(s, delims1);
+  foreach (const std::string& token, tokens) {
+    const std::vector<std::string>& pairs = tokenize(token, delims2);
+    if (pairs.size() == 2) {
+      result[pairs[0]].push_back(pairs[1]);
+    }
+  }
+
+  return result;
+}
+
+
+inline std::string join(const std::string& separator,
+                        const std::string& s1,
+                        const std::string& s2)
+{
+  return s1 + separator + s2;
+}
+
+
+inline std::string join(const std::string& separator,
+                        const std::string& s1,
+                        const std::string& s2,
+                        const std::string& s3)
+{
+  return s1 + separator + s2 + separator + s3;
+}
+
+
+inline std::string join(const std::string& separator,
+                        const std::string& s1,
+                        const std::string& s2,
+                        const std::string& s4,
+                        const std::string& s3)
+{
+  return s1 + separator + s2 + separator + s3 + separator + s4;
+}
+
+
+// Use duck-typing to join any iterable.
+template <typename Iterable>
+inline std::string join(const std::string& separator, const Iterable& i)
+{
+  std::string result;
+  typename Iterable::const_iterator iterator = i.begin();
+  while (iterator != i.end()) {
+    result += stringify(*iterator);
+    if (++iterator != i.end()) {
+      result += separator;
+    }
+  }
+  return result;
+}
+
+
+inline bool checkBracketsMatching(
+    const std::string& s,
+    const char openBracket,
+    const char closeBracket)
+{
+  int count = 0;
+  for (size_t i = 0; i < s.length(); i++) {
+    if (s[i] == openBracket) {
+      count++;
+    } else if (s[i] == closeBracket) {
+      count--;
+    }
+    if (count < 0) {
+      return false;
+    }
+  }
+  return count == 0;
+}
+
+
+inline bool startsWith(const std::string& s, const std::string& prefix)
+{
+  return s.find(prefix) == 0;
+}
+
+
+inline bool endsWith(const std::string& s, const std::string& suffix)
+{
+  return s.rfind(suffix) == s.length() - suffix.length();
+}
+
+
+inline bool contains(const std::string& s, const std::string& substr)
+{
+  return s.find(substr) != std::string::npos;
+}
+
+
+inline std::string lower(const std::string& s)
+{
+  std::string result = s;
+  std::transform(result.begin(), result.end(), result.begin(), ::tolower);
+  return result;
+}
+
+
+inline std::string upper(const std::string& s)
+{
+  std::string result = s;
+  std::transform(result.begin(), result.end(), result.begin(), ::toupper);
+  return result;
+}
+
+} // namespaces strings {
+
+#endif // __STOUT_STRINGS_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp
new file mode 100644
index 0000000..787bffd
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/try.hpp
@@ -0,0 +1,88 @@
+#ifndef __STOUT_TRY_HPP__
+#define __STOUT_TRY_HPP__
+
+#include <assert.h>
+#include <stdlib.h> // For abort.
+
+#include <iostream>
+#include <string>
+
+
+template <typename T>
+class Try
+{
+public:
+  static Try<T> some(const T& t)
+  {
+    return Try<T>(SOME, new T(t));
+  }
+
+  static Try<T> error(const std::string& message)
+  {
+    return Try<T>(ERROR, NULL, message);
+  }
+
+  Try(const T& _t) : state(SOME), t(new T(_t)) {}
+
+  Try(const Try<T>& that)
+  {
+    state = that.state;
+    if (that.t != NULL) {
+      t = new T(*that.t);
+    } else {
+      t = NULL;
+    }
+    message = that.message;
+  }
+
+  ~Try()
+  {
+    delete t;
+  }
+
+  Try<T>& operator = (const Try<T>& that)
+  {
+    if (this != &that) {
+      delete t;
+      state = that.state;
+      if (that.t != NULL) {
+        t = new T(*that.t);
+      } else {
+        t = NULL;
+      }
+      message = that.message;
+    }
+
+    return *this;
+  }
+
+  bool isSome() const { return state == SOME; }
+  bool isError() const { return state == ERROR; }
+
+  T get() const
+  {
+    if (state != SOME) {
+      std::cerr << "Try::get() but state == ERROR: " << error() << std::endl;
+      abort();
+    }
+    return *t;
+  }
+
+  std::string error() const { assert(state == ERROR); return message; }
+
+private:
+  enum State {
+    SOME,
+    ERROR
+  };
+
+  Try(State _state, T* _t = NULL, const std::string& _message = "")
+    : state(_state), t(_t), message(_message) {}
+
+  State state;
+  T* t;
+  std::string message;
+};
+
+
+#endif // __STOUT_TRY_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/utils.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/utils.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/utils.hpp
new file mode 100644
index 0000000..0f4bba2
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/utils.hpp
@@ -0,0 +1,11 @@
+#ifndef __STOUT_UTILS_HPP__
+#define __STOUT_UTILS_HPP__
+
+namespace utils {
+
+template <typename T>
+T copy(const T& t) { return t; }
+
+} // namespace utils {
+
+#endif // __STOUT_UTILS_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/uuid.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/uuid.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/uuid.hpp
new file mode 100644
index 0000000..c6c290d
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/uuid.hpp
@@ -0,0 +1,54 @@
+#ifndef __STOUT_UUID_HPP__
+#define __STOUT_UUID_HPP__
+
+#include <assert.h>
+
+#include <sstream>
+#include <string>
+
+#include <boost/uuid/uuid.hpp>
+#include <boost/uuid/uuid_io.hpp>
+#include <boost/uuid/uuid_generators.hpp>
+
+struct UUID : boost::uuids::uuid
+{
+public:
+  static UUID random()
+  {
+    return UUID(boost::uuids::random_generator()());
+  }
+
+  static UUID fromBytes(const std::string& s)
+  {
+    boost::uuids::uuid uuid;
+    memcpy(&uuid, s.data(), s.size());
+    return UUID(uuid);
+  }
+
+  static UUID fromString(const std::string& s)
+  {
+    boost::uuids::uuid uuid;
+    std::istringstream in(s);
+    in >> uuid;
+    return UUID(uuid);
+  }
+
+  std::string toBytes() const
+  {
+    assert(sizeof(data) == size());
+    return std::string(reinterpret_cast<const char*>(data), sizeof(data));
+  }
+
+  std::string toString() const
+  {
+    std::ostringstream out;
+    out << *this;
+    return out.str();
+  }
+
+private:
+  explicit UUID(const boost::uuids::uuid& uuid)
+    : boost::uuids::uuid(uuid) {}
+};
+
+#endif // __STOUT_UUID_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/install-sh
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/install-sh b/3rdparty/libprocess/3rdparty/stout/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/m4/acx_pthread.m4
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/m4/acx_pthread.m4 b/3rdparty/libprocess/3rdparty/stout/m4/acx_pthread.m4
new file mode 100644
index 0000000..2cf20de
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/m4/acx_pthread.m4
@@ -0,0 +1,363 @@
+# This was retrieved from
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
+# See also (perhaps for new versions?)
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
+#
+# We've rewritten the inconsistency check code (from avahi), to work
+# more broadly.  In particular, it no longer assumes ld accepts -zdefs.
+# This caused a restructing of the code, but the functionality has only
+# changed a little.
+
+dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl
+dnl @summary figure out how to build C programs using POSIX threads
+dnl
+dnl This macro figures out how to build C programs using POSIX threads.
+dnl It sets the PTHREAD_LIBS output variable to the threads library and
+dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
+dnl C compiler flags that are needed. (The user can also force certain
+dnl compiler flags/libs to be tested by setting these environment
+dnl variables.)
+dnl
+dnl Also sets PTHREAD_CC to any special C compiler that is needed for
+dnl multi-threaded programs (defaults to the value of CC otherwise).
+dnl (This is necessary on AIX to use the special cc_r compiler alias.)
+dnl
+dnl NOTE: You are assumed to not only compile your program with these
+dnl flags, but also link it with them as well. e.g. you should link
+dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
+dnl $LIBS
+dnl
+dnl If you are only building threads programs, you may wish to use
+dnl these variables in your default LIBS, CFLAGS, and CC:
+dnl
+dnl        LIBS="$PTHREAD_LIBS $LIBS"
+dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+dnl        CC="$PTHREAD_CC"
+dnl
+dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
+dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
+dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+dnl
+dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
+dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
+dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
+dnl default action will define HAVE_PTHREAD.
+dnl
+dnl Please let the authors know if this macro fails on any platform, or
+dnl if you have any other suggestions or comments. This macro was based
+dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
+dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
+dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
+dnl We are also grateful for the helpful feedback of numerous users.
+dnl
+dnl @category InstalledPackages
+dnl @author Steven G. Johnson <st...@alum.mit.edu>
+dnl @version 2006-05-29
+dnl @license GPLWithACException
+dnl 
+dnl Checks for GCC shared/pthread inconsistency based on work by
+dnl Marcin Owsiany <ma...@owsiany.pl>
+
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_TRY_LINK([#include <pthread.h>],
+                    [pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+                    [acx_pthread_ok=yes])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	AC_MSG_CHECKING([for joinable pthread attribute])
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+                        [attr_name=$attr; break])
+	done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+	fi
+
+	# The next part tries to detect GCC inconsistency with -shared on some
+	# architectures and systems. The problem is that in certain
+	# configurations, when -shared is specified, GCC "forgets" to
+	# internally use various flags which are still necessary.
+	
+	#
+	# Prepare the flags
+	#
+	save_CFLAGS="$CFLAGS"
+	save_LIBS="$LIBS"
+	save_CC="$CC"
+	
+	# Try with the flags determined by the earlier checks.
+	#
+	# -Wl,-z,defs forces link-time symbol resolution, so that the
+	# linking checks with -shared actually have any value
+	#
+	# FIXME: -fPIC is required for -shared on many architectures,
+	# so we specify it here, but the right way would probably be to
+	# properly detect whether it is actually required.
+	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	CC="$PTHREAD_CC"
+	
+	# In order not to create several levels of indentation, we test
+	# the value of "$done" until we find the cure or run out of ideas.
+	done="no"
+	
+	# First, make sure the CFLAGS we added are actually accepted by our
+	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
+	# then we can't do this test.
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
+	   AC_TRY_LINK(,, , [done=yes])
+	
+	   if test "x$done" = xyes ; then
+	      AC_MSG_RESULT([no])
+	   else
+	      AC_MSG_RESULT([yes])
+	   fi
+	fi
+	
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	   
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	
+	#
+	# Linux gcc on some architectures such as mips/mipsel forgets
+	# about -lpthread
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lpthread fixes that])
+	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	#
+	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lc_r fixes that])
+	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	       [pthread_t th; pthread_join(th, 0);
+	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	        pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	       [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	if test x"$done" = xno; then
+	   # OK, we have run out of ideas
+	   AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
+	
+	   # so it's not safe to assume that we may use pthreads
+	   acx_pthread_ok=no
+	fi
+	
+	CFLAGS="$save_CFLAGS"
+	LIBS="$save_LIBS"
+	CC="$save_CC"
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        acx_pthread_ok=no
+        $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/bytes_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/bytes_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/bytes_tests.cpp
new file mode 100644
index 0000000..18b2474
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/bytes_tests.cpp
@@ -0,0 +1,38 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <stout/bytes.hpp>
+#include <stout/gtest.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+
+TEST(Stout, Bytes)
+{
+  Try<Bytes> _1terabyte = Bytes::parse("1TB");
+
+  EXPECT_SOME_EQ(Terabytes(1), _1terabyte);
+  EXPECT_SOME_EQ(Gigabytes(1024), _1terabyte);
+  EXPECT_SOME_EQ(Megabytes(1024 * 1024), _1terabyte);
+  EXPECT_SOME_EQ(Kilobytes(1024 * 1024 * 1024), _1terabyte);
+  EXPECT_SOME_EQ(Bytes(1024LLU * 1024 * 1024 * 1024), _1terabyte);
+
+  EXPECT_EQ(Bytes(1024), Kilobytes(1));
+  EXPECT_LT(Bytes(1023), Kilobytes(1));
+  EXPECT_GT(Bytes(1025), Kilobytes(1));
+
+  EXPECT_NE(Megabytes(1023), Gigabytes(1));
+
+  EXPECT_EQ("0B", stringify(Bytes()));
+
+  EXPECT_EQ("1KB", stringify(Kilobytes(1)));
+  EXPECT_EQ("1MB", stringify(Megabytes(1)));
+  EXPECT_EQ("1GB", stringify(Gigabytes(1)));
+  EXPECT_EQ("1TB", stringify(Terabytes(1)));
+
+  EXPECT_EQ("1023B", stringify(Bytes(1023)));
+  EXPECT_EQ("1023KB", stringify(Kilobytes(1023)));
+  EXPECT_EQ("1023MB", stringify(Megabytes(1023)));
+  EXPECT_EQ("1023GB", stringify(Gigabytes(1023)));
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/duration_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/duration_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/duration_tests.cpp
new file mode 100644
index 0000000..e0910d4
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/duration_tests.cpp
@@ -0,0 +1,82 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <stout/duration.hpp>
+#include <stout/gtest.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+
+TEST(DurationTest, Comparison)
+{
+  EXPECT_EQ(Duration::zero(), Seconds(0));
+  EXPECT_EQ(Minutes(180), Hours(3));
+  EXPECT_EQ(Seconds(10800), Hours(3));
+  EXPECT_EQ(Milliseconds(10800000), Hours(3));
+
+  EXPECT_EQ(Milliseconds(1), Microseconds(1000));
+  EXPECT_EQ(Milliseconds(1000), Seconds(1));
+
+  EXPECT_GT(Weeks(1), Days(6));
+
+  EXPECT_LT(Hours(23), Days(1));
+
+  EXPECT_LE(Hours(24), Days(1));
+  EXPECT_GE(Hours(24), Days(1));
+
+  EXPECT_NE(Minutes(59), Hours(1));
+
+  // Maintains precision for a 100 year duration.
+  EXPECT_GT(Weeks(5217) + Nanoseconds(1), Weeks(5217));
+  EXPECT_LT(Weeks(5217) - Nanoseconds(1), Weeks(5217));
+}
+
+TEST(DurationTest, ParseAndTry)
+{
+  EXPECT_SOME_EQ(Hours(3), Duration::parse("3hrs"));
+  EXPECT_SOME_EQ(Hours(3) + Minutes(30), Duration::parse("3.5hrs"));
+
+  EXPECT_SOME_EQ(Nanoseconds(3141592653), Duration::create(3.141592653));
+  // Duration can hold only 9.22337e9 seconds.
+  EXPECT_ERROR(Duration::create(10 * 1e9));
+}
+
+TEST(DurationTest, Arithmetic)
+{
+  Duration d = Seconds(11);
+  d += Seconds(9);
+  EXPECT_EQ(Seconds(20), d);
+
+  d = Seconds(11);
+  d -= Seconds(21);
+  EXPECT_EQ(Seconds(-10), d);
+
+  d = Seconds(10);
+  d *= 2;
+  EXPECT_EQ(Seconds(20), d);
+
+  d = Seconds(10);
+  d /= 2.5;
+  EXPECT_EQ(Seconds(4), d);
+
+  EXPECT_EQ(Seconds(20), Seconds(11) + Seconds(9));
+  EXPECT_EQ(Seconds(-10), Seconds(11) - Seconds(21));
+  EXPECT_EQ(Duration::create(3.3).get(), Seconds(10) * 0.33);
+  EXPECT_EQ(Duration::create(1.25).get(), Seconds(10) / 8);
+
+  EXPECT_EQ(Duration::create(Days(11).secs() + 9).get(), Days(11) + Seconds(9));
+}
+
+
+TEST(DurationTest, OutputFormat)
+{
+  // Truncated. Seconds in 15 digits of precision, max of double
+  // type's precise digits.
+  EXPECT_EQ("3.141592653secs",
+            stringify(Duration::create(3.14159265358979).get()));
+  EXPECT_EQ("3.14secs", stringify(Duration::create(3.14).get()));
+  EXPECT_EQ("10hrs", stringify(Hours(10)));
+  // This is the current expected way how it should be printed out.
+  EXPECT_EQ("1.42857142857143weeks", stringify(Days(10)));
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/error_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/error_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/error_tests.cpp
new file mode 100644
index 0000000..75e365e
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/error_tests.cpp
@@ -0,0 +1,60 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+#include <stout/try.hpp>
+
+using std::string;
+
+
+Error error1()
+{
+  return Error("Failed to ...");
+}
+
+
+Try<string> error2()
+{
+  return Error("Failed to ...");
+}
+
+
+Try<string> error3(const Try<string>& t)
+{
+  return t;
+}
+
+
+Result<string> error4()
+{
+  return Error("Failed to ...");
+}
+
+
+Result<string> error5(const Result<string>& r)
+{
+  return r;
+}
+
+
+TEST(ErrorTest, Test)
+{
+  Try<string> t = error1();
+  EXPECT_TRUE(t.isError());
+  t = error2();
+  EXPECT_TRUE(t.isError());
+  t = error3(error1());
+  EXPECT_TRUE(t.isError());
+
+  Result<string> r = error1();
+  EXPECT_TRUE(r.isError());
+  r = error4();
+  EXPECT_TRUE(r.isError());
+  r = error5(error1());
+  EXPECT_TRUE(r.isError());
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp
new file mode 100644
index 0000000..2809280
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp
@@ -0,0 +1,349 @@
+#include <gmock/gmock.h>
+
+#include <map>
+#include <string>
+
+#include <stout/duration.hpp>
+#include <stout/flags.hpp>
+#include <stout/gtest.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/os.hpp>
+
+
+using namespace flags;
+
+class TestFlags : public virtual FlagsBase
+{
+public:
+  TestFlags()
+  {
+    add(&TestFlags::name1,
+        "name1",
+        "Set name1",
+        "ben folds");
+
+    add(&TestFlags::name2,
+        "name2",
+        "Set name2",
+        42);
+
+    add(&TestFlags::name3,
+        "name3",
+        "Set name3",
+        false);
+
+    add(&TestFlags::name4,
+        "name4",
+        "Set name4");
+
+    add(&TestFlags::name5,
+        "name5",
+        "Set name5");
+  }
+
+  std::string name1;
+  int name2;
+  bool name3;
+  Option<bool> name4;
+  Option<bool> name5;
+};
+
+
+TEST(FlagsTest, Load)
+{
+  TestFlags flags;
+
+  std::map<std::string, Option<std::string> > values;
+
+  values["name1"] = Option<std::string>::some("billy joel");
+  values["name2"] = Option<std::string>::some("43");
+  values["name3"] = Option<std::string>::some("false");
+  values["no-name4"] = None();
+  values["name5"] = None();
+
+  flags.load(values);
+
+  EXPECT_EQ("billy joel", flags.name1);
+  EXPECT_EQ(43, flags.name2);
+  EXPECT_FALSE(flags.name3);
+  ASSERT_SOME(flags.name4);
+  EXPECT_FALSE(flags.name4.get());
+  ASSERT_SOME(flags.name5);
+  EXPECT_TRUE(flags.name5.get());
+}
+
+
+TEST(FlagsTest, Add)
+{
+  Flags<TestFlags> flags;
+
+  Option<std::string> name6;
+
+  flags.add(&name6,
+            "name6",
+            "Also set name6");
+
+  bool name7;
+
+  flags.add(&name7,
+            "name7",
+            "Also set name7",
+            true);
+
+  Option<std::string> name8;
+
+  flags.add(&name8,
+            "name8",
+            "Also set name8");
+
+  std::map<std::string, Option<std::string> > values;
+
+  values["name6"] = Option<std::string>::some("ben folds");
+  values["no-name7"] = None();
+
+  flags.load(values);
+
+  ASSERT_SOME(name6);
+  EXPECT_EQ("ben folds", name6.get());
+
+  EXPECT_FALSE(name7);
+
+  ASSERT_TRUE(name8.isNone());
+}
+
+
+TEST(FlagsTest, Flags)
+{
+  TestFlags flags;
+
+  std::map<std::string, Option<std::string> > values;
+
+  values["name1"] = Option<std::string>::some("billy joel");
+  values["name2"] = Option<std::string>::some("43");
+  values["name3"] = Option<std::string>::some("false");
+  values["no-name4"] = None();
+  values["name5"] = None();
+
+  flags.load(values);
+
+  EXPECT_EQ("billy joel", flags.name1);
+  EXPECT_EQ(43, flags.name2);
+  EXPECT_FALSE(flags.name3);
+  ASSERT_SOME(flags.name4);
+  EXPECT_FALSE(flags.name4.get());
+  ASSERT_SOME(flags.name5);
+  EXPECT_TRUE(flags.name5.get());
+}
+
+
+TEST(FlagsTest, LoadFromEnvironment)
+{
+  TestFlags flags;
+
+  os::setenv("FLAGSTEST_name1", "billy joel");
+  os::setenv("FLAGSTEST_name2", "43");
+  os::setenv("FLAGSTEST_no-name3", "");
+  os::setenv("FLAGSTEST_no-name4", "");
+  os::setenv("FLAGSTEST_name5", "");
+
+  Try<Nothing> load = flags.load("FLAGSTEST_");
+  EXPECT_SOME(load);
+
+  EXPECT_EQ("billy joel", flags.name1);
+  EXPECT_EQ(43, flags.name2);
+  EXPECT_FALSE(flags.name3);
+  ASSERT_SOME(flags.name4);
+  EXPECT_FALSE(flags.name4.get());
+  ASSERT_SOME(flags.name5);
+  EXPECT_TRUE(flags.name5.get());
+
+  os::unsetenv("FLAGSTEST_name1");
+  os::unsetenv("FLAGSTEST_name2");
+  os::unsetenv("FLAGSTEST_no-name3");
+  os::unsetenv("FLAGSTEST_no-name4");
+  os::unsetenv("FLAGSTEST_name5");
+}
+
+
+TEST(FlagsTest, LoadFromCommandLine)
+{
+  TestFlags flags;
+
+  int argc = 6;
+  char* argv[argc];
+
+  argv[0] = (char*) "/path/to/program";
+  argv[1] = (char*) "--name1=billy joel";
+  argv[2] = (char*) "--name2=43";
+  argv[3] = (char*) "--no-name3";
+  argv[4] = (char*) "--no-name4";
+  argv[5] = (char*) "--name5";
+
+  Try<Nothing> load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_SOME(load);
+
+  EXPECT_EQ("billy joel", flags.name1);
+  EXPECT_EQ(43, flags.name2);
+  EXPECT_FALSE(flags.name3);
+  ASSERT_SOME(flags.name4);
+  EXPECT_FALSE(flags.name4.get());
+  ASSERT_SOME(flags.name5);
+  EXPECT_TRUE(flags.name5.get());
+}
+
+
+TEST(FlagsTest, DuplicatesFromEnvironment)
+{
+  TestFlags flags;
+
+  os::setenv("FLAGSTEST_name1", "ben folds");
+
+  int argc = 2;
+  char* argv[argc];
+
+  argv[0] = (char*) "/path/to/program";
+  argv[1] = (char*) "--name1=billy joel";
+
+  Try<Nothing> load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Duplicate flag 'name1' on command line", load.error());
+
+  os::unsetenv("FLAGSTEST_name1");
+}
+
+
+TEST(FlagsTest, DuplicatesFromCommandLine)
+{
+  TestFlags flags;
+
+  int argc = 3;
+  char* argv[argc];
+
+  argv[0] = (char*) "/path/to/program";
+  argv[1] = (char*) "--name1=billy joel";
+  argv[2] = (char*) "--name1=ben folds";
+
+  Try<Nothing> load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Duplicate flag 'name1' on command line", load.error());
+}
+
+
+TEST(FlagsTest, Errors)
+{
+  TestFlags flags;
+
+  int argc = 2;
+  char* argv[argc];
+
+  argv[0] = (char*) "/path/to/program";
+
+  // Test an unknown flag.
+  argv[1] = (char*) "--foo";
+
+  Try<Nothing> load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Failed to load unknown flag 'foo'", load.error());
+
+  // Now try an unknown flag with a value.
+  argv[1] = (char*) "--foo=value";
+
+  load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Failed to load unknown flag 'foo'", load.error());
+
+  // Now try an unknown flag with a 'no-' prefix.
+  argv[1] = (char*) "--no-foo";
+
+  load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Failed to load unknown flag 'foo' via 'no-foo'", load.error());
+
+  // Now test a boolean flag using the 'no-' prefix _and_ a value.
+  argv[1] = (char*) "--no-name3=value";
+
+  load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Failed to load boolean flag 'name3' via "
+            "'no-name3' with value 'value'", load.error());
+
+  // Now test a boolean flag that couldn't be parsed.
+  argv[1] = (char*) "--name3=value";
+
+  load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Failed to load flag 'name3': Failed to load value 'value': "
+            "Expecting a boolean (e.g., true or false)", load.error());
+
+  // Now test a non-boolean flag without a value.
+  argv[1] = (char*) "--name1";
+
+  load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Failed to load non-boolean flag 'name1': "
+            "Missing value", load.error());
+
+  // Now test a non-boolean flag using the 'no-' prefix.
+  argv[1] = (char*) "--no-name2";
+
+  load = flags.load("FLAGSTEST_", argc, argv);
+  EXPECT_ERROR(load);
+
+  EXPECT_EQ("Failed to load non-boolean flag 'name2' "
+            "via 'no-name2'", load.error());
+}
+
+
+TEST(FlagsTest, Usage)
+{
+  TestFlags flags;
+
+  EXPECT_EQ(
+      "  --name1=VALUE     Set name1 (default: ben folds)\n"
+      "  --name2=VALUE     Set name2 (default: 42)\n"
+      "  --[no-]name3      Set name3 (default: false)\n"
+      "  --[no-]name4      Set name4\n"
+      "  --[no-]name5      Set name5\n",
+      flags.usage());
+}
+
+
+TEST(FlagsTest, Duration)
+{
+  Flags<TestFlags> flags;
+
+  Duration name6;
+
+  flags.add(&name6,
+            "name6",
+            "Amount of time",
+            Milliseconds(100));
+
+  Option<Duration> name7;
+
+  flags.add(&name7,
+            "name7",
+            "Also some amount of time");
+
+  std::map<std::string, Option<std::string> > values;
+
+  values["name6"] = Option<std::string>::some("2mins");
+  values["name7"] = Option<std::string>::some("3hrs");
+
+  flags.load(values);
+
+  EXPECT_EQ(Minutes(2), name6);
+
+  ASSERT_SOME(name7);
+  EXPECT_EQ(Hours(3), name7.get());
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/gzip_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/gzip_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/gzip_tests.cpp
new file mode 100644
index 0000000..13296d8
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/gzip_tests.cpp
@@ -0,0 +1,53 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include <stout/gtest.hpp>
+#include <stout/gzip.hpp>
+
+using std::string;
+
+
+#ifdef HAVE_LIBZ
+TEST(GzipTest, CompressDecompressString)
+{
+  // Test bad compression levels, outside of [-1, Z_BEST_COMPRESSION].
+  ASSERT_ERROR(gzip::compress("", -2));
+  ASSERT_ERROR(gzip::compress("", Z_BEST_COMPRESSION + 1));
+
+  string s =
+    "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
+    "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad "
+    "minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
+    "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit "
+    "in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
+    "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui "
+    "officia deserunt mollit anim id est laborum.";
+
+  Try<string> compressed = gzip::compress(s);
+  ASSERT_SOME(compressed);
+  Try<string> decompressed = gzip::decompress(compressed.get());
+  ASSERT_SOME(decompressed);
+  ASSERT_EQ(s, decompressed.get());
+
+  // Test with a 1MB random string!
+  s = "";
+  while (s.length() < (1024 * 1024)) {
+    s.append(1, ' ' + (rand() % ('~' - ' ')));
+  }
+  compressed = gzip::compress(s);
+  ASSERT_SOME(compressed);
+  decompressed = gzip::decompress(compressed.get());
+  ASSERT_SOME(decompressed);
+  ASSERT_EQ(s, decompressed.get());
+
+  s = "";
+  compressed = gzip::compress(s);
+  ASSERT_SOME(compressed);
+  decompressed = gzip::decompress(compressed.get());
+  ASSERT_SOME(decompressed);
+  ASSERT_EQ(s, decompressed.get());
+}
+#endif // HAVE_LIBZ

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/hashset_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/hashset_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/hashset_tests.cpp
new file mode 100644
index 0000000..72f65c4
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/hashset_tests.cpp
@@ -0,0 +1,25 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include <stout/hashset.hpp>
+
+using std::string;
+
+
+TEST(HashsetTest, Insert)
+{
+  hashset<string> hs1;
+  hs1.insert(string("HS1"));
+  hs1.insert(string("HS3"));
+
+  hashset<string> hs2;
+  hs2.insert(string("HS2"));
+
+  hs1 = hs2;
+  ASSERT_EQ(1u, hs1.size());
+  ASSERT_TRUE(hs1.contains("HS2"));
+  ASSERT_TRUE(hs1 == hs2);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp
new file mode 100644
index 0000000..c582d70
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/json_tests.cpp
@@ -0,0 +1,19 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include <stout/json.hpp>
+#include <stout/stringify.hpp>
+
+using std::string;
+
+
+TEST(JsonTest, BinaryData)
+{
+  JSON::String s(string("\"\\/\b\f\n\r\t\x00\x19 !#[]\x7F\xFF", 17));
+
+  EXPECT_EQ("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\\u0000\\u0019 !#[]\\u007F\\u00FF\"",
+            stringify(s));
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/main.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/main.cpp b/3rdparty/libprocess/3rdparty/stout/tests/main.cpp
new file mode 100644
index 0000000..0f1e9cb
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/main.cpp
@@ -0,0 +1,11 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+int main(int argc, char** argv)
+{
+  // Initialize Google Mock/Test.
+  testing::InitGoogleMock(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp
new file mode 100644
index 0000000..79e7200
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp
@@ -0,0 +1,168 @@
+#include <stdint.h>
+
+#include <gtest/gtest.h>
+
+#include <set>
+#include <string>
+
+#include <stout/foreach.hpp>
+#include <stout/multimap.hpp>
+#include <stout/multihashmap.hpp>
+
+using std::set;
+using std::string;
+
+template <typename T>
+class MultimapTest : public ::testing::Test {};
+
+typedef ::testing::Types<
+  Multimap<string, uint16_t>, multihashmap<string, uint16_t> > MultimapTypes;
+
+// Causes all TYPED_TEST(MultimapTest, ...) to be run for each of the
+// specified multimap types.
+TYPED_TEST_CASE(MultimapTest, MultimapTypes);
+
+
+TYPED_TEST(MultimapTest, Put)
+{
+  typedef TypeParam Map;
+
+  Map map;
+
+  map.put("foo", 1024);
+  ASSERT_EQ(1u, map.get("foo").size());
+
+  map.put("foo", 1025);
+  ASSERT_EQ(2u, map.get("foo").size());
+
+  ASSERT_EQ(2u, map.size());
+
+  map.put("bar", 1024);
+  ASSERT_EQ(1u, map.get("bar").size());
+
+  map.put("bar", 1025);
+  ASSERT_EQ(2u, map.get("bar").size());
+
+  ASSERT_EQ(4u, map.size());
+}
+
+
+TYPED_TEST(MultimapTest, Remove)
+{
+  typedef TypeParam Map;
+
+  Map map;
+
+  map.put("foo", 1024);
+  map.remove("foo", 1024);
+  ASSERT_EQ(0u, map.get("foo").size());
+
+  ASSERT_EQ(0u, map.size());
+
+  map.put("foo", 1024);
+  map.put("foo", 1025);
+  ASSERT_EQ(2u, map.get("foo").size());
+
+  ASSERT_EQ(2u, map.size());
+
+  map.remove("foo");
+  ASSERT_EQ(0u, map.get("foo").size());
+  ASSERT_EQ(0u, map.size());
+}
+
+
+TYPED_TEST(MultimapTest, Size)
+{
+  typedef TypeParam Map;
+
+  Map map;
+
+  map.put("foo", 1024);
+  map.put("foo", 1025);
+  ASSERT_EQ(2u, map.get("foo").size());
+  ASSERT_TRUE(map.contains("foo", 1024));
+  ASSERT_TRUE(map.contains("foo", 1025));
+  ASSERT_EQ(2u, map.size());
+
+  map.put("bar", 1024);
+  map.put("bar", 1025);
+  ASSERT_EQ(2u, map.get("bar").size());
+  ASSERT_TRUE(map.contains("bar", 1024));
+  ASSERT_TRUE(map.contains("bar", 1025));
+  ASSERT_EQ(4u, map.size());
+}
+
+
+TYPED_TEST(MultimapTest, Keys)
+{
+  typedef TypeParam Map;
+
+  Map map;
+
+  map.put("foo", 1024);
+  map.put("foo", 1024);
+  map.put("foo", 1024);
+  map.put("foo", 1025);
+  map.put("bar", 1);
+
+  set<string> keys = map.keys();
+
+  ASSERT_EQ(2, keys.size());
+  ASSERT_EQ(1, keys.count("foo"));
+  ASSERT_EQ(1, keys.count("bar"));
+}
+
+
+TYPED_TEST(MultimapTest, Iterator)
+{
+  typedef TypeParam Map;
+
+  Map map;
+
+  map.put("foo", 1024);
+  map.put("foo", 1025);
+  ASSERT_EQ(2u, map.get("foo").size());
+  ASSERT_TRUE(map.contains("foo", 1024));
+  ASSERT_TRUE(map.contains("foo", 1025));
+
+  typename Map::iterator i = map.begin();
+
+  ASSERT_TRUE(i != map.end());
+
+  ASSERT_EQ("foo", i->first);
+  ASSERT_EQ(1024, i->second);
+
+  ++i;
+  ASSERT_TRUE(i != map.end());
+
+  ASSERT_EQ("foo", i->first);
+  ASSERT_EQ(1025, i->second);
+
+  ++i;
+  ASSERT_TRUE(i == map.end());
+}
+
+
+TYPED_TEST(MultimapTest, Foreach)
+{
+  typedef TypeParam Map;
+
+  Map map;
+
+  map.put("foo", 1024);
+  map.put("bar", 1025);
+  ASSERT_EQ(1u, map.get("foo").size());
+  ASSERT_EQ(1u, map.get("bar").size());
+  ASSERT_TRUE(map.contains("foo", 1024));
+  ASSERT_TRUE(map.contains("bar", 1025));
+
+  foreachpair (const string& key, uint16_t value, map) {
+    if (key == "foo") {
+      ASSERT_EQ(1024, value);
+    } else if (key == "bar") {
+      ASSERT_EQ(1025, value);
+    } else {
+      FAIL() << "Unexpected key/value in multimap";
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/none_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/none_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/none_tests.cpp
new file mode 100644
index 0000000..38d25bb
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/none_tests.cpp
@@ -0,0 +1,59 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+
+using std::string;
+
+
+None none1()
+{
+  return None();
+}
+
+
+Option<string> none2()
+{
+  return None();
+}
+
+
+Option<string> none3(const Option<string>& o)
+{
+  return o;
+}
+
+
+Result<string> none4()
+{
+  return None();
+}
+
+
+Result<string> none5(const Result<string>& r)
+{
+  return r;
+}
+
+
+TEST(NoneTest, Test)
+{
+  Option<string> o = none1();
+  EXPECT_TRUE(o.isNone());
+  o = none2();
+  EXPECT_TRUE(o.isNone());
+  o = none3(none1());
+  EXPECT_TRUE(o.isNone());
+
+  Result<string> r = none1();
+  EXPECT_TRUE(r.isNone());
+  r = none4();
+  EXPECT_TRUE(r.isNone());
+  r = none5(none1());
+  EXPECT_TRUE(r.isNone());
+}