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:06 UTC

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

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/os_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/os_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/os_tests.cpp
new file mode 100644
index 0000000..047778d
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/os_tests.cpp
@@ -0,0 +1,208 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <cstdlib> // For rand.
+#include <string>
+
+#include <stout/foreach.hpp>
+#include <stout/gtest.hpp>
+#include <stout/hashset.hpp>
+#include <stout/os.hpp>
+#include <stout/stopwatch.hpp>
+#include <stout/try.hpp>
+#include <stout/uuid.hpp>
+
+using std::string;
+
+
+static hashset<string> listfiles(const string& directory)
+{
+  hashset<string> fileset;
+  foreach (const string& file, os::ls(directory)) {
+    fileset.insert(file);
+  }
+  return fileset;
+}
+
+
+class OsTest : public ::testing::Test
+{
+protected:
+  virtual void SetUp()
+  {
+    Try<string> mkdtemp = os::mkdtemp();
+    ASSERT_SOME(mkdtemp);
+    tmpdir = mkdtemp.get();
+  }
+
+  virtual void TearDown()
+  {
+    ASSERT_SOME(os::rmdir(tmpdir));
+  }
+
+  string tmpdir;
+};
+
+
+TEST_F(OsTest, rmdir)
+{
+  const hashset<string> EMPTY;
+
+  hashset<string> expectedListing = EMPTY;
+  EXPECT_EQ(expectedListing, listfiles(tmpdir));
+
+  os::mkdir(tmpdir + "/a/b/c");
+  os::mkdir(tmpdir + "/a/b/d");
+  os::mkdir(tmpdir + "/e/f");
+
+  expectedListing = EMPTY;
+  expectedListing.insert("a");
+  expectedListing.insert("e");
+  EXPECT_EQ(expectedListing, listfiles(tmpdir));
+
+  expectedListing = EMPTY;
+  expectedListing.insert("b");
+  EXPECT_EQ(expectedListing, listfiles(tmpdir + "/a"));
+
+  expectedListing = EMPTY;
+  expectedListing.insert("c");
+  expectedListing.insert("d");
+  EXPECT_EQ(expectedListing, listfiles(tmpdir + "/a/b"));
+
+  expectedListing = EMPTY;
+  EXPECT_EQ(expectedListing, listfiles(tmpdir + "/a/b/c"));
+  EXPECT_EQ(expectedListing, listfiles(tmpdir + "/a/b/d"));
+
+  expectedListing.insert("f");
+  EXPECT_EQ(expectedListing, listfiles(tmpdir + "/e"));
+
+  expectedListing = EMPTY;
+  EXPECT_EQ(expectedListing, listfiles(tmpdir + "/e/f"));
+}
+
+
+TEST_F(OsTest, nonblock)
+{
+  int pipes[2];
+  ASSERT_NE(-1, pipe(pipes));
+
+  Try<bool> isNonBlock = false;
+
+  isNonBlock = os::isNonblock(pipes[0]);
+  ASSERT_SOME(isNonBlock);
+  EXPECT_FALSE(isNonBlock.get());
+
+  ASSERT_SOME(os::nonblock(pipes[0]));
+
+  isNonBlock = os::isNonblock(pipes[0]);
+  ASSERT_SOME(isNonBlock);
+  EXPECT_TRUE(isNonBlock.get());
+
+  close(pipes[0]);
+  close(pipes[1]);
+
+  EXPECT_ERROR(os::nonblock(pipes[0]));
+  EXPECT_ERROR(os::nonblock(pipes[0]));
+}
+
+
+TEST_F(OsTest, touch)
+{
+  const string& testfile  = tmpdir + "/" + UUID::random().toString();
+
+  ASSERT_SOME(os::touch(testfile));
+  ASSERT_TRUE(os::exists(testfile));
+}
+
+
+TEST_F(OsTest, readWriteString)
+{
+  const string& testfile  = tmpdir + "/" + UUID::random().toString();
+  const string& teststr = "test";
+
+  ASSERT_SOME(os::write(testfile, teststr));
+
+  Try<string> readstr = os::read(testfile);
+
+  ASSERT_SOME(readstr);
+  EXPECT_EQ(teststr, readstr.get());
+}
+
+
+TEST_F(OsTest, find)
+{
+  const string& testdir = tmpdir + "/" + UUID::random().toString();
+  const string& subdir = testdir + "/test1";
+  ASSERT_SOME(os::mkdir(subdir)); // Create the directories.
+
+  // Now write some files.
+  const string& file1 = testdir + "/file1.txt";
+  const string& file2 = subdir + "/file2.txt";
+  const string& file3 = subdir + "/file3.jpg";
+
+  ASSERT_SOME(os::touch(file1));
+  ASSERT_SOME(os::touch(file2));
+  ASSERT_SOME(os::touch(file3));
+
+  // Find "*.txt" files.
+  Try<std::list<string> > result = os::find(testdir, ".txt");
+  ASSERT_SOME(result);
+
+  hashset<string> files;
+  foreach (const string& file, result.get()) {
+    files.insert(file);
+  }
+
+  ASSERT_EQ(2u, files.size());
+  ASSERT_TRUE(files.contains(file1));
+  ASSERT_TRUE(files.contains(file2));
+}
+
+
+TEST_F(OsTest, uname)
+{
+  Try<os::UTSInfo> info = os::uname();
+
+  ASSERT_SOME(info);
+#ifdef __linux__
+  EXPECT_EQ(info.get().sysname, "Linux");
+#endif
+#ifdef __APPLE__
+  EXPECT_EQ(info.get().sysname, "Darwin");
+#endif
+}
+
+
+TEST_F(OsTest, sysname)
+{
+  Try<string> name = os::sysname();
+
+  ASSERT_SOME(name);
+#ifdef __linux__
+  EXPECT_EQ(name.get(), "Linux");
+#endif
+#ifdef __APPLE__
+  EXPECT_EQ(name.get(), "Darwin");
+#endif
+}
+
+
+TEST_F(OsTest, release)
+{
+  Try<os::Release> info = os::release();
+
+  ASSERT_SOME(info);
+}
+
+
+TEST_F(OsTest, sleep)
+{
+  Duration duration = Milliseconds(10);
+  Stopwatch stopwatch;
+  stopwatch.start();
+  ASSERT_SOME(os::sleep(duration));
+  ASSERT_LE(duration, stopwatch.elapsed());
+
+  ASSERT_ERROR(os::sleep(Milliseconds(-10)));
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/proc_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/proc_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/proc_tests.cpp
new file mode 100644
index 0000000..2305ef5
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/proc_tests.cpp
@@ -0,0 +1,162 @@
+/**
+ * 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.
+ */
+
+#include <unistd.h> // For getpid, getppid.
+
+#include <gmock/gmock.h>
+
+#include <set>
+
+#include <stout/gtest.hpp>
+#include <stout/proc.hpp>
+#include <stout/try.hpp>
+
+using proc::CPU;
+using proc::SystemStatus;
+using proc::ProcessStatus;
+
+using std::set;
+
+
+TEST(ProcTest, pids)
+{
+  Try<set<pid_t> > pids = proc::pids();
+
+  ASSERT_SOME(pids);
+  EXPECT_NE(0u, pids.get().size());
+  EXPECT_EQ(1u, pids.get().count(getpid()));
+  EXPECT_EQ(1u, pids.get().count(1));
+}
+
+
+TEST(ProcTest, children)
+{
+  Try<set<pid_t> > children = proc::children(getpid());
+
+  ASSERT_SOME(children);
+  EXPECT_EQ(0u, children.get().size());
+
+  // Use pipes to determine the pids of the child and grandchild.
+  int childPipes[2];
+  int grandchildPipes[2];
+  ASSERT_NE(-1, pipe(childPipes));
+  ASSERT_NE(-1, pipe(grandchildPipes));
+
+  pid_t childPid;
+  pid_t grandchildPid;
+  pid_t pid = fork();
+  ASSERT_NE(-1, pid);
+
+  if (pid > 0) {
+    // In parent process.
+    close(childPipes[1]);
+    close(grandchildPipes[1]);
+
+    // Get the pids via the pipes.
+    ASSERT_NE(
+        -1,
+        read(childPipes[0], &childPid, sizeof(childPid)));
+    ASSERT_NE(
+        -1,
+        read(grandchildPipes[0], &grandchildPid, sizeof(grandchildPid)));
+
+    close(childPipes[0]);
+    close(grandchildPipes[0]);
+  } else {
+    // In child process.
+    close(childPipes[0]);
+    close(grandchildPipes[0]);
+
+    // Double fork!
+    if ((pid = fork()) == -1) {
+      perror("Failed to fork a grand child process");
+      abort();
+    }
+
+    if (pid > 0) {
+      // Still in child process.
+      pid = getpid();
+      if (write(childPipes[1], &pid, sizeof(pid)) != sizeof(pid)) {
+        perror("Failed to write PID on pipe");
+        abort();
+      }
+
+      close(childPipes[1]);
+
+      while (true); // Keep waiting until we get a signal.
+    } else {
+      // In grandchild process.
+      pid = getpid();
+      if (write(grandchildPipes[1], &pid, sizeof(pid)) != sizeof(pid)) {
+        perror("Failed to write PID on pipe");
+        abort();
+      }
+
+      close(grandchildPipes[1]);
+
+      while (true); // Keep waiting until we get a signal.
+    }
+  }
+
+  // Ensure the non-recursive children does not include the
+  // grandchild.
+  children = proc::children(getpid(), false);
+
+  ASSERT_SOME(children);
+  EXPECT_EQ(1u, children.get().size());
+  EXPECT_EQ(1u, children.get().count(childPid));
+
+  children = proc::children(getpid());
+
+  ASSERT_SOME(children);
+  EXPECT_EQ(2u, children.get().size());
+  EXPECT_EQ(1u, children.get().count(childPid));
+  EXPECT_EQ(1u, children.get().count(grandchildPid));
+
+  // Cleanup by killing the descendants.
+  EXPECT_EQ(0, kill(grandchildPid, SIGKILL));
+  EXPECT_EQ(0, kill(childPid, SIGKILL));
+}
+
+
+TEST(ProcTest, cpus)
+{
+  Try<std::list<CPU> > cpus = proc::cpus();
+
+  ASSERT_SOME(cpus);
+  EXPECT_LE(1u, cpus.get().size());
+}
+
+
+TEST(ProcTest, SystemStatus)
+{
+  Try<SystemStatus> status = proc::status();
+
+  ASSERT_SOME(status);
+  EXPECT_NE(0u, status.get().btime);
+}
+
+
+TEST(ProcTest, ProcessStatus)
+{
+  Try<ProcessStatus> status = proc::status(getpid());
+
+  ASSERT_SOME(status);
+  EXPECT_EQ(getpid(), status.get().pid);
+  EXPECT_EQ(getppid(), status.get().ppid);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/strings_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/strings_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/strings_tests.cpp
new file mode 100644
index 0000000..7ec9446
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/strings_tests.cpp
@@ -0,0 +1,255 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <stout/format.hpp>
+#include <stout/gtest.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+
+using std::map;
+using std::string;
+using std::vector;
+
+
+TEST(StringsTest, Format)
+{
+  Try<std::string> result = strings::format("%s %s", "hello", "world");
+  ASSERT_SOME(result);
+  EXPECT_EQ("hello world", result.get());
+
+  result = strings::format("hello %d", 42);
+  ASSERT_SOME(result);
+  EXPECT_EQ("hello 42", result.get());
+
+  result = strings::format("hello %s", "fourty-two");
+  ASSERT_SOME(result);
+  EXPECT_EQ("hello fourty-two", result.get());
+
+  string hello = "hello";
+
+  result = strings::format("%s %s", hello, "fourty-two");
+  ASSERT_SOME(result);
+  EXPECT_EQ("hello fourty-two", result.get());
+}
+
+
+TEST(StringsTest, Remove)
+{
+  EXPECT_EQ("heo word", strings::remove("hello world", "l"));
+  EXPECT_EQ("hel world", strings::remove("hello world", "lo"));
+  EXPECT_EQ("home/", strings::remove("/home/", "/", strings::PREFIX));
+  EXPECT_EQ("/home", strings::remove("/home/", "/", strings::SUFFIX));
+}
+
+
+TEST(StringsTest, Replace)
+{
+  EXPECT_EQ("hello*", strings::replace("hello/", "/", "*"));
+  EXPECT_EQ("*hello", strings::replace("/hello", "/", "*"));
+  EXPECT_EQ("*hello*world*", strings::replace("/hello/world/", "/", "*"));
+  EXPECT_EQ("*", strings::replace("/", "/", "*"));
+  EXPECT_EQ("hello world", strings::replace("hello world", "/", "*"));
+  EXPECT_EQ("***1***2***3***", strings::replace("/1/2/3/", "/", "***"));
+  EXPECT_EQ("123", strings::replace("/1/2/3/", "/", ""));
+  EXPECT_EQ("/1/2/3**", strings::replace("***1***2***3**", "***", "/"));
+  EXPECT_EQ("/1/2/3/", strings::replace("/1/2/3/", "", "*"));
+}
+
+
+TEST(StringsTest, Trim)
+{
+  EXPECT_EQ("", strings::trim("", " "));
+  EXPECT_EQ("", strings::trim("    ", " "));
+  EXPECT_EQ("hello world", strings::trim("hello world", " "));
+  EXPECT_EQ("hello world", strings::trim("  hello world", " "));
+  EXPECT_EQ("hello world", strings::trim("hello world  ", " "));
+  EXPECT_EQ("hello world", strings::trim("  hello world  ", " "));
+  EXPECT_EQ("hello world", strings::trim(" \t hello world\t  ", " \t"));
+  EXPECT_EQ("hello world", strings::trim(" \t hello world\t \n\r "));
+}
+
+
+TEST(StringsTest, Tokenize)
+{
+  vector<string> tokens = strings::tokenize("hello world,  what's up?", " ");
+  ASSERT_EQ(4u, tokens.size());
+  EXPECT_EQ("hello",  tokens[0]);
+  EXPECT_EQ("world,", tokens[1]);
+  EXPECT_EQ("what's", tokens[2]);
+  EXPECT_EQ("up?",    tokens[3]);
+}
+
+
+TEST(StringsTest, TokenizeStringWithDelimsAtStart)
+{
+  vector<string> tokens = strings::tokenize("  hello world,  what's up?", " ");
+  ASSERT_EQ(4u, tokens.size());
+  EXPECT_EQ("hello",  tokens[0]);
+  EXPECT_EQ("world,", tokens[1]);
+  EXPECT_EQ("what's", tokens[2]);
+  EXPECT_EQ("up?",    tokens[3]);
+}
+
+
+TEST(StringsTest, TokenizeStringWithDelimsAtEnd)
+{
+  vector<string> tokens = strings::tokenize("hello world,  what's up?  ", " ");
+  ASSERT_EQ(4u, tokens.size());
+  EXPECT_EQ("hello",  tokens[0]);
+  EXPECT_EQ("world,", tokens[1]);
+  EXPECT_EQ("what's", tokens[2]);
+  EXPECT_EQ("up?",    tokens[3]);
+}
+
+
+TEST(StringsTest, TokenizeStringWithDelimsAtStartAndEnd)
+{
+  vector<string> tokens = strings::tokenize("  hello world,  what's up?  ", " ");
+  ASSERT_EQ(4u, tokens.size());
+  EXPECT_EQ("hello",  tokens[0]);
+  EXPECT_EQ("world,", tokens[1]);
+  EXPECT_EQ("what's", tokens[2]);
+  EXPECT_EQ("up?",    tokens[3]);
+}
+
+
+TEST(StringsTest, TokenizeWithMultipleDelims)
+{
+  vector<string> tokens = strings::tokenize("hello\tworld,  \twhat's up?",
+                                            " \t");
+  ASSERT_EQ(4u, tokens.size());
+  EXPECT_EQ("hello",  tokens[0]);
+  EXPECT_EQ("world,", tokens[1]);
+  EXPECT_EQ("what's", tokens[2]);
+  EXPECT_EQ("up?",    tokens[3]);
+}
+
+
+TEST(StringsTest, TokenizeEmptyString)
+{
+  vector<string> tokens = strings::tokenize("", " ");
+  ASSERT_EQ(0u, tokens.size());
+}
+
+
+TEST(StringsTest, TokenizeDelimOnlyString)
+{
+  vector<string> tokens = strings::tokenize("   ", " ");
+  ASSERT_EQ(0u, tokens.size());
+}
+
+
+TEST(StringsTest, SplitEmptyString)
+{
+  vector<string> tokens = strings::split("", ",");
+  ASSERT_EQ(1u, tokens.size());
+  EXPECT_EQ("", tokens[0]);
+}
+
+
+TEST(StringsTest, SplitDelimOnlyString)
+{
+  vector<string> tokens = strings::split(",,,", ",");
+  ASSERT_EQ(4u, tokens.size());
+  EXPECT_EQ("", tokens[0]);
+  EXPECT_EQ("", tokens[1]);
+  EXPECT_EQ("", tokens[2]);
+  EXPECT_EQ("", tokens[3]);
+}
+
+
+TEST(StringsTest, Split)
+{
+  vector<string> tokens = strings::split("foo,bar,,baz", ",");
+  ASSERT_EQ(4u, tokens.size());
+  EXPECT_EQ("foo", tokens[0]);
+  EXPECT_EQ("bar", tokens[1]);
+  EXPECT_EQ("",    tokens[2]);
+  EXPECT_EQ("baz", tokens[3]);
+}
+
+
+TEST(StringsTest, SplitStringWithDelimsAtStart)
+{
+  vector<string> tokens = strings::split(",,foo,bar,,baz", ",");
+  ASSERT_EQ(6u, tokens.size());
+  EXPECT_EQ("",    tokens[0]);
+  EXPECT_EQ("",    tokens[1]);
+  EXPECT_EQ("foo", tokens[2]);
+  EXPECT_EQ("bar", tokens[3]);
+  EXPECT_EQ("",    tokens[4]);
+  EXPECT_EQ("baz", tokens[5]);
+}
+
+
+TEST(StringsTest, SplitStringWithDelimsAtEnd)
+{
+  vector<string> tokens = strings::split("foo,bar,,baz,,", ",");
+  ASSERT_EQ(6u, tokens.size());
+  EXPECT_EQ("foo", tokens[0]);
+  EXPECT_EQ("bar", tokens[1]);
+  EXPECT_EQ("",    tokens[2]);
+  EXPECT_EQ("baz", tokens[3]);
+  EXPECT_EQ("",    tokens[4]);
+  EXPECT_EQ("",    tokens[5]);
+}
+
+
+TEST(StringsTest, SplitStringWithDelimsAtStartAndEnd)
+{
+  vector<string> tokens = strings::split(",,foo,bar,,", ",");
+  ASSERT_EQ(6u, tokens.size());
+  EXPECT_EQ("",    tokens[0]);
+  EXPECT_EQ("",    tokens[1]);
+  EXPECT_EQ("foo", tokens[2]);
+  EXPECT_EQ("bar", tokens[3]);
+  EXPECT_EQ("",    tokens[4]);
+  EXPECT_EQ("",    tokens[5]);
+}
+
+
+TEST(StringsTest, SplitWithMultipleDelims)
+{
+  vector<string> tokens = strings::split("foo.bar,.,.baz.", ",.");
+  ASSERT_EQ(7u, tokens.size());
+  EXPECT_EQ("foo", tokens[0]);
+  EXPECT_EQ("bar", tokens[1]);
+  EXPECT_EQ("",    tokens[2]);
+  EXPECT_EQ("",    tokens[3]);
+  EXPECT_EQ("",    tokens[4]);
+  EXPECT_EQ("baz", tokens[5]);
+  EXPECT_EQ("",    tokens[6]);
+}
+
+
+TEST(StringsTest, Pairs)
+{
+  map<string, vector<string> > pairs = strings::pairs("one=1,two=2", ",", "=");
+  ASSERT_EQ(2u, pairs.size());
+  ASSERT_EQ(1u, pairs.count("one"));
+  ASSERT_EQ(1u, pairs["one"].size());
+  EXPECT_EQ("1", pairs["one"].front());
+  ASSERT_EQ(1u, pairs.count("two"));
+  ASSERT_EQ(1u, pairs["two"].size());
+  EXPECT_EQ("2", pairs["two"].front());
+}
+
+
+TEST(StringsTest, StartsWith)
+{
+  EXPECT_TRUE(strings::startsWith("hello world", "hello"));
+  EXPECT_FALSE(strings::startsWith("hello world", "no"));
+  EXPECT_FALSE(strings::startsWith("hello world", "ello"));
+}
+
+
+TEST(StringsTest, Contains)
+{
+  EXPECT_TRUE(strings::contains("hello world", "world"));
+  EXPECT_FALSE(strings::contains("hello world", "no"));
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/tests/uuid_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/uuid_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/uuid_tests.cpp
new file mode 100644
index 0000000..ad1d986
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/uuid_tests.cpp
@@ -0,0 +1,37 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include <stout/uuid.hpp>
+
+using std::string;
+
+
+TEST(UUIDTest, test)
+{
+  UUID uuid1 = UUID::random();
+  UUID uuid2 = UUID::fromBytes(uuid1.toBytes());
+  UUID uuid3 = uuid2;
+
+  EXPECT_EQ(uuid1, uuid2);
+  EXPECT_EQ(uuid2, uuid3);
+  EXPECT_EQ(uuid1, uuid3);
+
+  string bytes1 = uuid1.toBytes();
+  string bytes2 = uuid2.toBytes();
+  string bytes3 = uuid3.toBytes();
+
+  EXPECT_EQ(bytes1, bytes2);
+  EXPECT_EQ(bytes2, bytes3);
+  EXPECT_EQ(bytes1, bytes3);
+
+  string string1 = uuid1.toString();
+  string string2 = uuid2.toString();
+  string string3 = uuid3.toString();
+
+  EXPECT_EQ(string1, string2);
+  EXPECT_EQ(string2, string3);
+  EXPECT_EQ(string1, string3);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/versions.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/versions.am b/3rdparty/libprocess/3rdparty/versions.am
new file mode 100644
index 0000000..0d05698
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/versions.am
@@ -0,0 +1,11 @@
+# This automake utility file is included from 3rdparty/Makefile.am
+# and src/Makefile.am, so we can update the version numbers of
+# third_party packages in exactly one place.
+
+BOOST_VERSION = 1.53.0
+GLOG_VERSION = 0.3.1
+GMOCK_VERSION = 1.6.0
+GPERFTOOLS_VERSION = 2.0
+LIBEV_VERSION = 4.15
+PROTOBUF_VERSION = 2.4.1
+RY_HTTP_PARSER_VERSION = 1c3624a

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/LICENSE
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/LICENSE b/3rdparty/libprocess/LICENSE
new file mode 100644
index 0000000..f433b1a
--- /dev/null
+++ b/3rdparty/libprocess/LICENSE
@@ -0,0 +1,177 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/Makefile.am b/3rdparty/libprocess/Makefile.am
new file mode 100644
index 0000000..b6b8abd
--- /dev/null
+++ b/3rdparty/libprocess/Makefile.am
@@ -0,0 +1,125 @@
+# Makefile for libprocess. Note that 3rdparty needs to be built
+# first (see 3rdparty/Makefile.am).
+
+ACLOCAL_AMFLAGS = -I m4
+
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = 3rdparty .
+
+include 3rdparty/versions.am
+
+STOUT = 3rdparty/stout
+BOOST = 3rdparty/boost-$(BOOST_VERSION)
+GLOG = 3rdparty/glog-$(GLOG_VERSION)
+GMOCK = 3rdparty/gmock-$(GMOCK_VERSION)
+GPERFTOOLS = 3rdparty/gperftools-$(GPERFTOOLS_VERSION)
+GTEST = $(GMOCK)/gtest
+RY_HTTP_PARSER = 3rdparty/ry-http-parser-$(RY_HTTP_PARSER_VERSION)
+LIBEV = 3rdparty/libev-$(LIBEV_VERSION)
+
+
+# Library. It is not installable presently because most people link
+# the libprocess statically into their resulting library or binary and
+# don't want any parts of libprocess to get installed (which happens
+# even if you attempt to do conditional installation via configure
+# arguments, see configure.ac).
+noinst_LTLIBRARIES = libprocess.la
+
+libprocess_la_SOURCES =		\
+  src/config.hpp		\
+  src/decoder.hpp		\
+  src/encoder.hpp		\
+  src/gate.hpp			\
+  src/latch.cpp			\
+  src/pid.cpp			\
+  src/process.cpp		\
+  src/statistics.cpp		\
+  src/synchronized.hpp
+
+libprocess_la_CPPFLAGS =		\
+  -I$(srcdir)/include			\
+  -I$(srcdir)/$(STOUT)/include		\
+  -I$(BOOST)				\
+  -I$(GLOG)/src				\
+  -I$(LIBEV)				\
+  -I$(RY_HTTP_PARSER)			\
+  $(AM_CPPFLAGS)
+
+libprocess_la_LIBADD =			\
+  $(GLOG)/libglog.la			\
+  3rdparty/libry_http_parser.la	\
+  $(LIBEV)/libev.la
+
+if HAS_GPERFTOOLS
+libprocess_la_CPPFLAGS += -I$(GPERFTOOLS)/src
+libprocess_la_LIBADD += $(GPERFTOOLS)/libprofiler.la
+endif
+
+# Headers.
+libprocess_la_SOURCES +=					\
+  $(top_srcdir)/include/process/async.hpp			\
+  $(top_srcdir)/include/process/clock.hpp			\
+  $(top_srcdir)/include/process/collect.hpp			\
+  $(top_srcdir)/include/process/defer.hpp			\
+  $(top_srcdir)/include/process/deferred.hpp			\
+  $(top_srcdir)/include/process/delay.hpp			\
+  $(top_srcdir)/include/process/dispatch.hpp			\
+  $(top_srcdir)/include/process/event.hpp			\
+  $(top_srcdir)/include/process/executor.hpp			\
+  $(top_srcdir)/include/process/filter.hpp			\
+  $(top_srcdir)/include/process/future.hpp			\
+  $(top_srcdir)/include/process/gc.hpp				\
+  $(top_srcdir)/include/process/gmock.hpp			\
+  $(top_srcdir)/include/process/gtest.hpp			\
+  $(top_srcdir)/include/process/http.hpp			\
+  $(top_srcdir)/include/process/id.hpp				\
+  $(top_srcdir)/include/process/io.hpp				\
+  $(top_srcdir)/include/process/latch.hpp			\
+  $(top_srcdir)/include/process/logging.hpp			\
+  $(top_srcdir)/include/process/message.hpp			\
+  $(top_srcdir)/include/process/mime.hpp			\
+  $(top_srcdir)/include/process/once.hpp			\
+  $(top_srcdir)/include/process/pid.hpp				\
+  $(top_srcdir)/include/process/process.hpp			\
+  $(top_srcdir)/include/process/profiler.hpp			\
+  $(top_srcdir)/include/process/protobuf.hpp			\
+  $(top_srcdir)/include/process/run.hpp				\
+  $(top_srcdir)/include/process/socket.hpp			\
+  $(top_srcdir)/include/process/statistics.hpp			\
+  $(top_srcdir)/include/process/thread.hpp			\
+  $(top_srcdir)/include/process/time.hpp			\
+  $(top_srcdir)/include/process/timeout.hpp			\
+  $(top_srcdir)/include/process/timer.hpp
+
+# Tests.
+check_PROGRAMS = tests
+
+tests_SOURCES =							\
+  src/tests/decoder_tests.cpp					\
+  src/tests/encoder_tests.cpp					\
+  src/tests/http_tests.cpp					\
+  src/tests/io_tests.cpp					\
+  src/tests/main.cpp						\
+  src/tests/process_tests.cpp					\
+  src/tests/statistics_tests.cpp				\
+  src/tests/time_tests.cpp
+
+tests_CPPFLAGS =			\
+  -I$(top_srcdir)/src			\
+  -I$(GTEST)/include			\
+  -I$(GMOCK)/include			\
+  $(libprocess_la_CPPFLAGS)
+
+tests_LDADD = 3rdparty/libgmock.la libprocess.la
+
+TESTS = tests
+
+# TODO(benh): Fix shared builds (tests need libglog, libev, etc).
+
+# Using LT_OUTPUT in configure.ac creates config.lt that doesn't get
+# cleaned up by distclean-libtool. See this bug patch (which doesn't
+# appear to be in all versions of libtool.m4):
+# http://lists.gnu.org/archive/html/automake-commit/2008-11/msg00015.html.
+distclean-local:
+	-rm -f config.lt

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/README
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/README b/3rdparty/libprocess/README
new file mode 100644
index 0000000..89b009f
--- /dev/null
+++ b/3rdparty/libprocess/README
@@ -0,0 +1,10 @@
+README for libprocess
+
+Most importantly, if you run into an issue, please send me an email:
+benh@berkeley.edu.
+
+$ ./bootstrap # Unless you already have a distribution.
+$ mkdir build && cd build # Optional.
+$ path/to/configure
+$ make
+$ make check

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/TODO
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/TODO b/3rdparty/libprocess/TODO
new file mode 100644
index 0000000..9770546
--- /dev/null
+++ b/3rdparty/libprocess/TODO
@@ -0,0 +1,33 @@
+/* TODO(benh): Improve link/connection management. For example, make
+   links be about sockets. Then see whether or not already connected
+   sockets can be used for sending a message back (without opening a
+   new socket first). */
+
+/* TODO(benh): When a link fails, try and reconnect a configurable
+   number of times before you just assume the link is dead. */
+
+/* TODO(benh): Fix link functionality (processes need to send
+   process_exit message since a dead process on one node might not
+   know that a process on another node linked with it). */
+
+/* TODO(benh): What happens when a remote link exits? Do we close the
+   socket correclty?. */
+
+/* TODO(benh): Handle/Enable forking. */
+
+/* TODO(benh): Use multiple processing threads (do process affinity). */
+
+/* TODO(benh): Better error handling (i.e., warn if re-spawn process
+   instead of just returning bad pid). */
+
+/* TODO(benh): Use different backends for files and sockets. */
+
+/* TODO(benh): Allow messages to be received out-of-order (i.e., allow
+   someone to do a receive with a message id and let other messages
+   queue until a message with that message id is received).  */
+
+/* TODO(benh): LinkManager::link and LinkManager::send are pretty big
+   functions, we could probably create some queue that the I/O thread
+   checks for sending messages and creating links instead ... that
+   would probably be faster, and have less contention for the mutex
+   (that might mean we can eliminate contention for the mutex!). */

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/bootstrap
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/bootstrap b/3rdparty/libprocess/bootstrap
new file mode 100755
index 0000000..1d3215d
--- /dev/null
+++ b/3rdparty/libprocess/bootstrap
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# Make sure that we are in the right directory.
+if test ! -f configure.ac; then
+    cat >&2 <<__EOF__
+You must run bootstrap from the root of the distribution.
+__EOF__
+    exit 1
+fi
+
+autoreconf --install -Wall --verbose "${@}"

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/configure.ac
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/configure.ac b/3rdparty/libprocess/configure.ac
new file mode 100644
index 0000000..d3b86a3
--- /dev/null
+++ b/3rdparty/libprocess/configure.ac
@@ -0,0 +1,117 @@
+# Generated with autoscan, then modified appropriately.
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.61])
+AC_INIT([libprocess], [0.0.1])
+
+# Have autoconf setup some variables related to the system.
+AC_CANONICAL_HOST
+AC_CANONICAL_BUILD
+AC_CANONICAL_TARGET
+
+AC_LANG([C++])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+# Initialize automake.
+# -Wno-portability, since we require GNU Make for % patterns.
+AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability foreign])
+
+# Required for linking non-POSIX libs.
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+# Initialize libtool (LT_OUTPUT builds ./libtool immediately, needed
+# if we want to do tests with libtool during configuration).
+LT_PREREQ([2.2])
+LT_INIT
+LT_LANG([C++])
+LT_OUTPUT
+
+# The default CFLAGS/CXXFLAGS from autoconf when using gcc usually
+# includes "-O2". These really slow down compiling our tests, so we
+# turn them off and enable them (where desired) directly in the
+# Makefile. Note that this should not have an impact on users setting
+# CFLAGS/CXXFLAGS directly at configure time, or when running make.
+AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"], [CFLAGS="-g"])
+AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"], [CXXFLAGS="-g"])
+
+# Save the configure arguments so we can pass them to any third-party
+# libraries that we might run configure on (see
+# 3rdparty/Makefile.am). One downside of our strategy for shipping
+# and building third-party libraries is that we can't expose options
+# from nested third-party configure scripts.
+CONFIGURE_ARGS="$ac_configure_args"
+AC_SUBST(CONFIGURE_ARGS)
+
+AC_CONFIG_SUBDIRS([3rdparty/stout])
+
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([3rdparty/Makefile])
+
+AC_ARG_ENABLE([install],
+              AS_HELP_STRING([--enable-install],
+                             [install libprocess]),
+              [AC_MSG_ERROR([libprocess can not currently be installed])])
+
+AC_ARG_ENABLE([optimize],
+              AS_HELP_STRING([--disable-optimize],
+                             [don't try to compile with optimizations]),
+              [], [enable_optimize=yes])
+
+AC_ARG_ENABLE([perftools],
+              AS_HELP_STRING([--enable-perftools],
+                             [enable google perftools]),
+              [gperftools=yes])
+
+AC_ARG_WITH([zlib],
+            AS_HELP_STRING([--without-zlib],
+                           [disables zlib compression, which means the webui
+                            will be far less responsive; not recommended]),
+            [], [with_zlib=yes])
+
+# Do some OS specific setup.
+case "${target_os}" in
+  linux*)
+    LIBS="$LIBS -lrt" # For clock_gettime() in stout/stopwatch.hpp.
+    OS_NAME=linux # Used below for OS_LINUX.
+    ;;
+  *)
+    ;;
+esac
+
+# Checks for gcc toolchain (we rely on some atomic builtins for now).
+AC_PROG_CXX([g++])
+AC_PROG_CC([gcc])
+
+# Check for pthreads (uses m4/acx_pthread.m4).
+ACX_PTHREAD([], [AC_MSG_ERROR([failed to find pthreads])])
+
+
+# Check if we should try and enable optimizations.
+if test "x$enable_optimize" = "xyes"; then
+  # For now, we only turn on optimizations for gcc.
+  if test "x$GCC" = "xyes"; then
+    CXXFLAGS="$CXXFLAGS -g2 -O2"
+  fi
+fi
+
+
+# Check if we should/can build with libz.
+if test "x$with_zlib" = "xyes"; then
+  AC_CHECK_LIB([z], [deflate, gzread, gzwrite, inflate], [],
+               [AC_MSG_ERROR([cannot find libz
+  -------------------------------------------------------------------
+  This means HTTP responses will be slower because we cannot use
+  compression; you probably want to download and install zlib, but
+  you can get away without it by doing --without-zlib.
+  -------------------------------------------------------------------
+  ])])
+fi
+
+AM_CONDITIONAL([HAS_GPERFTOOLS], [test "x$gperftools" = "xyes"])
+
+# Used for conditionally building source files (e.g., only want to
+# build stout/tests/proc_tests.cpp on Linux).
+AM_CONDITIONAL([OS_LINUX], [test "x$OS_NAME" = "xlinux"])
+
+AC_OUTPUT

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/examples/example.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/examples/example.cpp b/3rdparty/libprocess/examples/example.cpp
new file mode 100644
index 0000000..3fb4ef5
--- /dev/null
+++ b/3rdparty/libprocess/examples/example.cpp
@@ -0,0 +1,121 @@
+#include <iostream>
+#include <sstream>
+
+#include <process/defer.hpp>
+#include <process/dispatch.hpp>
+#include <process/future.hpp>
+#include <process/http.hpp>
+#include <process/process.hpp>
+
+using namespace process;
+
+using namespace process::http;
+
+using std::string;
+
+class MyProcess : public Process<MyProcess>
+{
+public:
+  MyProcess() {}
+  virtual ~MyProcess() {}
+
+  Future<int> func1()
+  {
+    promise.future().onAny(
+        defer([=] (const Future<int>& future) {
+          terminate(self());
+        }));
+    return promise.future();
+  }
+
+  void func2(int i)
+  {
+    promise.set(i);
+  }
+
+  Future<Response> vars(const Request& request)
+  {
+    string body = "... vars here ...";
+    OK response;
+    response.headers["Content-Type"] = "text/plain";
+    std::ostringstream out;
+    out << body.size();
+    response.headers["Content-Length"] = out.str();
+    response.body = body;
+    return response;
+  }
+
+  void stop(const UPID& from, const string& body)
+  {
+    terminate(self());
+  }
+
+protected:
+  virtual void initialize()
+  {
+//     route("/vars", &MyProcess::vars);
+    route("/vars", [=] (const Request& request) {
+        string body = "... vars here ...";
+        OK response;
+        response.headers["Content-Type"] = "text/plain";
+        std::ostringstream out;
+        out << body.size();
+        response.headers["Content-Length"] = out.str();
+        response.body = body;
+        return response;
+      });
+
+//     install("stop", &MyProcess::stop);
+    install("stop", [=] (const UPID& from, const string& body) {
+        terminate(self());
+      });
+  }
+
+private:
+  Promise<int> promise;
+};
+
+
+int main(int argc, char** argv)
+{
+  MyProcess process;
+  PID<MyProcess> pid = spawn(&process);
+
+  PID<> pid2 = pid;
+
+// --------------------------------------
+
+//   Future<int> future = dispatch(pid, &MyProcess::func1);
+//   dispatch(pid, &MyProcess::func2, 42);
+
+//   std::cout << future.get() << std::endl;
+
+//   post(pid, "stop");
+
+// --------------------------------------
+
+//   Promise<bool> p;
+
+//   dispatch(pid, &MyProcess::func1)
+//     .then([=, &p] (int i) {
+//         p.set(i == 42);
+//         return p.future();
+//       })
+//     .then([=] (bool b) {
+//         if (b) {
+//           post(pid, "stop");
+//         }
+//         return true; // No Future<void>.
+//       });
+
+//   dispatch(pid, &MyProcess::func2, 42);
+
+// --------------------------------------
+
+  dispatch(pid, &MyProcess::func1);
+  dispatch(pid, &MyProcess::func2, 42);
+
+
+  wait(pid);
+  return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/async.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/async.hpp b/3rdparty/libprocess/include/process/async.hpp
new file mode 100644
index 0000000..8fa2771
--- /dev/null
+++ b/3rdparty/libprocess/include/process/async.hpp
@@ -0,0 +1,231 @@
+#ifndef __ASYNC_HPP__
+#define __ASYNC_HPP__
+
+#include <process/dispatch.hpp>
+#include <process/future.hpp>
+#include <process/id.hpp>
+#include <process/process.hpp>
+
+#include <tr1/functional>
+
+namespace process {
+
+// TODO(vinod): Merge this into ExecutorProcess.
+// TODO(vinod): Add support for void functions. Currently this is tricky,
+// because Future<void> is not supported.
+class AsyncExecutorProcess : public Process<AsyncExecutorProcess>
+{
+private:
+  friend class AsyncExecutor;
+
+  AsyncExecutorProcess() : ProcessBase(ID::generate("__async_executor__")) {}
+  virtual ~AsyncExecutorProcess() {}
+
+  // Not copyable, not assignable.
+  AsyncExecutorProcess(const AsyncExecutorProcess&);
+  AsyncExecutorProcess& operator = (const AsyncExecutorProcess&);
+
+  template<typename F>
+  typename std::tr1::result_of<F(void)>::type execute(
+      const F& f)
+  {
+    terminate(self()); // Terminate this process after the function returns.
+    return f();
+  }
+
+  // TODO(vinod): Use boost macro enumerations.
+  template<typename F, typename A1>
+  typename std::tr1::result_of<F(A1)>::type execute(
+      const F& f, A1 a1)
+  {
+    terminate(self()); // Terminate this process after the function returns.
+    return f(a1);
+  }
+
+  template<typename F, typename A1, typename A2>
+  typename std::tr1::result_of<F(A1, A2)>::type execute(
+      const F& f, A1 a1, A2 a2)
+  {
+    terminate(self()); // Terminate this process after the function returns.
+    return f(a1, a2);
+  }
+
+  template<typename F, typename A1, typename A2, typename A3>
+  typename std::tr1::result_of<F(A1, A2, A3)>::type execute(
+      const F& f, A1 a1, A2 a2, A3 a3)
+  {
+    terminate(self()); // Terminate this process after the function returns.
+    return f(a1, a2, a3);
+  }
+
+  template<typename F, typename A1, typename A2, typename A3, typename A4>
+  typename std::tr1::result_of<F(A1, A2, A3, A4)>::type execute(
+      const F& f, A1 a1, A2 a2, A3 a3, A4 a4)
+  {
+    terminate(self()); // Terminate this process after the function returns.
+    return f(a1, a2, a3, a4);
+  }
+};
+
+
+// This is a wrapper around AsyncExecutorProcess.
+class AsyncExecutor
+{
+private:
+  // Declare async functions as friends.
+  template<typename F>
+  friend Future<typename std::tr1::result_of<F(void)>::type> async(
+      const F& f);
+
+  template<typename F, typename A1>
+  friend Future<typename std::tr1::result_of<F(A1)>::type> async(
+      const F& f, A1 a1);
+
+  template<typename F, typename A1, typename A2>
+  friend Future<typename std::tr1::result_of<F(A1, A2)>::type> async(
+      const F& f, A1 a1, A2 a2);
+
+  template<typename F, typename A1, typename A2, typename A3>
+  friend Future<typename std::tr1::result_of<F(A1, A2, A3)>::type> async(
+      const F& f, A1 a1, A2 a2, A3 a3);
+
+  template<typename F, typename A1, typename A2, typename A3, typename A4>
+  friend Future<typename std::tr1::result_of<F(A1, A2, A3, A4)>::type> async(
+      const F& f, A1 a1, A2 a2, A3 a3, A4 a4);
+
+  AsyncExecutor()
+  {
+    process = new AsyncExecutorProcess();
+    spawn(process, true); // Automatically GC.
+  }
+
+  virtual ~AsyncExecutor() {}
+
+  // Not copyable, not assignable.
+  AsyncExecutor(const AsyncExecutor&);
+  AsyncExecutor& operator = (const AsyncExecutor&);
+
+  template<typename F>
+  Future<typename std::tr1::result_of<F(void)>::type> execute(
+      const F& f)
+  {
+    // Necessary to disambiguate.
+    typedef typename std::tr1::result_of<F(void)>::type
+        (AsyncExecutorProcess::*R)(const F&);
+
+    return dispatch(process,
+                    static_cast<R>(&AsyncExecutorProcess::execute),
+                    f);
+  }
+
+  // TODO(vinod): Use boost macro enumerations.
+  template<typename F, typename A1>
+  Future<typename std::tr1::result_of<F(A1)>::type> execute(
+      const F& f, A1 a1)
+  {
+    // Necessary to disambiguate.
+    typedef typename std::tr1::result_of<F(A1)>::type
+        (AsyncExecutorProcess::*R)(const F&, A1);
+
+    return dispatch(process,
+                    static_cast<R>(&AsyncExecutorProcess::execute),
+                    f,
+                    a1);
+  }
+
+  template<typename F, typename A1, typename A2>
+  Future<typename std::tr1::result_of<F(A1, A2)>::type> execute(
+      const F& f, A1 a1, A2 a2)
+  {
+    // Necessary to disambiguate.
+    typedef typename std::tr1::result_of<F(A1, A2)>::type
+        (AsyncExecutorProcess::*R)(const F&, A1, A2);
+
+    return dispatch(process,
+                    static_cast<R>(&AsyncExecutorProcess::execute),
+                    f,
+                    a1,
+                    a2);
+  }
+
+  template<typename F, typename A1, typename A2, typename A3>
+  Future<typename std::tr1::result_of<F(A1, A2, A3)>::type> execute(
+      const F& f, A1 a1, A2 a2, A3 a3)
+  {
+    // Necessary to disambiguate.
+    typedef typename std::tr1::result_of<F(A1, A2, A3)>::type
+        (AsyncExecutorProcess::*R)(const F&, A1, A2, A3);
+
+    return dispatch(process,
+                    static_cast<R>(&AsyncExecutorProcess::execute),
+                    f,
+                    a1,
+                    a2,
+                    a3);
+  }
+
+  template<typename F, typename A1, typename A2, typename A3, typename A4>
+  Future<typename std::tr1::result_of<F(A1, A2, A3, A4)>::type> execute(
+      const F& f, A1 a1, A2 a2, A3 a3, A4 a4)
+  {
+    // Necessary to disambiguate.
+    typedef typename std::tr1::result_of<F(A1, A2, A3, A4)>::type
+        (AsyncExecutorProcess::*R)(const F&, A1, A2, A3, A4);
+
+    return dispatch(process,
+                    static_cast<R>(&AsyncExecutorProcess::execute),
+                    f,
+                    a1,
+                    a2,
+                    a3,
+                    a4);
+  }
+
+  AsyncExecutorProcess* process;
+};
+
+
+// Provides an abstraction for asynchronously executing a function.
+// TODO(vinod): Use boost macro to enumerate arguments/params.
+template<typename F>
+Future<typename std::tr1::result_of<F(void)>::type>
+    async(const F& f)
+{
+  return AsyncExecutor().execute(f);
+}
+
+
+template<typename F, typename A1>
+Future<typename std::tr1::result_of<F(A1)>::type>
+    async(const F& f, A1 a1)
+{
+  return AsyncExecutor().execute(f, a1);
+}
+
+
+template<typename F, typename A1, typename A2>
+Future<typename std::tr1::result_of<F(A1, A2)>::type>
+    async(const F& f, A1 a1, A2 a2)
+{
+  return AsyncExecutor().execute(f, a1, a2);
+}
+
+
+template<typename F, typename A1, typename A2, typename A3>
+Future<typename std::tr1::result_of<F(A1, A2, A3)>::type>
+    async(const F& f, A1 a1, A2 a2, A3 a3)
+{
+  return AsyncExecutor().execute(f, a1, a2, a3);
+}
+
+
+template<typename F, typename A1, typename A2, typename A3, typename A4>
+Future<typename std::tr1::result_of<F(A1, A2, A3, A4)>::type>
+    async(const F& f, A1 a1, A2 a2, A3 a3, A4 a4)
+{
+  return AsyncExecutor().execute(f, a1, a2, a3, a4);
+}
+
+} // namespace process {
+
+#endif // __ASYNC_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/clock.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/clock.hpp b/3rdparty/libprocess/include/process/clock.hpp
new file mode 100644
index 0000000..82ae3c6
--- /dev/null
+++ b/3rdparty/libprocess/include/process/clock.hpp
@@ -0,0 +1,32 @@
+#ifndef __PROCESS_CLOCK_HPP__
+#define __PROCESS_CLOCK_HPP__
+
+#include <process/time.hpp>
+
+#include <stout/duration.hpp>
+
+namespace process {
+
+// Forward declarations.
+class ProcessBase;
+class Time;
+
+class Clock
+{
+public:
+  static Time now();
+  static Time now(ProcessBase* process);
+  static void pause();
+  static bool paused();
+  static void resume();
+  static void advance(const Duration& duration);
+  static void advance(ProcessBase* process, const Duration& duration);
+  static void update(const Time& time);
+  static void update(ProcessBase* process, const Time& time);
+  static void order(ProcessBase* from, ProcessBase* to);
+  static void settle();
+};
+
+} // namespace process {
+
+#endif // __PROCESS_CLOCK_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/collect.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/collect.hpp b/3rdparty/libprocess/include/process/collect.hpp
new file mode 100644
index 0000000..8050351
--- /dev/null
+++ b/3rdparty/libprocess/include/process/collect.hpp
@@ -0,0 +1,125 @@
+#ifndef __PROCESS_COLLECT_HPP__
+#define __PROCESS_COLLECT_HPP__
+
+#include <assert.h>
+
+#include <list>
+
+#include <process/defer.hpp>
+#include <process/delay.hpp>
+#include <process/future.hpp>
+#include <process/process.hpp>
+#include <process/timeout.hpp>
+
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+
+namespace process {
+
+// Waits on each future in the specified set and returns the set of
+// resulting values. If any future is discarded then the result will
+// be a failure. Likewise, if any future fails than the result future
+// will be a failure.
+template <typename T>
+Future<std::list<T> > collect(
+    std::list<Future<T> >& futures,
+    const Option<Timeout>& timeout = None());
+
+
+namespace internal {
+
+template <typename T>
+class CollectProcess : public Process<CollectProcess<T> >
+{
+public:
+  CollectProcess(
+      const std::list<Future<T> >& _futures,
+      const Option<Timeout>& _timeout,
+      Promise<std::list<T> >* _promise)
+    : futures(_futures),
+      timeout(_timeout),
+      promise(_promise) {}
+
+  virtual ~CollectProcess()
+  {
+    delete promise;
+  }
+
+  virtual void initialize()
+  {
+    // Stop this nonsense if nobody cares.
+    promise->future().onDiscarded(defer(this, &CollectProcess::discarded));
+
+    // Only wait as long as requested.
+    if (timeout.isSome()) {
+      delay(timeout.get().remaining(), this, &CollectProcess::timedout);
+    }
+
+    typename std::list<Future<T> >::const_iterator iterator;
+    for (iterator = futures.begin(); iterator != futures.end(); ++iterator) {
+      (*iterator).onAny(
+          defer(this, &CollectProcess::waited, std::tr1::placeholders::_1));
+    }
+  }
+
+private:
+  void discarded()
+  {
+    terminate(this);
+  }
+
+  void timedout()
+  {
+    // Need to discard all of the futures so any of their associated
+    // resources can get properly cleaned up.
+    typename std::list<Future<T> >::const_iterator iterator;
+    for (iterator = futures.begin(); iterator != futures.end(); ++iterator) {
+      Future<T> future = *iterator; // Need a non-const copy to discard.
+      future.discard();
+    }
+
+    promise->fail("Collect failed: timed out");
+    terminate(this);
+  }
+
+  void waited(const Future<T>& future)
+  {
+    if (future.isFailed()) {
+      promise->fail("Collect failed: " + future.failure());
+      terminate(this);
+    } else if (future.isDiscarded()) {
+      promise->fail("Collect failed: future discarded");
+      terminate(this);
+    } else {
+      assert(future.isReady());
+      values.push_back(future.get());
+      if (futures.size() == values.size()) {
+        promise->set(values);
+        terminate(this);
+      }
+    }
+  }
+
+  const std::list<Future<T> > futures;
+  const Option<Timeout> timeout;
+  Promise<std::list<T> >* promise;
+  std::list<T> values;
+};
+
+} // namespace internal {
+
+
+template <typename T>
+inline Future<std::list<T> > collect(
+    std::list<Future<T> >& futures,
+    const Option<Timeout>& timeout)
+{
+  Promise<std::list<T> >* promise = new Promise<std::list<T> >();
+  Future<std::list<T> > future = promise->future();
+  spawn(new internal::CollectProcess<T>(futures, timeout, promise), true);
+  return future;
+}
+
+} // namespace process {
+
+#endif // __PROCESS_COLLECT_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/defer.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/defer.hpp b/3rdparty/libprocess/include/process/defer.hpp
new file mode 100644
index 0000000..1eb770b
--- /dev/null
+++ b/3rdparty/libprocess/include/process/defer.hpp
@@ -0,0 +1,438 @@
+#ifndef __PROCESS_DEFER_HPP__
+#define __PROCESS_DEFER_HPP__
+
+#include <tr1/functional>
+
+#include <process/deferred.hpp>
+#include <process/dispatch.hpp>
+#include <process/executor.hpp>
+
+#include <stout/preprocessor.hpp>
+
+namespace process {
+
+// The defer mechanism is very similar to the dispatch mechanism (see
+// dispatch.hpp), however, rather than scheduling the method to get
+// invoked, the defer mechanism returns a 'Deferred' object that when
+// invoked does the underlying dispatch. Similar to dispatch, we
+// provide the C++11 variadic template definitions first, and then use
+// Boost preprocessor macros to provide the actual definitions.
+
+
+// First, definitions of defer for methods returning void:
+//
+// template <typename T, typename ...P>
+// Deferred<void(void)> void defer(const PID<T>& pid,
+//                                 void (T::*method)(P...),
+//                                 P... p)
+// {
+//   void (*dispatch)(const PID<T>&, void (T::*)(P...), P...) =
+//     &process::template dispatch<T, P...>;
+
+//   return Deferred<void(void)>(
+//       std::tr1::bind(dispatch, pid, method, std::forward<P>(p)...));
+// }
+
+template <typename T>
+_Defer<void(*(PID<T>, void (T::*)(void)))
+       (const PID<T>&, void (T::*)(void))>
+defer(const PID<T>& pid, void (T::*method)(void))
+{
+  void (*dispatch)(const PID<T>&, void (T::*)(void)) =
+    &process::template dispatch<T>;
+  return std::tr1::bind(dispatch, pid, method);
+}
+
+template <typename T>
+_Defer<void(*(PID<T>, void (T::*)(void)))
+       (const PID<T>&, void (T::*)(void))>
+defer(const Process<T>& process, void (T::*method)(void))
+{
+  return defer(process.self(), method);
+}
+
+template <typename T>
+_Defer<void(*(PID<T>, void (T::*)(void)))
+       (const PID<T>&, void (T::*)(void))>
+defer(const Process<T>* process, void (T::*method)(void))
+{
+  return defer(process->self(), method);
+}
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<void(*(PID<T>,                                                 \
+                void (T::*)(ENUM_PARAMS(N, P)),                         \
+                ENUM_PARAMS(N, A)))                                     \
+         (const PID<T>&,                                                \
+          void (T::*)(ENUM_PARAMS(N, P)),                               \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const PID<T>& pid,                                              \
+        void (T::*method)(ENUM_PARAMS(N, P)),                           \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    void (*dispatch)(const PID<T>&,                                     \
+                     void (T::*)(ENUM_PARAMS(N, P)),                    \
+                     ENUM_PARAMS(N, P)) =                               \
+      &process::template dispatch<T, ENUM_PARAMS(N, P), ENUM_PARAMS(N, P)>; \
+    return std::tr1::bind(dispatch, pid, method, ENUM_PARAMS(N, a));    \
+  }                                                                     \
+                                                                        \
+  template <typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<void(*(PID<T>,                                                 \
+                void (T::*)(ENUM_PARAMS(N, P)),                         \
+                ENUM_PARAMS(N, A)))                                     \
+         (const PID<T>&,                                                \
+          void (T::*)(ENUM_PARAMS(N, P)),                               \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const Process<T>& process,                                      \
+        void (T::*method)(ENUM_PARAMS(N, P)),                           \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    return defer(process.self(), method, ENUM_PARAMS(N, a));            \
+  }                                                                     \
+                                                                        \
+  template <typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<void(*(PID<T>,                                                 \
+                void (T::*)(ENUM_PARAMS(N, P)),                         \
+                ENUM_PARAMS(N, A)))                                     \
+         (const PID<T>&,                                                \
+          void (T::*)(ENUM_PARAMS(N, P)),                               \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const Process<T>* process,                                      \
+        void (T::*method)(ENUM_PARAMS(N, P)),                           \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    return defer(process->self(), method, ENUM_PARAMS(N, a));           \
+  }
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+
+// Next, definitions of defer for methods returning future:
+//
+// template <typename R, typename T, typename ...P>
+// Deferred<Future<R>(void)> void defer(const PID<T>& pid,
+//                                      Future<R> (T::*method)(P...),
+//                                      P... p)
+// {
+//   Future<R> (*dispatch)(const PID<T>&, Future<R> (T::*)(P...), P...) =
+//     &process::template dispatch<R, T, P...>;
+//
+//   return Deferred<Future<R>(void)>(
+//       std::tr1::bind(dispatch, pid, method, std::forward<P>(p)...));
+// }
+
+template <typename R, typename T>
+_Defer<Future<R>(*(PID<T>, Future<R> (T::*)(void)))
+       (const PID<T>&, Future<R> (T::*)(void))>
+defer(const PID<T>& pid, Future<R> (T::*method)(void))
+{
+  Future<R> (*dispatch)(const PID<T>&, Future<R> (T::*)(void)) =
+    &process::template dispatch<R, T>;
+  return std::tr1::bind(dispatch, pid, method);
+}
+
+template <typename R, typename T>
+_Defer<Future<R>(*(PID<T>, Future<R> (T::*)(void)))(
+           const PID<T>&, Future<R> (T::*)(void))>
+defer(const Process<T>& process, Future<R> (T::*method)(void))
+{
+  return defer(process.self(), method);
+}
+
+template <typename R, typename T>
+_Defer<Future<R>(*(PID<T>, Future<R> (T::*)(void)))
+       (const PID<T>&, Future<R> (T::*)(void))>
+defer(const Process<T>* process, Future<R> (T::*method)(void))
+{
+  return defer(process->self(), method);
+}
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<Future<R>(*(PID<T>,                                            \
+                     Future<R> (T::*)(ENUM_PARAMS(N, P)),               \
+                     ENUM_PARAMS(N, A)))                                \
+         (const PID<T>&,                                                \
+          Future<R> (T::*)(ENUM_PARAMS(N, P)),                          \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const PID<T>& pid,                                              \
+        Future<R> (T::*method)(ENUM_PARAMS(N, P)),                      \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    Future<R> (*dispatch)(const PID<T>&,                                \
+                          Future<R> (T::*)(ENUM_PARAMS(N, P)),          \
+                          ENUM_PARAMS(N, P)) =                          \
+      &process::template dispatch<R, T, ENUM_PARAMS(N, P), ENUM_PARAMS(N, P)>; \
+    return std::tr1::bind(dispatch, pid, method, ENUM_PARAMS(N, a));    \
+  }                                                                     \
+                                                                        \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<Future<R>(*(PID<T>,                                            \
+                     Future<R> (T::*)(ENUM_PARAMS(N, P)),               \
+                     ENUM_PARAMS(N, A)))                                \
+         (const PID<T>&,                                                \
+          Future<R> (T::*)(ENUM_PARAMS(N, P)),                          \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const Process<T>& process,                                      \
+        Future<R> (T::*method)(ENUM_PARAMS(N, P)),                      \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    return defer(process.self(), method, ENUM_PARAMS(N, a));            \
+  }                                                                     \
+                                                                        \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<Future<R>(*(PID<T>,                                            \
+                     Future<R> (T::*)(ENUM_PARAMS(N, P)),               \
+                     ENUM_PARAMS(N, A)))                                \
+         (const PID<T>&,                                                \
+          Future<R> (T::*)(ENUM_PARAMS(N, P)),                          \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const Process<T>* process,                                      \
+        Future<R> (T::*method)(ENUM_PARAMS(N, P)),                      \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    return defer(process->self(), method, ENUM_PARAMS(N, a));           \
+  }
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+
+// Next, definitions of defer for methods returning a value:
+//
+// template <typename R, typename T, typename ...P>
+// Deferred<Future<R>(void)> void defer(const PID<T>& pid,
+//                                      R (T::*method)(P...),
+//                                      P... p)
+// {
+//   Future<R> (*dispatch)(const PID<T>&, R (T::*)(P...), P...) =
+//     &process::template dispatch<R, T, P...>;
+//
+//   return Deferred<Future<R>(void)>(
+//       std::tr1::bind(dispatch, pid, method, std::forward<P>(p)...));
+// }
+
+template <typename R, typename T>
+_Defer<Future<R>(*(PID<T>, R (T::*)(void)))
+       (const PID<T>&, R (T::*)(void))>
+defer(const PID<T>& pid, R (T::*method)(void))
+{
+  Future<R> (*dispatch)(const PID<T>&, R (T::*)(void)) =
+    &process::template dispatch<R, T>;
+  return std::tr1::bind(dispatch, pid, method);
+}
+
+template <typename R, typename T>
+_Defer<Future<R>(*(PID<T>, R (T::*)(void)))
+       (const PID<T>&, R (T::*)(void))>
+defer(const Process<T>& process, R (T::*method)(void))
+{
+  return defer(process.self(), method);
+}
+
+template <typename R, typename T>
+_Defer<Future<R>(*(PID<T>, R (T::*)(void)))
+       (const PID<T>&, R (T::*)(void))>
+defer(const Process<T>* process, R (T::*method)(void))
+{
+  return defer(process->self(), method);
+}
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<Future<R>(*(PID<T>,                                            \
+                     R (T::*)(ENUM_PARAMS(N, P)),                       \
+                     ENUM_PARAMS(N, A)))                                \
+         (const PID<T>&,                                                \
+          R (T::*)(ENUM_PARAMS(N, P)),                                  \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const PID<T>& pid,                                              \
+        R (T::*method)(ENUM_PARAMS(N, P)),                              \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    Future<R> (*dispatch)(const PID<T>&,                                \
+                          R (T::*)(ENUM_PARAMS(N, P)),                  \
+                          ENUM_PARAMS(N, P)) =                          \
+      &process::template dispatch<R, T, ENUM_PARAMS(N, P), ENUM_PARAMS(N, P)>; \
+    return std::tr1::bind(dispatch, pid, method, ENUM_PARAMS(N, a));    \
+  }                                                                     \
+                                                                        \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<Future<R>(*(PID<T>,                                            \
+                     R (T::*)(ENUM_PARAMS(N, P)),                       \
+                     ENUM_PARAMS(N, A)))                                \
+         (const PID<T>&,                                                \
+          R (T::*)(ENUM_PARAMS(N, P)),                                  \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const Process<T>& process,                                      \
+        R (T::*method)(ENUM_PARAMS(N, P)),                              \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    return defer(process.self(), method, ENUM_PARAMS(N, a));            \
+  }                                                                     \
+                                                                        \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  _Defer<Future<R>(*(PID<T>,                                            \
+                     R (T::*)(ENUM_PARAMS(N, P)),                       \
+                     ENUM_PARAMS(N, A)))                                \
+         (const PID<T>&,                                                \
+          R (T::*)(ENUM_PARAMS(N, P)),                                  \
+          ENUM_PARAMS(N, P))>                                           \
+  defer(const Process<T>* process,                                      \
+        R (T::*method)(ENUM_PARAMS(N, P)),                              \
+        ENUM_BINARY_PARAMS(N, A, a))                                    \
+  {                                                                     \
+    return defer(process->self(), method, ENUM_PARAMS(N, a));           \
+  }
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+
+namespace internal {
+
+inline void invoker(
+    ProcessBase* _,
+    const std::tr1::function<void(void)>& f)
+{
+  f();
+}
+
+inline void dispatcher(
+    const UPID& pid,
+    const std::tr1::function<void(void)>& f)
+{
+  std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > invoker(
+      new std::tr1::function<void(ProcessBase*)>(
+          std::tr1::bind(&internal::invoker,
+                         std::tr1::placeholders::_1,
+                         f)));
+
+  internal::dispatch(pid, invoker);
+}
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <ENUM_PARAMS(N, typename A)>                                 \
+  void CAT(invoker, N)(                                                 \
+      ProcessBase* _,                                                   \
+      const std::tr1::function<void(ENUM_PARAMS(N, A))>& f,             \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    f(ENUM_PARAMS(N, a));                                               \
+  }                                                                     \
+                                                                        \
+  template <ENUM_PARAMS(N, typename A)>                                 \
+  void CAT(dispatcher, N)(                                              \
+      const UPID& pid,                                                  \
+      const std::tr1::function<void(ENUM_PARAMS(N, A))>& f,             \
+      ENUM_BINARY_PARAMS(N, A, a))                                      \
+  {                                                                     \
+    std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > invoker( \
+        new std::tr1::function<void(ProcessBase*)>(                     \
+            std::tr1::bind(&internal::CAT(invoker, N)<ENUM_PARAMS(N, A)>, \
+                           std::tr1::placeholders::_1,                  \
+                           f,                                           \
+                           ENUM_PARAMS(N, a))));                        \
+                                                                        \
+    internal::dispatch(pid, invoker);                                   \
+  }
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+
+  // We can't easily use 'std::tr1::_Placeholder<X>' when doing macro
+  // expansion via ENUM_BINARY_PARAMS because compilers don't like it
+  // when you try and concatenate '<' 'N' '>'. Thus, we typedef them.
+#define TEMPLATE(Z, N, DATA)                            \
+  typedef std::tr1::_Placeholder<INC(N)> _ ## N;
+
+  REPEAT(10, TEMPLATE, _)
+#undef TEMPLATE
+
+} // namespace internal {
+
+
+// Now we define defer calls for functions and bind statements.
+inline Deferred<void(void)> defer(const std::tr1::function<void(void)>& f)
+{
+  if (__process__ != NULL) {
+    // In C++11:
+    //   const UPID pid = __process__->self();
+    //   return []() {
+    //     internal::dispatch(pid, [](ProcessBase* _) { f(); });
+    //   }
+    return std::tr1::function<void(void)>(
+          std::tr1::bind(&internal::dispatcher,
+                         __process__->self(),
+                         f));
+  }
+
+  return __executor__->defer(f);
+}
+
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <ENUM_PARAMS(N, typename A)>                                 \
+  Deferred<void(ENUM_PARAMS(N, A))> defer(                              \
+      const std::tr1::function<void(ENUM_PARAMS(N, A))>& f)             \
+  {                                                                     \
+    if (__process__ != NULL) {                                          \
+      return std::tr1::function<void(ENUM_PARAMS(N, A))>(               \
+          std::tr1::bind(&internal::CAT(dispatcher, N)<ENUM_PARAMS(N, A)>, \
+                         __process__->self(),                           \
+                         f,                                             \
+                         ENUM_BINARY_PARAMS(N, internal::_, () INTERCEPT))); \
+    }                                                                   \
+                                                                        \
+    return __executor__->defer(f);                                      \
+  }                                                                     \
+                                                                        \
+  template <typename R, ENUM_PARAMS(N, typename A)>                     \
+  Deferred<Future<R>(ENUM_PARAMS(N, A))> defer(                         \
+      const std::tr1::function<Future<R>(ENUM_PARAMS(N, A))>& f)        \
+  {                                                                     \
+    if (__process__ != NULL) {                                          \
+      return std::tr1::function<Future<R>(ENUM_PARAMS(N, A))>(          \
+          std::tr1::bind(&internal::CAT(dispatcher, N)<ENUM_PARAMS(N, A)>, \
+                         __process__->self(),                           \
+                         f,                                             \
+                         ENUM_BINARY_PARAMS(N, internal::_, () INTERCEPT))); \
+    }                                                                   \
+                                                                        \
+    return __executor__->defer(f);                                      \
+  }
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+} // namespace process {
+
+#endif // __PROCESS_DEFER_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/deferred.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/deferred.hpp b/3rdparty/libprocess/include/process/deferred.hpp
new file mode 100644
index 0000000..8907e80
--- /dev/null
+++ b/3rdparty/libprocess/include/process/deferred.hpp
@@ -0,0 +1,136 @@
+#ifndef __PROCESS_DEFERRED_HPP__
+#define __PROCESS_DEFERRED_HPP__
+
+#include <tr1/functional>
+
+#include <process/future.hpp>
+#include <process/pid.hpp>
+
+#include <stout/preprocessor.hpp>
+
+namespace process {
+
+// Forward declarations (removing these produces cryptic compiler
+// errors even though we are just using them to declare friends).
+class Executor;
+template <typename _F> struct _Defer;
+
+
+// Acts like a function call but runs within an asynchronous execution
+// context such as an Executor or a ProcessBase (enforced because only
+// an executor or the 'defer' routines are allowed to create them).
+template <typename F>
+struct Deferred : std::tr1::function<F>
+{
+private:
+  // Only an Executor and the 'defer' routines can create these.
+  friend class Executor;
+
+  template <typename _F> friend struct _Defer;
+
+  friend Deferred<void(void)> defer(const std::tr1::function<void(void)>& f);
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <ENUM_PARAMS(N, typename A)>                                 \
+  friend Deferred<void(ENUM_PARAMS(N, A))> defer(                       \
+      const std::tr1::function<void(ENUM_PARAMS(N, A))>& f);
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+  Deferred(const std::tr1::function<F>& f) : std::tr1::function<F>(f) {}
+};
+
+
+// The result of invoking the 'defer' routines is actually an internal
+// type, effectively just a wrapper around the result of invoking
+// 'std::tr1::bind'. However, we want the result of bind to be
+// castable to a 'Deferred' but we don't want anyone to be able to
+// create a 'Deferred' so we use a level-of-indirection via this type.
+template <typename F>
+struct _Defer : std::tr1::_Bind<F>
+{
+  template <typename _F>
+  operator Deferred<_F> ()
+  {
+    return Deferred<_F>(std::tr1::function<_F>(*this));
+  }
+
+private:
+  friend class Executor;
+
+  template <typename T>
+  friend _Defer<void(*(PID<T>, void (T::*)(void)))
+                (const PID<T>&, void (T::*)(void))>
+  defer(const PID<T>& pid, void (T::*method)(void));
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  friend _Defer<void(*(PID<T>,                                          \
+                       void (T::*)(ENUM_PARAMS(N, P)),                  \
+                       ENUM_PARAMS(N, A)))                              \
+                (const PID<T>&,                                         \
+                 void (T::*)(ENUM_PARAMS(N, P)),                        \
+                 ENUM_PARAMS(N, P))>                                    \
+  defer(const PID<T>& pid,                                              \
+        void (T::*method)(ENUM_PARAMS(N, P)),                           \
+        ENUM_BINARY_PARAMS(N, A, a));
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+  template <typename R, typename T>
+  friend _Defer<Future<R>(*(PID<T>, Future<R> (T::*)(void)))(
+      const PID<T>&, Future<R> (T::*)(void))>
+  defer(const PID<T>& pid, Future<R> (T::*method)(void));
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  friend _Defer<Future<R>(*(PID<T>,                                     \
+                            Future<R> (T::*)(ENUM_PARAMS(N, P)),        \
+                            ENUM_PARAMS(N, A)))                         \
+                (const PID<T>&,                                         \
+                 Future<R> (T::*)(ENUM_PARAMS(N, P)),                   \
+                 ENUM_PARAMS(N, P))>                                    \
+  defer(const PID<T>& pid,                                              \
+        Future<R> (T::*method)(ENUM_PARAMS(N, P)),                      \
+        ENUM_BINARY_PARAMS(N, A, a));
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+  template <typename R, typename T>
+  friend _Defer<Future<R>(*(PID<T>, R (T::*)(void)))(
+      const PID<T>&, R (T::*)(void))>
+  defer(const PID<T>& pid, R (T::*method)(void));
+
+#define TEMPLATE(Z, N, DATA)                                            \
+  template <typename R,                                                 \
+            typename T,                                                 \
+            ENUM_PARAMS(N, typename P),                                 \
+            ENUM_PARAMS(N, typename A)>                                 \
+  friend _Defer<Future<R>(*(PID<T>,                                     \
+                            R (T::*)(ENUM_PARAMS(N, P)),                \
+                            ENUM_PARAMS(N, A)))                         \
+                (const PID<T>&,                                         \
+                 R (T::*)(ENUM_PARAMS(N, P)),                           \
+                 ENUM_PARAMS(N, P))>                                    \
+  defer(const PID<T>& pid,                                              \
+        R (T::*method)(ENUM_PARAMS(N, P)),                              \
+        ENUM_BINARY_PARAMS(N, A, a));
+
+  REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+  _Defer(const std::tr1::_Bind<F>& b)
+    : std::tr1::_Bind<F>(b) {}
+};
+
+} // namespace process {
+
+#endif // __PROCESS_DEFERRED_HPP__