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:40:39 UTC
[01/35] Updated libprocess to use '3rdparty' instead of 'third_party'.
Updated Branches:
refs/heads/master f122e613d -> cc5e1e7b7
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/tests/os_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/os_tests.cpp b/third_party/libprocess/third_party/stout/tests/os_tests.cpp
deleted file mode 100644
index 047778d..0000000
--- a/third_party/libprocess/third_party/stout/tests/os_tests.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/proc_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/proc_tests.cpp b/third_party/libprocess/third_party/stout/tests/proc_tests.cpp
deleted file mode 100644
index 2305ef5..0000000
--- a/third_party/libprocess/third_party/stout/tests/proc_tests.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * 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/bc531d3c/third_party/libprocess/third_party/stout/tests/strings_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/strings_tests.cpp b/third_party/libprocess/third_party/stout/tests/strings_tests.cpp
deleted file mode 100644
index 7ec9446..0000000
--- a/third_party/libprocess/third_party/stout/tests/strings_tests.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/uuid_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/uuid_tests.cpp b/third_party/libprocess/third_party/stout/tests/uuid_tests.cpp
deleted file mode 100644
index ad1d986..0000000
--- a/third_party/libprocess/third_party/stout/tests/uuid_tests.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/versions.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/versions.am b/third_party/libprocess/third_party/versions.am
deleted file mode 100644
index 9b6a829..0000000
--- a/third_party/libprocess/third_party/versions.am
+++ /dev/null
@@ -1,11 +0,0 @@
-# This automake utility file is included from third_party/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
[30/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/flags/loader.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
new file mode 100644
index 0000000..e5eaf24
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
@@ -0,0 +1,109 @@
+#ifndef __STOUT_FLAGS_LOADER_HPP__
+#define __STOUT_FLAGS_LOADER_HPP__
+
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+#include <stout/flags/parse.hpp>
+
+namespace flags {
+
+// Forward declaration.
+class FlagsBase;
+
+template <typename T>
+struct Loader
+{
+ static Try<Nothing> load(
+ T* flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ *flag = t.get();
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename T>
+struct OptionLoader
+{
+ static Try<Nothing> load(
+ Option<T>* flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ *flag = Option<T>::some(t.get());
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename F, typename T>
+struct MemberLoader
+{
+ static Try<Nothing> load(
+ FlagsBase* base,
+ T F::*flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ F* f = dynamic_cast<F*>(base);
+ if (f != NULL) {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ f->*flag = t.get();
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename F, typename T>
+struct OptionMemberLoader
+{
+ static Try<Nothing> load(
+ FlagsBase* base,
+ Option<T> F::*flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ F* f = dynamic_cast<F*>(base);
+ if (f != NULL) {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ f->*flag = Option<T>::some(t.get());
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ }
+ return Nothing();
+ }
+};
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_LOADER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/flags/parse.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
new file mode 100644
index 0000000..54eb35c
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
@@ -0,0 +1,55 @@
+#ifndef __STOUT_FLAGS_PARSE_HPP__
+#define __STOUT_FLAGS_PARSE_HPP__
+
+#include <sstream> // For istringstream.
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/duration.hpp>
+#include <stout/error.hpp>
+#include <stout/try.hpp>
+
+namespace flags {
+
+template <typename T>
+Try<T> parse(const std::string& value)
+{
+ T t;
+ std::istringstream in(value);
+ in >> t;
+ if (!in.good() && !in.eof()) {
+ return Error("Failed to convert into required type");
+ }
+ return t;
+}
+
+
+template <>
+inline Try<std::string> parse(const std::string& value)
+{
+ return value;
+}
+
+
+template <>
+inline Try<bool> parse(const std::string& value)
+{
+ if (value == "true" || value == "1") {
+ return true;
+ } else if (value == "false" || value == "0") {
+ return false;
+ }
+ return Error("Expecting a boolean (e.g., true or false)");
+}
+
+
+template <>
+inline Try<Duration> parse(const std::string& value)
+{
+ return Duration::parse(value);
+}
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_PARSE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/foreach.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/foreach.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/foreach.hpp
new file mode 100644
index 0000000..0afe285
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/foreach.hpp
@@ -0,0 +1,51 @@
+#ifndef __STOUT_FOREACH_HPP__
+#define __STOUT_FOREACH_HPP__
+
+#include <boost/foreach.hpp>
+
+#include <boost/tuple/tuple.hpp>
+
+namespace __foreach__ {
+
+// NOTE: This is a copied from Boost
+// (boost/tuple/detail/tuple_basic_no_partial_spec.hpp) because the
+// new 'boost::tuples::ignore' does not work in our 'foreachkey' and
+// 'foreachvalue'.
+struct swallow_assign {
+ template<typename T>
+ swallow_assign const& operator=(const T&) const {
+ return *this;
+ }
+};
+
+swallow_assign const ignore = swallow_assign();
+
+} // namespace __foreach__ {
+
+#define BOOST_FOREACH_PAIR(VARFIRST, VARSECOND, COL) \
+ BOOST_FOREACH_PREAMBLE() \
+ if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \
+ if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else \
+ if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_END(COL)) {} else \
+ for (bool BOOST_FOREACH_ID(_foreach_continue) = true, BOOST_FOREACH_ID(_foreach_onetime) = true; \
+ BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_DONE(COL); \
+ BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0) \
+ if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_onetime))) {} else \
+ for (VARFIRST = BOOST_FOREACH_DEREF(COL).first; \
+ !BOOST_FOREACH_ID(_foreach_onetime); \
+ BOOST_FOREACH_ID(_foreach_onetime) = true) \
+ if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \
+ for (VARSECOND = BOOST_FOREACH_DEREF(COL).second; \
+ !BOOST_FOREACH_ID(_foreach_continue); \
+ BOOST_FOREACH_ID(_foreach_continue) = true)
+
+#define foreach BOOST_FOREACH
+#define foreachpair BOOST_FOREACH_PAIR
+
+#define foreachkey(VAR, COL) \
+ foreachpair (VAR, __foreach__::ignore, COL)
+
+#define foreachvalue(VAR, COL) \
+ foreachpair (__foreach__::ignore, VAR, COL)
+
+#endif // __STOUT_FOREACH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp
new file mode 100644
index 0000000..71b5986
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/format.hpp
@@ -0,0 +1,343 @@
+#ifndef __STOUT_FORMAT_HPP__
+#define __STOUT_FORMAT_HPP__
+
+#include <stdarg.h> // For 'va_list', 'va_start', 'va_end'.
+#include <stdio.h> // For 'vasprintf'.
+
+#include <string>
+
+#include <tr1/type_traits> // For 'is_pod'.
+
+#include "error.hpp"
+#include "try.hpp"
+#include "stringify.hpp"
+
+
+// The 'strings::format' functions produces strings based on the
+// printf family of functions. Except, unlike the printf family of
+// functions, the 'strings::format' routines attempt to "stringify"
+// any arguments that are not POD types (i.e., "plain old data":
+// primitives, pointers, certain structs/classes and unions,
+// etc). This enables passing structs/classes to 'strings::format'
+// provided there is a definition/specialization of 'ostream::operator
+// <<' available for that type. Note that the '%s' format specifier is
+// expected for each argument that gets stringified. A specialization
+// for std::string is also provided so that std::string::c_str is not
+// necessary (but again, '%s' is expected as the format specifier).
+
+namespace strings {
+namespace internal {
+
+Try<std::string> format(const std::string& fmt, va_list args);
+Try<std::string> format(const std::string& fmt, ...);
+
+template <typename T, bool b>
+struct stringify;
+
+} // namespace internal {
+
+
+#if __cplusplus >= 201103L
+template <typename ...T>
+Try<std::string> format(const std::string& s, const T& ...t)
+{
+ return internal::format(
+ s,
+ internal::stringify<T, !std::is_pod<T>::value>(t).get()...);
+}
+#else
+template <typename T1>
+Try<std::string> format(const std::string& s,
+ const T1& t1)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get());
+}
+
+
+template <typename T1,
+ typename T2>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T1>::value>(t2).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6,
+ typename T7>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6,
+ const T7& t7)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
+ internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6,
+ typename T7,
+ typename T8>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6,
+ const T7& t7,
+ const T8& t8)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
+ internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
+ internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6,
+ typename T7,
+ typename T8,
+ typename T9>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6,
+ const T7& t7,
+ const T8& t8,
+ const T9& t9)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
+ internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
+ internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get(),
+ internal::stringify<T9, !std::tr1::is_pod<T9>::value>(t9).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6,
+ typename T7,
+ typename T8,
+ typename T9,
+ typename T10>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6,
+ const T7& t7,
+ const T8& t8,
+ const T9& t9,
+ const T10& t10)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
+ internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
+ internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get(),
+ internal::stringify<T9, !std::tr1::is_pod<T9>::value>(t9).get(),
+ internal::stringify<T10, !std::tr1::is_pod<T10>::value>(t10).get());
+}
+#endif // __cplusplus >= 201103L
+
+
+namespace internal {
+
+inline Try<std::string> format(const std::string& fmt, va_list args)
+{
+ char* temp;
+ if (vasprintf(&temp, fmt.c_str(), args) == -1) {
+ // Note that temp is undefined, so we do not need to call free.
+ return Error("Failed to format '" + fmt + "' (possibly out of memory)");
+ }
+ std::string result(temp);
+ free(temp);
+ return result;
+}
+
+
+inline Try<std::string> format(const std::string& fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ const Try<std::string>& result = format(fmt, args);
+ va_end(args);
+ return result;
+}
+
+
+template <typename T>
+struct stringify<T, false>
+{
+ stringify(const T& _t) : t(_t) {}
+ const T& get() { return t; }
+ const T& t;
+};
+
+
+template <typename T>
+struct stringify<T, true>
+{
+ stringify(const T& _t) : s(::stringify(_t)) {}
+ const char* get() { return s.c_str(); }
+
+ // NOTE: We need to do the copy here, because the temporary returned by
+ // ::stringify() doesn't outlive the get() call inside strings::format().
+ // TODO(vinod): Figure out a fix for using const ref here.
+ const std::string s;
+};
+
+
+template <>
+struct stringify<std::string, true>
+{
+ stringify(const std::string& _s) : s(_s) {}
+ const char* get() { return s.c_str(); }
+ const std::string& s;
+};
+
+} // namespace internal {
+} // namespace strings {
+
+#endif // __STOUT_FORMAT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/fs.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/fs.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/fs.hpp
new file mode 100644
index 0000000..c1a05b5
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/fs.hpp
@@ -0,0 +1,53 @@
+#ifndef __STOUT_FS_HPP__
+#define __STOUT_FS_HPP__
+
+#include <unistd.h> // For symlink.
+
+#include <sys/statvfs.h>
+
+#include <string>
+
+#include "bytes.hpp"
+#include "error.hpp"
+#include "nothing.hpp"
+#include "try.hpp"
+
+// TODO(bmahler): Migrate the appropriate 'os' namespace funtions here.
+namespace fs {
+
+// Returns the total available disk size in bytes.
+inline Try<Bytes> available(const std::string& path = "/")
+{
+ struct statvfs buf;
+ if (::statvfs(path.c_str(), &buf) < 0) {
+ return ErrnoError();
+ }
+ return Bytes(buf.f_bavail * buf.f_frsize);
+}
+
+
+// Returns relative disk usage of the file system that the given path
+// is mounted at.
+inline Try<double> usage(const std::string& path = "/")
+{
+ struct statvfs buf;
+ if (statvfs(path.c_str(), &buf) < 0) {
+ return ErrnoError("Error invoking statvfs on '" + path + "'");
+ }
+ return (double) (buf.f_blocks - buf.f_bfree) / buf.f_blocks;
+}
+
+
+inline Try<Nothing> symlink(
+ const std::string& original,
+ const std::string& link)
+{
+ if (::symlink(original.c_str(), link.c_str()) < 0) {
+ return ErrnoError();
+ }
+ return Nothing();
+}
+
+} // namespace fs {
+
+#endif // __STOUT_FS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/gtest.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/gtest.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/gtest.hpp
new file mode 100644
index 0000000..3c34124
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/gtest.hpp
@@ -0,0 +1,122 @@
+#ifndef __STOUT_GTEST_HPP__
+#define __STOUT_GTEST_HPP__
+
+#include <gtest/gtest.h>
+
+#include <string>
+
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+#include <stout/try.hpp>
+
+
+template <typename T>
+::testing::AssertionResult AssertSome(
+ const char* expr,
+ const Option<T>& actual)
+{
+ if (actual.isNone()) {
+ return ::testing::AssertionFailure()
+ << expr << " is NONE";
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T>
+::testing::AssertionResult AssertSome(
+ const char* expr,
+ const Try<T>& actual)
+{
+ if (actual.isError()) {
+ return ::testing::AssertionFailure()
+ << expr << ": " << actual.error();
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T>
+::testing::AssertionResult AssertSome(
+ const char* expr,
+ const Result<T>& actual)
+{
+ if (actual.isNone()) {
+ return ::testing::AssertionFailure()
+ << expr << " is NONE";
+ } else if (actual.isError()) {
+ return ::testing::AssertionFailure()
+ << expr << ": " << actual.error();
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T1, typename T2>
+::testing::AssertionResult AssertSomeEq(
+ const char* expectedExpr,
+ const char* actualExpr,
+ const T1& expected,
+ const T2& actual) // Duck typing!
+{
+ const ::testing::AssertionResult result = AssertSome(actualExpr, actual);
+
+ if (result) {
+ if (expected == actual.get()) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Value of: (" << actualExpr << ").get()\n"
+ << " Actual: " << ::testing::PrintToString(actual.get()) << "\n"
+ << "Expected: " << expectedExpr << "\n"
+ << "Which is: " << ::testing::PrintToString(expected);
+ }
+ }
+
+ return result;
+}
+
+
+#define ASSERT_SOME(actual) \
+ ASSERT_PRED_FORMAT1(AssertSome, actual)
+
+
+#define EXPECT_SOME(actual) \
+ EXPECT_PRED_FORMAT1(AssertSome, actual)
+
+
+#define ASSERT_SOME_EQ(expected, actual) \
+ ASSERT_PRED_FORMAT2(AssertSomeEq, expected, actual)
+
+
+#define EXPECT_SOME_EQ(expected, actual) \
+ EXPECT_PRED_FORMAT2(AssertSomeEq, expected, actual)
+
+
+#define ASSERT_SOME_TRUE(actual) \
+ ASSERT_PRED_FORMAT2(AssertSomeEq, true, actual)
+
+
+#define EXPECT_SOME_TRUE(actual) \
+ EXPECT_PRED_FORMAT2(AssertSomeEq, true, actual)
+
+
+#define ASSERT_SOME_FALSE(actual) \
+ ASSERT_PRED_FORMAT2(AssertSomeEq, false, actual)
+
+
+#define EXPECT_SOME_FALSE(actual) \
+ EXPECT_PRED_FORMAT2(AssertSomeEq, false, actual)
+
+
+#define ASSERT_ERROR(actual) \
+ ASSERT_TRUE(actual.isError())
+
+
+#define EXPECT_ERROR(actual) \
+ EXPECT_TRUE(actual.isError())
+
+#endif // __STOUT_GTEST_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp
new file mode 100644
index 0000000..ef36f1b
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/gzip.hpp
@@ -0,0 +1,149 @@
+#ifndef __STOUT_GZIP_HPP__
+#define __STOUT_GZIP_HPP__
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include <string>
+
+#include "error.hpp"
+#include "try.hpp"
+
+// Compression utilities.
+// TODO(bmahler): Provide streaming compression / decompression as well.
+namespace gzip {
+
+// We use a 16KB buffer with zlib compression / decompression.
+#define GZIP_BUFFER_SIZE 16384
+
+// Returns a gzip compressed version of the provided string.
+// The compression level should be within the range [-1, 9].
+// See zlib.h:
+// #define Z_NO_COMPRESSION 0
+// #define Z_BEST_SPEED 1
+// #define Z_BEST_COMPRESSION 9
+// #define Z_DEFAULT_COMPRESSION (-1)
+inline Try<std::string> compress(
+ const std::string& decompressed,
+#ifdef HAVE_LIBZ
+ int level = Z_DEFAULT_COMPRESSION)
+#else
+ int level = -1)
+#endif
+{
+#ifndef HAVE_LIBZ
+ return Error("libz is not available");
+#else
+ // Verify the level is within range.
+ if (!(level == Z_DEFAULT_COMPRESSION ||
+ (level >= Z_NO_COMPRESSION && level <= Z_BEST_COMPRESSION))) {
+ return Error("Invalid compression level: " + level);
+ }
+
+ z_stream_s stream;
+ stream.next_in =
+ const_cast<Bytef*>(reinterpret_cast<const Bytef*>(decompressed.data()));
+ stream.avail_in = decompressed.length();
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ int code = deflateInit2(
+ &stream,
+ level, // Compression level.
+ Z_DEFLATED, // Compression method.
+ MAX_WBITS + 16, // Zlib magic for gzip compression / decompression.
+ 8, // Default memLevel value.
+ Z_DEFAULT_STRATEGY);
+
+ if (code != Z_OK) {
+ return Error("Failed to initialize zlib: " + std::string(stream.msg));
+ }
+
+ // Build up the compressed result.
+ Bytef buffer[GZIP_BUFFER_SIZE];
+ std::string result = "";
+ do {
+ stream.next_out = buffer;
+ stream.avail_out = GZIP_BUFFER_SIZE;
+ code = deflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+ if (code != Z_OK && code != Z_STREAM_END) {
+ Error error(std::string(stream.msg));
+ deflateEnd(&stream);
+ return error;
+ }
+
+ // Consume output and reset the buffer.
+ result.append(
+ reinterpret_cast<char*>(buffer),
+ GZIP_BUFFER_SIZE - stream.avail_out);
+ stream.next_out = buffer;
+ stream.avail_out = GZIP_BUFFER_SIZE;
+ } while (code != Z_STREAM_END);
+
+ code = deflateEnd(&stream);
+ if (code != Z_OK) {
+ return Error("Failed to clean up zlib: " + std::string(stream.msg));
+ }
+ return result;
+#endif // HAVE_LIBZ
+}
+
+
+// Returns a gzip decompressed version of the provided string.
+inline Try<std::string> decompress(const std::string& compressed)
+{
+#ifndef HAVE_LIBZ
+ return Error("libz is not available");
+#else
+ z_stream_s stream;
+ stream.next_in =
+ const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
+ stream.avail_in = compressed.length();
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ int code = inflateInit2(
+ &stream,
+ MAX_WBITS + 16); // Zlib magic for gzip compression / decompression.
+
+ if (code != Z_OK) {
+ return Error("Failed to initialize zlib: " + std::string(stream.msg));
+ }
+
+ // Build up the decompressed result.
+ Bytef buffer[GZIP_BUFFER_SIZE];
+ std::string result = "";
+ do {
+ stream.next_out = buffer;
+ stream.avail_out = GZIP_BUFFER_SIZE;
+ code = inflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+ if (code != Z_OK && code != Z_STREAM_END) {
+ Error error(std::string(stream.msg));
+ inflateEnd(&stream);
+ return error;
+ }
+
+ // Consume output and reset the buffer.
+ result.append(
+ reinterpret_cast<char*>(buffer),
+ GZIP_BUFFER_SIZE - stream.avail_out);
+ stream.next_out = buffer;
+ stream.avail_out = GZIP_BUFFER_SIZE;
+ } while (code != Z_STREAM_END);
+
+ code = inflateEnd(&stream);
+ if (code != Z_OK) {
+ return Error("Failed to clean up zlib: " + std::string(stream.msg));
+ }
+ return result;
+#endif // HAVE_LIBZ
+}
+
+} // namespace gzip {
+
+#endif // __STOUT_GZIP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/hashmap.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/hashmap.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/hashmap.hpp
new file mode 100644
index 0000000..796cb50
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/hashmap.hpp
@@ -0,0 +1,102 @@
+#ifndef __STOUT_HASHMAP_HPP__
+#define __STOUT_HASHMAP_HPP__
+
+#include <boost/get_pointer.hpp>
+#include <boost/unordered_map.hpp>
+
+#include "hashset.hpp"
+#include "foreach.hpp"
+#include "none.hpp"
+#include "option.hpp"
+
+
+// Provides a hash map via Boost's 'unordered_map'. For most intensive
+// purposes this could be accomplished with a templated typedef, but
+// those don't exist (until C++-11). Also, doing it this way allows us
+// to add functionality, or better naming of existing functionality,
+// etc.
+
+template <typename Key, typename Value>
+class hashmap : public boost::unordered_map<Key, Value>
+{
+public:
+ // An explicit default constructor is needed so
+ // 'const hashmap<T> map;' is not an error.
+ hashmap() {}
+
+ // Checks whether this map contains a binding for a key.
+ bool contains(const Key& key) const
+ {
+ return boost::unordered_map<Key, Value>::count(key) > 0;
+ }
+
+ // Checks whether there exists a bound value in this map.
+ bool containsValue(const Value& v) const
+ {
+ foreachvalue (const Value& value, *this) {
+ if (value == v) {
+ return true;
+ }
+ }
+ }
+
+ // Returns an Option for the binding to the key.
+ Option<Value> get(const Key& key) const
+ {
+ typedef typename boost::unordered_map<Key, Value>::const_iterator
+ const_iterator;
+ const_iterator it = boost::unordered_map<Key, Value>::find(key);
+ if (it == boost::unordered_map<Key, Value>::end()) {
+ return None();
+ }
+ return it->second;
+ }
+
+ // Returns the set of keys in this map.
+ hashset<Key> keys() const
+ {
+ hashset<Key> result;
+ foreachkey (const Key& key, *this) {
+ result.insert(key);
+ }
+ return result;
+ }
+
+ // Returns the set of values in this map.
+ hashset<Value> values() const
+ {
+ hashset<Value> result;
+ foreachvalue (const Value& value, *this) {
+ result.insert(value);
+ }
+ return result;
+ }
+
+ // Checks whether there exists a value in this map that returns the
+ // a result equal to 'r' when the specified method is invoked.
+ template <typename R, typename T>
+ bool existsValue(R (T::*method)(), R r) const
+ {
+ foreachvalue (const Value& value, *this) {
+ const T* t = boost::get_pointer(value);
+ if (t->*method() == r) {
+ return true;
+ }
+ }
+ }
+
+ // Checks whether there exists a value in this map whose specified
+ // member is equal to 'r'.
+ template <typename R, typename T>
+ bool existsValue(R (T::*member), R r) const
+ {
+ foreachvalue (const Value& value, *this) {
+ const T* t = boost::get_pointer(value);
+ if (t->*member == r) {
+ return true;
+ }
+ }
+ }
+};
+
+#endif // __STOUT_HASHMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/hashset.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/hashset.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/hashset.hpp
new file mode 100644
index 0000000..f584545
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/hashset.hpp
@@ -0,0 +1,57 @@
+#ifndef __STOUT_HASHSET_HPP__
+#define __STOUT_HASHSET_HPP__
+
+#include <boost/get_pointer.hpp>
+#include <boost/unordered_set.hpp>
+
+#include "foreach.hpp"
+
+
+// Provides a hash set via Boost's 'unordered_set'. For most intensive
+// purposes this could be accomplished with a templated typedef, but
+// those don't exist (until C++-11). Also, doing it this way allows us
+// to add functionality, or better naming of existing functionality,
+// etc.
+
+template <typename Elem>
+class hashset : public boost::unordered_set<Elem>
+{
+public:
+ // An explicit default constructor is needed so
+ // 'const hashset<T> map;' is not an error.
+ hashset() {}
+
+ // Checks whether this map contains a binding for a key.
+ bool contains(const Elem& elem) const
+ {
+ return boost::unordered_set<Elem>::count(elem) > 0;
+ }
+
+ // Checks whether there exists a value in this set that returns the
+ // a result equal to 'r' when the specified method is invoked.
+ template <typename R, typename T>
+ bool exists(R (T::*method)(), R r) const
+ {
+ foreach (const Elem& elem, *this) {
+ const T* t = boost::get_pointer(elem);
+ if (t->*method() == r) {
+ return true;
+ }
+ }
+ }
+
+ // Checks whether there exists an element in this set whose
+ // specified member is equal to 'r'.
+ template <typename R, typename T>
+ bool exists(R (T::*member), R r) const
+ {
+ foreach (const Elem& elem, *this) {
+ const T* t = boost::get_pointer(elem);
+ if (t->*member == r) {
+ return true;
+ }
+ }
+ }
+};
+
+#endif // __STOUT_HASHSET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp
new file mode 100644
index 0000000..e2cd4f2
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/json.hpp
@@ -0,0 +1,202 @@
+#ifndef __STOUT_JSON__
+#define __STOUT_JSON__
+
+#include <iomanip>
+#include <iostream>
+#include <list>
+#include <map>
+#include <string>
+
+#include <boost/variant.hpp>
+
+#include <stout/foreach.hpp>
+
+// TODO(jsirois): Implement parsing that constructs JSON objects.
+
+
+namespace JSON {
+
+// Implementation of the JavaScript Object Notation (JSON) grammar
+// using boost::variant. We explicitly define each "type" of the
+// grammar, including 'true' (json::True), 'false' (json::False), and
+// 'null' (json::Null), for clarity and also because boost::variant
+// "picks" the wrong type when we try and use std::string, long (or
+// int), double (or float), and bool all in the same variant (while it
+// does work with explicit casts, it seemed bad style to force people
+// to put those casts in place). We could have avoided using
+// json::String or json::Number and just used std::string and double
+// respectively, but we choose to include them for completeness
+// (although, this does pay a 2x cost when compiling thanks to all the
+// extra template instantiations).
+
+struct String;
+struct Number;
+struct Object;
+struct Array;
+struct True;
+struct False;
+struct Null;
+
+
+typedef boost::variant<boost::recursive_wrapper<String>,
+ boost::recursive_wrapper<Number>,
+ boost::recursive_wrapper<Object>,
+ boost::recursive_wrapper<Array>,
+ boost::recursive_wrapper<True>,
+ boost::recursive_wrapper<False>,
+ boost::recursive_wrapper<Null> > Value;
+
+
+struct String
+{
+ String() {}
+ String(const char* _value) : value(_value) {}
+ String(const std::string& _value) : value(_value) {}
+ std::string value;
+};
+
+
+struct Number
+{
+ Number() {}
+ Number(double _value) : value(_value) {}
+ double value;
+};
+
+
+struct Object
+{
+ std::map<std::string, Value> values;
+};
+
+
+struct Array
+{
+ std::list<Value> values;
+};
+
+
+struct True {};
+
+
+struct False {};
+
+
+struct Null {};
+
+
+// Implementation of rendering JSON objects built above using standard
+// C++ output streams. The visitor pattern is used thanks to to build
+// a "renderer" with boost::static_visitor and two top-level render
+// routines are provided for rendering JSON objects and arrays.
+
+struct Renderer : boost::static_visitor<>
+{
+ Renderer(std::ostream& _out) : out(_out) {}
+
+ void operator () (const String& string) const
+ {
+ // TODO(benh): This escaping DOES NOT handle unicode, it encodes as ASCII.
+ // See RFC4627 for the JSON string specificiation.
+ out << "\"";
+ foreach (unsigned char c, string.value) {
+ switch (c) {
+ case '"': out << "\\\""; break;
+ case '\\': out << "\\\\"; break;
+ case '/': out << "\\/"; break;
+ case '\b': out << "\\b"; break;
+ case '\f': out << "\\f"; break;
+ case '\n': out << "\\n"; break;
+ case '\r': out << "\\r"; break;
+ case '\t': out << "\\t"; break;
+ default:
+ // See RFC4627 for these ranges.
+ if ((c >= 0x20 && c <= 0x21) ||
+ (c >= 0x23 && c <= 0x5B) ||
+ (c >= 0x5D && c < 0x7F)) {
+ out << c;
+ } else {
+ // NOTE: We also escape all bytes > 0x7F since they imply more than
+ // 1 byte in UTF-8. This is why we don't escape UTF-8 properly.
+ // See RFC4627 for the escaping format: \uXXXX (X is a hex digit).
+ // Each byte here will be of the form: \u00XX (this is why we need
+ // setw and the cast to unsigned int).
+ out << "\\u" << std::setfill('0') << std::setw(4)
+ << std::hex << std::uppercase << (unsigned int) c;
+ }
+ break;
+ }
+ }
+ out << "\"";
+ }
+
+ void operator () (const Number& number) const
+ {
+ out.precision(10);
+ out << number.value;
+ }
+
+ void operator () (const Object& object) const
+ {
+ out << "{";
+ std::map<std::string, Value>::const_iterator iterator;
+ iterator = object.values.begin();
+ while (iterator != object.values.end()) {
+ out << "\"" << (*iterator).first << "\":";
+ boost::apply_visitor(Renderer(out), (*iterator).second);
+ if (++iterator != object.values.end()) {
+ out << ",";
+ }
+ }
+ out << "}";
+ }
+
+ void operator () (const Array& array) const
+ {
+ out << "[";
+ std::list<Value>::const_iterator iterator;
+ iterator = array.values.begin();
+ while (iterator != array.values.end()) {
+ boost::apply_visitor(Renderer(out), *iterator);
+ if (++iterator != array.values.end()) {
+ out << ",";
+ }
+ }
+ out << "]";
+ }
+
+ void operator () (const True&) const
+ {
+ out << "true";
+ }
+
+ void operator () (const False&) const
+ {
+ out << "false";
+ }
+
+ void operator () (const Null&) const
+ {
+ out << "null";
+ }
+
+private:
+ std::ostream& out;
+};
+
+
+inline void render(std::ostream& out, const Value& value)
+{
+ boost::apply_visitor(Renderer(out), value);
+}
+
+
+inline std::ostream& operator<<(std::ostream& out, const JSON::Value& value)
+{
+ JSON::render(out, value);
+ return out;
+}
+
+} // namespace JSON {
+
+#endif // __STOUT_JSON__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/lambda.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/lambda.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/lambda.hpp
new file mode 100644
index 0000000..d493353
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/lambda.hpp
@@ -0,0 +1,14 @@
+#ifndef __STOUT_LAMBDA_HPP__
+#define __STOUT_LAMBDA_HPP__
+
+#include <tr1/functional>
+
+namespace lambda {
+
+using std::tr1::bind;
+using std::tr1::function;
+using namespace std::tr1::placeholders;
+
+} // namespace lambda {
+
+#endif // __STOUT_LAMBDA_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
new file mode 100644
index 0000000..10e49dc
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
@@ -0,0 +1,109 @@
+#ifndef __STOUT_MULTIHASHMAP_HPP__
+#define __STOUT_MULTIHASHMAP_HPP__
+
+#include <algorithm> // For find.
+#include <list>
+#include <set>
+#include <utility>
+
+#include <boost/unordered_map.hpp>
+
+
+// Implementation of a hash multimap via Boost's 'unordered_multimap'
+// but with a better interface. The rationale for creating this is
+// that the std::multimap interface is painful to use (requires lots
+// of iterator garbage, as well as the use of 'equal_range' which
+// makes for cluttered code).
+template <typename K, typename V>
+class multihashmap : public boost::unordered_multimap<K, V>
+{
+public:
+ void put(const K& key, const V& value);
+ std::list<V> get(const K& key) const;
+ std::set<K> keys() const;
+ bool remove(const K& key);
+ bool remove(const K& key, const V& value);
+ bool contains(const K& key) const;
+ bool contains(const K& key, const V& value) const;
+};
+
+
+template <typename K, typename V>
+void multihashmap<K, V>::put(const K& key, const V& value)
+{
+ boost::unordered_multimap<K, V>::insert(std::pair<K, V>(key, value));
+}
+
+
+template <typename K, typename V>
+std::list<V> multihashmap<K, V>::get(const K& key) const
+{
+ std::list<V> values; // Values to return.
+
+ std::pair<typename boost::unordered_multimap<K, V>::const_iterator,
+ typename boost::unordered_multimap<K, V>::const_iterator> range;
+
+ range = boost::unordered_multimap<K, V>::equal_range(key);
+
+ typename boost::unordered_multimap<K, V>::const_iterator i;
+ for (i = range.first; i != range.second; ++i) {
+ values.push_back(i->second);
+ }
+
+ return values;
+}
+
+
+template <typename K, typename V>
+std::set<K> multihashmap<K, V>::keys() const
+{
+ std::set<K> keys;
+ foreachkey (const K& key, *this) {
+ keys.insert(key);
+ }
+ return keys;
+}
+
+
+template <typename K, typename V>
+bool multihashmap<K, V>::remove(const K& key)
+{
+ return boost::unordered_multimap<K, V>::erase(key) > 0;
+}
+
+
+template <typename K, typename V>
+bool multihashmap<K, V>::remove(const K& key, const V& value)
+{
+ std::pair<typename boost::unordered_multimap<K, V>::iterator,
+ typename boost::unordered_multimap<K, V>::iterator> range;
+
+ range = boost::unordered_multimap<K, V>::equal_range(key);
+
+ typename boost::unordered_multimap<K, V>::iterator i;
+ for (i = range.first; i != range.second; ++i) {
+ if (i->second == value) {
+ boost::unordered_multimap<K, V>::erase(i);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+template <typename K, typename V>
+bool multihashmap<K, V>::contains(const K& key) const
+{
+ return multihashmap<K, V>::count(key) > 0;
+}
+
+
+template <typename K, typename V>
+bool multihashmap<K, V>::contains(const K& key, const V& value) const
+{
+ const std::list<V>& values = get(key);
+ return std::find(values.begin(), values.end(), value) != values.end();
+}
+
+#endif // __STOUT_MULTIHASHMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp
new file mode 100644
index 0000000..187ad79
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp
@@ -0,0 +1,107 @@
+#ifndef __STOUT_MULTIMAP_HPP__
+#define __STOUT_MULTIMAP_HPP__
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <set>
+#include <utility>
+
+// Implementation of a multimap via std::multimap but with a better
+// interface. The rationale for creating this is that the
+// std::multimap interface is painful to use (requires lots of
+// iterator garbage, as well as the use of 'equal_range' which makes
+// for cluttered code).
+template <typename K, typename V>
+class Multimap : public std::multimap<K, V>
+{
+public:
+ void put(const K& key, const V& value);
+ std::list<V> get(const K& key) const;
+ std::set<K> keys() const;
+ bool remove(const K& key);
+ bool remove(const K& key, const V& value);
+ bool contains(const K& key) const;
+ bool contains(const K& key, const V& value) const;
+};
+
+
+template <typename K, typename V>
+void Multimap<K, V>::put(const K& key, const V& value)
+{
+ std::multimap<K, V>::insert(std::pair<K, V>(key, value));
+}
+
+
+template <typename K, typename V>
+std::list<V> Multimap<K, V>::get(const K& key) const
+{
+ std::list<V> values; // Values to return.
+
+ std::pair<typename std::multimap<K, V>::const_iterator,
+ typename std::multimap<K, V>::const_iterator> range;
+
+ range = std::multimap<K, V>::equal_range(key);
+
+ typename std::multimap<K, V>::const_iterator i;
+ for (i = range.first; i != range.second; ++i) {
+ values.push_back(i->second);
+ }
+
+ return values;
+}
+
+
+template <typename K, typename V>
+std::set<K> Multimap<K, V>::keys() const
+{
+ std::set<K> keys;
+ foreachkey (const K& key, *this) {
+ keys.insert(key);
+ }
+ return keys;
+}
+
+
+template <typename K, typename V>
+bool Multimap<K, V>::remove(const K& key)
+{
+ return std::multimap<K, V>::erase(key) > 0;
+}
+
+
+template <typename K, typename V>
+bool Multimap<K, V>::remove(const K& key, const V& value)
+{
+ std::pair<typename std::multimap<K, V>::iterator,
+ typename std::multimap<K, V>::iterator> range;
+
+ range = std::multimap<K, V>::equal_range(key);
+
+ typename std::multimap<K, V>::iterator i;
+ for (i = range.first; i != range.second; ++i) {
+ if (i->second == value) {
+ std::multimap<K, V>::erase(i);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+template <typename K, typename V>
+bool Multimap<K, V>::contains(const K& key) const
+{
+ return std::multimap<K, V>::count(key) > 0;
+}
+
+
+template <typename K, typename V>
+bool Multimap<K, V>::contains(const K& key, const V& value) const
+{
+ const std::list<V>& values = get(key);
+ return std::find(values.begin(), values.end(), value) != values.end();
+}
+
+#endif // __STOUT_MULTIMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
new file mode 100644
index 0000000..1c5f88a
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/net.hpp
@@ -0,0 +1,102 @@
+#ifndef __STOUT_NET_HPP__
+#define __STOUT_NET_HPP__
+
+#include <netdb.h>
+#include <stdio.h>
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif
+
+#include <string>
+
+#include "error.hpp"
+#include "os.hpp"
+#include "try.hpp"
+
+
+// Network utilities.
+namespace net {
+
+// Returns the HTTP response code resulting from attempting to download the
+// specified HTTP or FTP URL into a file at the specified path.
+inline Try<int> download(const std::string& url, const std::string& path)
+{
+#ifndef HAVE_LIBCURL
+ return Error("libcurl is not available");
+#else
+ Try<int> fd = os::open(
+ path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
+
+ if (fd.isError()) {
+ return Error(fd.error());
+ }
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ CURL* curl = curl_easy_init();
+
+ if (curl == NULL) {
+ curl_easy_cleanup(curl);
+ os::close(fd.get());
+ return Error("Failed to initialize libcurl");
+ }
+
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
+
+ FILE* file = fdopen(fd.get(), "w");
+ if (file == NULL) {
+ return ErrnoError("Failed to open file handle of '" + path + "'");
+ }
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
+
+ CURLcode curlErrorCode = curl_easy_perform(curl);
+ if (curlErrorCode != 0) {
+ curl_easy_cleanup(curl);
+ fclose(file);
+ return Error(curl_easy_strerror(curlErrorCode));
+ }
+
+ long code;
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
+ curl_easy_cleanup(curl);
+
+ if (fclose(file) != 0) {
+ return ErrnoError("Failed to close file handle of '" + path + "'");
+ }
+
+ return Try<int>::some(code);
+#endif // HAVE_LIBCURL
+}
+
+// Returns a Try of the hostname for the provided IP. If the hostname cannot
+// be resolved, then a string version of the IP address is returned.
+inline Try<std::string> getHostname(uint32_t ip)
+{
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = ip;
+
+ char hostname[MAXHOSTNAMELEN];
+ if (getnameinfo(
+ (sockaddr*)&addr,
+ sizeof(addr),
+ hostname,
+ MAXHOSTNAMELEN,
+ NULL,
+ 0,
+ 0) != 0) {
+ return ErrnoError();
+ }
+
+ return std::string(hostname);
+}
+
+} // namespace net {
+
+#endif // __STOUT_NET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/none.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/none.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/none.hpp
new file mode 100644
index 0000000..ea8e0f5
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/none.hpp
@@ -0,0 +1,56 @@
+#ifndef __STOUT_NONE_HPP__
+#define __STOUT_NONE_HPP__
+
+#include "option.hpp"
+#include "result.hpp"
+
+// A "none" type that is implicitly convertible to an Option<T> and
+// Result<T> for any T (effectively "syntactic sugar" to make code
+// more readable). The implementation uses cast operators to perform
+// the conversions instead of adding constructors to Option/Result
+// directly. Performance shouldn't be an issue given that an instance
+// of None has no virtual functions and no fields.
+
+class None
+{
+public:
+ template <typename T>
+ operator Option<T> () const
+ {
+ return Option<T>::none();
+ }
+
+ // Give the compiler some help for nested Option<T>. For example,
+ // enable converting None to a Try<Option<T>>. Note that this will
+ // bind to the innermost Option<T>.
+ template <template <typename> class S, typename T>
+ operator S<Option<T> > () const
+ {
+ return S<Option<T> >(Option<T>::none());
+ }
+
+ template <typename T>
+ operator Result<T> () const
+ {
+ return Result<T>::none();
+ }
+
+ // Give the compiler some help for nested Result<T>. For example,
+ // enable converting None to a Try<Result<T>>. Note that this will
+ // bind to the innermost Result<T>.
+ template <template <typename> class S, typename T>
+ operator S<Result<T> > () const
+ {
+ return S<Result<T> >(Result<T>::none());
+ }
+
+ // Give the compiler some more help to disambiguate the above cast
+ // operators from Result<Option<T>>.
+ template <typename T>
+ operator Result<Option<T> > () const
+ {
+ return Result<Option<T> >::none();
+ }
+};
+
+#endif // __STOUT_NONE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/nothing.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/nothing.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/nothing.hpp
new file mode 100644
index 0000000..c11a010
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/nothing.hpp
@@ -0,0 +1,6 @@
+#ifndef __NOTHING_HPP__
+#define __NOTHING_HPP__
+
+struct Nothing {};
+
+#endif // __NOTHING_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/numify.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/numify.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/numify.hpp
new file mode 100644
index 0000000..d23e238
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/numify.hpp
@@ -0,0 +1,40 @@
+#ifndef __STOUT_NUMIFY_HPP__
+#define __STOUT_NUMIFY_HPP__
+
+#include <string>
+
+#include <boost/lexical_cast.hpp>
+
+#include "error.hpp"
+#include "none.hpp"
+#include "option.hpp"
+#include "result.hpp"
+#include "try.hpp"
+
+template <typename T>
+Try<T> numify(const std::string& s)
+{
+ try {
+ return boost::lexical_cast<T>(s);
+ } catch (const boost::bad_lexical_cast&) {
+ return Error("Failed to convert '" + s + "' to number");
+ }
+}
+
+
+template <typename T>
+Result<T> numify(const Option<std::string>& s)
+{
+ if (s.isSome()) {
+ Try<T> t = numify<T>(s.get());
+ if (t.isSome()) {
+ return t.get();
+ } else if (t.isError()) {
+ return Error(t.error());
+ }
+ }
+
+ return None();
+}
+
+#endif // __STOUT_NUMIFY_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/option.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/option.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/option.hpp
new file mode 100644
index 0000000..f991ae8
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/option.hpp
@@ -0,0 +1,85 @@
+#ifndef __STOUT_OPTION_HPP__
+#define __STOUT_OPTION_HPP__
+
+#include <assert.h>
+
+template <typename T>
+class Option
+{
+public:
+ static Option<T> none()
+ {
+ return Option<T>(NONE);
+ }
+
+ static Option<T> some(const T& t)
+ {
+ return Option<T>(SOME, new T(t));
+ }
+
+ Option() : state(NONE), t(NULL) {}
+
+ Option(const T& _t) : state(SOME), t(new T(_t)) {}
+
+ Option(const Option<T>& that)
+ {
+ state = that.state;
+ if (that.t != NULL) {
+ t = new T(*that.t);
+ } else {
+ t = NULL;
+ }
+ }
+
+ ~Option()
+ {
+ delete t;
+ }
+
+ Option<T>& operator = (const Option<T>& that)
+ {
+ if (this != &that) {
+ delete t;
+ state = that.state;
+ if (that.t != NULL) {
+ t = new T(*that.t);
+ } else {
+ t = NULL;
+ }
+ }
+
+ return *this;
+ }
+
+ bool operator == (const Option<T>& that) const
+ {
+ return (state == NONE && that.state == NONE) ||
+ (state == SOME && that.state == SOME && *t == *that.t);
+ }
+
+ bool operator != (const Option<T>& that) const
+ {
+ return !operator == (that);
+ }
+
+ bool isSome() const { return state == SOME; }
+ bool isNone() const { return state == NONE; }
+
+ T get() const { assert(state == SOME); return *t; }
+
+ T get(const T& _t) const { return state == NONE ? _t : *t; }
+
+private:
+ enum State {
+ SOME,
+ NONE,
+ };
+
+ Option(State _state, T* _t = NULL)
+ : state(_state), t(_t) {}
+
+ State state;
+ T* t;
+};
+
+#endif // __STOUT_OPTION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
new file mode 100644
index 0000000..28a08cc
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
@@ -0,0 +1,1081 @@
+#ifndef __STOUT_OS_HPP__
+#define __STOUT_OS_HPP__
+
+#ifdef __APPLE__
+#include <crt_externs.h> // For _NSGetEnviron().
+#endif
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <glob.h>
+#include <libgen.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <glog/logging.h>
+
+#ifdef __linux__
+#include <linux/version.h>
+#endif
+
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+#endif
+#ifdef __linux__
+#include <sys/sysinfo.h>
+#endif
+#include <sys/types.h>
+#include <sys/utsname.h>
+
+#include <list>
+#include <set>
+#include <sstream>
+#include <string>
+
+#include "bytes.hpp"
+#include "duration.hpp"
+#include "error.hpp"
+#include "foreach.hpp"
+#include "none.hpp"
+#include "nothing.hpp"
+#include "path.hpp"
+#include "result.hpp"
+#include "strings.hpp"
+#include "try.hpp"
+
+#ifdef __APPLE__
+// Assigning the result pointer to ret silences an unused var warning.
+#define gethostbyname2_r(name, af, ret, buf, buflen, result, h_errnop) \
+ ({ (void)ret; *(result) = gethostbyname2(name, af); 0; })
+#endif // __APPLE__
+
+// Need to declare 'environ' pointer for non OS X platforms.
+#ifndef __APPLE__
+extern char** environ;
+#endif
+
+namespace os {
+
+inline char** environ()
+{
+ // Accessing the list of environment variables is platform-specific.
+ // On OS X, the 'environ' symbol isn't visible to shared libraries,
+ // so we must use the _NSGetEnviron() function (see 'man environ' on
+ // OS X). On other platforms, it's fine to access 'environ' from
+ // shared libraries.
+#ifdef __APPLE__
+ return *_NSGetEnviron();
+#endif
+ return ::environ;
+}
+
+
+// Checks if the specified key is in the environment variables.
+inline bool hasenv(const std::string& key)
+{
+ char* value = ::getenv(key.c_str());
+
+ return value != NULL;
+}
+
+// Looks in the environment variables for the specified key and
+// returns a string representation of it's value. If 'expected' is
+// true (default) and no environment variable matching key is found,
+// this function will exit the process.
+inline std::string getenv(const std::string& key, bool expected = true)
+{
+ char* value = ::getenv(key.c_str());
+
+ if (expected && value == NULL) {
+ LOG(FATAL) << "Expecting '" << key << "' in environment variables";
+ }
+
+ if (value != NULL) {
+ return std::string(value);
+ }
+
+ return std::string();
+}
+
+
+// Sets the value associated with the specified key in the set of
+// environment variables.
+inline void setenv(const std::string& key,
+ const std::string& value,
+ bool overwrite = true)
+{
+ ::setenv(key.c_str(), value.c_str(), overwrite ? 1 : 0);
+}
+
+
+// Unsets the value associated with the specified key in the set of
+// environment variables.
+inline void unsetenv(const std::string& key)
+{
+ ::unsetenv(key.c_str());
+}
+
+
+inline Try<bool> access(const std::string& path, int how)
+{
+ if (::access(path.c_str(), how) < 0) {
+ if (errno == EACCES) {
+ return false;
+ } else {
+ return ErrnoError();
+ }
+ }
+ return true;
+}
+
+
+inline Try<int> open(const std::string& path, int oflag, mode_t mode = 0)
+{
+ int fd = ::open(path.c_str(), oflag, mode);
+
+ if (fd < 0) {
+ return ErrnoError();
+ }
+
+ return fd;
+}
+
+
+inline Try<Nothing> close(int fd)
+{
+ if (::close(fd) != 0) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+
+inline Try<Nothing> cloexec(int fd)
+{
+ int flags = ::fcntl(fd, F_GETFD);
+
+ if (flags == -1) {
+ return ErrnoError();
+ }
+
+ if (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+
+inline Try<Nothing> nonblock(int fd)
+{
+ int flags = ::fcntl(fd, F_GETFL);
+
+ if (flags == -1) {
+ return ErrnoError();
+ }
+
+ if (::fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+
+inline Try<bool> isNonblock(int fd)
+{
+ int flags = ::fcntl(fd, F_GETFL);
+
+ if (flags == -1) {
+ return ErrnoError();
+ }
+
+ return (flags & O_NONBLOCK) != 0;
+}
+
+
+inline Try<Nothing> touch(const std::string& path)
+{
+ Try<int> fd =
+ open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
+
+ if (fd.isError()) {
+ return Error("Failed to open file '" + path + "'");
+ }
+
+ // TODO(benh): Is opening/closing sufficient to have the same
+ // semantics as the touch utility (i.e., doesn't the utility change
+ // the modified date)?
+ return close(fd.get());
+}
+
+
+// Creates a temporary file using the specified path template. The
+// template may be any path with _6_ `Xs' appended to it, for example
+// /tmp/temp.XXXXXX. The trailing `Xs' are replaced with a unique
+// alphanumeric combination.
+inline Try<std::string> mktemp(const std::string& path = "/tmp/XXXXXX")
+{
+ char* temp = new char[path.size() + 1];
+ int fd = ::mkstemp(::strcpy(temp, path.c_str()));
+
+ if (fd < 0) {
+ delete temp;
+ return ErrnoError();
+ }
+
+ // We ignore the return value of close(). This is because users
+ // calling this function are interested in the return value of
+ // mkstemp(). Also an unsuccessful close() doesn't affect the file.
+ os::close(fd);
+
+ std::string result(temp);
+ delete temp;
+ return result;
+}
+
+
+// Write out the string to the file at the current fd position.
+inline Try<Nothing> write(int fd, const std::string& message)
+{
+ size_t offset = 0;
+
+ while (offset < message.length()) {
+ ssize_t length =
+ ::write(fd, message.data() + offset, message.length() - offset);
+
+ if (length < 0) {
+ // TODO(benh): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
+ if (errno == EINTR) {
+ continue;
+ }
+ return ErrnoError();
+ }
+
+ offset += length;
+ }
+
+ 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 std::string& 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 ErrnoError("Failed to open file '" + path + "'");
+ }
+
+ Try<Nothing> result = write(fd.get(), message);
+
+ // 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;
+}
+
+
+// Reads 'size' bytes from a file from its current offset.
+// If EOF is encountered before reading size bytes, then the offset
+// is restored and none is returned.
+inline Result<std::string> read(int fd, size_t size)
+{
+ // Save the current offset.
+ off_t current = lseek(fd, 0, SEEK_CUR);
+ if (current == -1) {
+ return ErrnoError("Failed to lseek to SEEK_CUR");
+ }
+
+ char* buffer = new char[size];
+ size_t offset = 0;
+
+ while (offset < size) {
+ ssize_t length = ::read(fd, buffer + offset, size - offset);
+
+ if (length < 0) {
+ // TODO(bmahler): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
+ if (errno == EINTR) {
+ continue;
+ }
+ // Attempt to restore the original offset.
+ lseek(fd, current, SEEK_SET);
+ return ErrnoError();
+ } else if (length == 0) {
+ // Reached EOF before expected! Restore the offset.
+ lseek(fd, current, SEEK_SET);
+ return None();
+ }
+
+ offset += length;
+ }
+
+ return std::string(buffer, size);
+}
+
+
+// Returns the contents of the file starting from its current offset.
+// If an error occurs, this will attempt to recover the file offset.
+inline Try<std::string> read(int fd)
+{
+ // Save the current offset.
+ off_t current = lseek(fd, 0, SEEK_CUR);
+ if (current == -1) {
+ return ErrnoError("Failed to lseek to SEEK_CUR");
+ }
+
+ // Get the size of the file from the offset.
+ off_t size = lseek(fd, current, SEEK_END);
+ if (size == -1) {
+ return ErrnoError("Failed to lseek to SEEK_END");
+ }
+
+ // Restore the offset.
+ if (lseek(fd, current, SEEK_SET) == -1) {
+ return ErrnoError("Failed to lseek with SEEK_SET");
+ }
+
+ Result<std::string> result = read(fd, size);
+ if (result.isNone()) {
+ // Hit EOF before reading size bytes.
+ return Error("The file size was modified while reading");
+ } else if (result.isError()) {
+ return Error(result.error());
+ }
+
+ return result.get();
+}
+
+
+// A wrapper function that wraps the above read() with
+// open and closing the file.
+inline Try<std::string> 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 + "'");
+ }
+
+ Try<std::string> result = read(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;
+}
+
+
+inline Try<Nothing> rm(const std::string& path)
+{
+ if (::remove(path.c_str()) != 0) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+
+inline Try<std::string> basename(const std::string& path)
+{
+ char* temp = new char[path.size() + 1];
+ char* result = ::basename(::strcpy(temp, path.c_str()));
+ if (result == NULL) {
+ delete temp;
+ return ErrnoError();
+ }
+
+ std::string s(result);
+ delete temp;
+ return s;
+}
+
+
+inline Try<std::string> dirname(const std::string& path)
+{
+ char* temp = new char[path.size() + 1];
+ char* result = ::dirname(::strcpy(temp, path.c_str()));
+ if (result == NULL) {
+ delete temp;
+ return ErrnoError();
+ }
+
+ std::string s(result);
+ delete temp;
+ return s;
+}
+
+
+inline Try<std::string> realpath(const std::string& path)
+{
+ char temp[PATH_MAX];
+ if (::realpath(path.c_str(), temp) == NULL) {
+ return ErrnoError();
+ }
+ return std::string(temp);
+}
+
+
+inline bool isdir(const std::string& path)
+{
+ struct stat s;
+
+ if (::stat(path.c_str(), &s) < 0) {
+ return false;
+ }
+ return S_ISDIR(s.st_mode);
+}
+
+
+inline bool isfile(const std::string& path)
+{
+ struct stat s;
+
+ if (::stat(path.c_str(), &s) < 0) {
+ return false;
+ }
+ return S_ISREG(s.st_mode);
+}
+
+
+inline bool islink(const std::string& path)
+{
+ struct stat s;
+
+ if (::lstat(path.c_str(), &s) < 0) {
+ return false;
+ }
+ return S_ISLNK(s.st_mode);
+}
+
+
+inline bool exists(const std::string& path)
+{
+ struct stat s;
+
+ if (::lstat(path.c_str(), &s) < 0) {
+ return false;
+ }
+ return true;
+}
+
+
+// TODO(benh): Put this in the 'paths' or 'files' or 'fs' namespace.
+inline Try<long> mtime(const std::string& path)
+{
+ struct stat s;
+
+ if (::lstat(path.c_str(), &s) < 0) {
+ return ErrnoError("Error invoking stat for '" + path + "'");
+ }
+
+ return s.st_mtime;
+}
+
+
+inline Try<Nothing> mkdir(const std::string& directory, bool recursive = true)
+{
+ if (!recursive) {
+ if (::mkdir(directory.c_str(), 0755) < 0) {
+ return ErrnoError();
+ }
+ } else {
+ std::vector<std::string> tokens = strings::tokenize(directory, "/");
+ std::string path = "";
+
+ // We got an absolute path, so keep the leading slash.
+ if (directory.find_first_of("/") == 0) {
+ path = "/";
+ }
+
+ foreach (const std::string& token, tokens) {
+ path += token;
+ if (::mkdir(path.c_str(), 0755) < 0 && errno != EEXIST) {
+ return ErrnoError();
+ }
+ path += "/";
+ }
+ }
+
+ return Nothing();
+}
+
+// Creates a temporary directory using the specified path
+// template. The template may be any path with _6_ `Xs' appended to
+// it, for example /tmp/temp.XXXXXX. The trailing `Xs' are replaced
+// with a unique alphanumeric combination.
+inline Try<std::string> mkdtemp(const std::string& path = "/tmp/XXXXXX")
+{
+ char* temp = new char[path.size() + 1];
+ if (::mkdtemp(::strcpy(temp, path.c_str())) != NULL) {
+ std::string result(temp);
+ delete temp;
+ return result;
+ } else {
+ delete temp;
+ return ErrnoError();
+ }
+}
+
+// By default, recursively deletes a directory akin to: 'rm -r'. If the
+// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
+// Note that this function expects an absolute path.
+inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
+{
+ if (!recursive) {
+ if (::rmdir(directory.c_str()) < 0) {
+ return ErrnoError();
+ }
+ } else {
+ char* paths[] = {const_cast<char*>(directory.c_str()), NULL};
+
+ FTS* tree = fts_open(paths, FTS_NOCHDIR, NULL);
+ if (tree == NULL) {
+ return ErrnoError();
+ }
+
+ FTSENT* node;
+ while ((node = fts_read(tree)) != NULL) {
+ switch (node->fts_info) {
+ case FTS_DP:
+ if (::rmdir(node->fts_path) < 0 && errno != ENOENT) {
+ return ErrnoError();
+ }
+ break;
+ case FTS_F:
+ case FTS_SL:
+ if (::unlink(node->fts_path) < 0 && errno != ENOENT) {
+ return ErrnoError();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (errno != 0) {
+ return ErrnoError();
+ }
+
+ if (fts_close(tree) < 0) {
+ return ErrnoError();
+ }
+ }
+
+ return Nothing();
+}
+
+
+inline int system(const std::string& command)
+{
+ return ::system(command.c_str());
+}
+
+
+// TODO(bmahler): Clean these bool functions to return Try<Nothing>.
+// Changes the specified path's user and group ownership to that of
+// the specified user..
+inline Try<Nothing> chown(
+ const std::string& user,
+ const std::string& path,
+ bool recursive = true)
+{
+ passwd* passwd;
+ if ((passwd = ::getpwnam(user.c_str())) == NULL) {
+ return ErrnoError("Failed to get user information for '" + user + "'");
+ }
+
+ if (recursive) {
+ // TODO(bmahler): Consider walking the file tree instead. We would need
+ // to be careful to not miss dotfiles.
+ std::string command = "chown -R " + stringify(passwd->pw_uid) + ':' +
+ stringify(passwd->pw_gid) + " '" + path + "'";
+
+ int status = os::system(command);
+ if (status != 0) {
+ return ErrnoError(
+ "Failed to execute '" + command +
+ "' (exit status: " + stringify(status) + ")");
+ }
+ } else {
+ if (::chown(path.c_str(), passwd->pw_uid, passwd->pw_gid) < 0) {
+ return ErrnoError();
+ }
+ }
+
+ return Nothing();
+}
+
+
+inline bool chmod(const std::string& path, int mode)
+{
+ if (::chmod(path.c_str(), mode) < 0) {
+ PLOG(ERROR) << "Failed to changed the mode of the path '" << path << "'";
+ return false;
+ }
+
+ return true;
+}
+
+
+inline bool chdir(const std::string& directory)
+{
+ if (::chdir(directory.c_str()) < 0) {
+ PLOG(ERROR) << "Failed to change directory";
+ return false;
+ }
+
+ return true;
+}
+
+
+inline bool su(const std::string& user)
+{
+ passwd* passwd;
+ if ((passwd = ::getpwnam(user.c_str())) == NULL) {
+ PLOG(ERROR) << "Failed to get user information for '"
+ << user << "', getpwnam";
+ return false;
+ }
+
+ if (::setgid(passwd->pw_gid) < 0) {
+ PLOG(ERROR) << "Failed to set group id, setgid";
+ return false;
+ }
+
+ if (::setuid(passwd->pw_uid) < 0) {
+ PLOG(ERROR) << "Failed to set user id, setuid";
+ return false;
+ }
+
+ return true;
+}
+
+
+inline std::string getcwd()
+{
+ size_t size = 100;
+
+ while (true) {
+ char* temp = new char[size];
+ if (::getcwd(temp, size) == temp) {
+ std::string result(temp);
+ delete[] temp;
+ return result;
+ } else {
+ if (errno != ERANGE) {
+ delete[] temp;
+ return std::string();
+ }
+ size *= 2;
+ delete[] temp;
+ }
+ }
+
+ return std::string();
+}
+
+
+// TODO(bmahler): Wrap with a Try.
+inline std::list<std::string> ls(const std::string& directory)
+{
+ std::list<std::string> result;
+
+ DIR* dir = opendir(directory.c_str());
+
+ if (dir == NULL) {
+ return std::list<std::string>();
+ }
+
+ // Calculate the size for a "directory entry".
+ long name_max = fpathconf(dirfd(dir), _PC_NAME_MAX);
+
+ // If we don't get a valid size, check NAME_MAX, but fall back on
+ // 255 in the worst case ... Danger, Will Robinson!
+ if (name_max == -1) {
+ name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+ }
+
+ size_t name_end =
+ (size_t) offsetof(dirent, d_name) + name_max + 1;
+
+ size_t size = (name_end > sizeof(dirent)
+ ? name_end
+ : sizeof(dirent));
+
+ dirent* temp = (dirent*) malloc(size);
+
+ if (temp == NULL) {
+ free(temp);
+ closedir(dir);
+ return std::list<std::string>();
+ }
+
+ struct dirent* entry;
+
+ int error;
+
+ while ((error = readdir_r(dir, temp, &entry)) == 0 && entry != NULL) {
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+ continue;
+ }
+ result.push_back(entry->d_name);
+ }
+
+ free(temp);
+ closedir(dir);
+
+ if (error != 0) {
+ return std::list<std::string>();
+ }
+
+ return result;
+}
+
+
+// Return the list of file paths that match the given pattern by recursively
+// searching the given directory. A match is successful if the pattern is a
+// substring of the file name.
+// NOTE: Directory path should not end with '/'.
+// NOTE: Symbolic links are not followed.
+// TODO(vinod): Support regular expressions for pattern.
+// TODO(vinod): Consider using ftw or a non-recursive approach.
+inline Try<std::list<std::string> > find(
+ const std::string& directory,
+ const std::string& pattern)
+{
+ std::list<std::string> results;
+
+ if (!isdir(directory)) {
+ return Error("'" + directory + "' is not a directory");
+ }
+
+ foreach (const std::string& entry, ls(directory)) {
+ std::string path = path::join(directory, entry);
+ // If it's a directory, recurse.
+ if (isdir(path) && !islink(path)) {
+ Try<std::list<std::string> > matches = find(path, pattern);
+ if (matches.isError()) {
+ return matches;
+ }
+ foreach (const std::string& match, matches.get()) {
+ results.push_back(match);
+ }
+ } else {
+ if (entry.find(pattern) != std::string::npos) {
+ results.push_back(path); // Matched the file pattern!
+ }
+ }
+ }
+
+ return results;
+}
+
+
+inline std::string user()
+{
+ passwd* passwd;
+ if ((passwd = getpwuid(getuid())) == NULL) {
+ LOG(FATAL) << "Failed to get username information";
+ }
+
+ return passwd->pw_name;
+}
+
+
+inline Try<std::string> hostname()
+{
+ char host[512];
+
+ if (gethostname(host, sizeof(host)) < 0) {
+ return ErrnoError();
+ }
+
+ // Allocate temporary buffer for gethostbyname2_r.
+ size_t length = 1024;
+ char* temp = new char[length];
+
+ struct hostent he, *hep = NULL;
+ int result = 0;
+ int herrno = 0;
+
+ while ((result = gethostbyname2_r(host, AF_INET, &he, temp,
+ length, &hep, &herrno)) == ERANGE) {
+ // Enlarge the buffer.
+ delete[] temp;
+ length *= 2;
+ temp = new char[length];
+ }
+
+ if (result != 0 || hep == NULL) {
+ delete[] temp;
+ return Error(hstrerror(herrno));
+ }
+
+ std::string hostname = hep->h_name;
+ delete[] temp;
+ return Try<std::string>::some(hostname);
+}
+
+
+// Runs a shell command formatted with varargs and return the return value
+// of the command. Optionally, the output is returned via an argument.
+// TODO(vinod): Pass an istream object that can provide input to the command.
+inline Try<int> shell(std::ostream* os, const std::string& fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ const Try<std::string>& cmdline = strings::internal::format(fmt, args);
+
+ va_end(args);
+
+ if (cmdline.isError()) {
+ return Error(cmdline.error());
+ }
+
+ FILE* file;
+
+ if ((file = popen(cmdline.get().c_str(), "r")) == NULL) {
+ return Error("Failed to run '" + cmdline.get() + "'");
+ }
+
+ char line[1024];
+ // NOTE(vinod): Ideally the if and while loops should be interchanged. But
+ // we get a broken pipe error if we don't read the output and simply close.
+ while (fgets(line, sizeof(line), file) != NULL) {
+ if (os != NULL) {
+ *os << line ;
+ }
+ }
+
+ if (ferror(file) != 0) {
+ ErrnoError error("Error reading output of '" + cmdline.get() + "'");
+ pclose(file); // Ignoring result since we already have an error.
+ return error;
+ }
+
+ int status;
+ if ((status = pclose(file)) == -1) {
+ return Error("Failed to get status of '" + cmdline.get() + "'");
+ }
+
+ return status;
+}
+
+
+// Suspends execution for the given duration.
+inline Try<Nothing> sleep(const Duration& duration)
+{
+ timespec remaining;
+ remaining.tv_sec = static_cast<long>(duration.secs());
+ remaining.tv_nsec =
+ static_cast<long>((duration - Seconds(remaining.tv_sec)).ns());
+
+ while (nanosleep(&remaining, &remaining) == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return ErrnoError();
+ }
+ }
+
+ return Nothing();
+}
+
+
+// Creates a tar 'archive' with gzip compression, of the given 'path'.
+inline Try<Nothing> tar(const std::string& path, const std::string& archive)
+{
+ Try<int> status =
+ shell(NULL, "tar -czf %s %s", archive.c_str(), path.c_str());
+
+ if (status.isError()) {
+ return Error("Failed to archive " + path + ": " + status.error());
+ } else if (status.get() != 0) {
+ return Error("Non-zero exit status when archiving " + path +
+ ": " + stringify(status.get()));
+ }
+
+ return Nothing();
+}
+
+
+// Returns the list of files that match the given (shell) pattern.
+inline Try<std::list<std::string> > glob(const std::string& pattern)
+{
+ glob_t g;
+ int status = ::glob(pattern.c_str(), GLOB_NOSORT, NULL, &g);
+
+ std::list<std::string> result;
+
+ if (status != 0) {
+ if (status == GLOB_NOMATCH) {
+ return result; // Empty list.
+ } else {
+ return ErrnoError();
+ }
+ }
+
+ for (size_t i = 0; i < g.gl_pathc; ++i) {
+ result.push_back(g.gl_pathv[i]);
+ }
+
+ globfree(&g); // Best-effort free of dynamically allocated memory.
+
+ return result;
+}
+
+
+// Returns the total number of cpus (cores).
+inline Try<long> cpus()
+{
+ long cpus = sysconf(_SC_NPROCESSORS_ONLN);
+
+ if (cpus < 0) {
+ return ErrnoError();
+ }
+ return cpus;
+}
+
+
+// Returns the total size of main memory.
+inline Try<Bytes> memory()
+{
+#ifdef __linux__
+ struct sysinfo info;
+ if (sysinfo(&info) != 0) {
+ return ErrnoError();
+ }
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23)
+ return Bytes(info.totalram * info.mem_unit);
+# else
+ return Bytes(info.totalram);
+# endif
+#elif defined __APPLE__
+ const size_t NAME_SIZE = 2;
+ int name[NAME_SIZE];
+ name[0] = CTL_HW;
+ name[1] = HW_MEMSIZE;
+
+ int64_t memory;
+ size_t length = sizeof(memory);
+
+ if (sysctl(name, NAME_SIZE, &memory, &length, NULL, 0) < 0) {
+ return ErrnoError("Failed to get sysctl of HW_MEMSIZE");
+ }
+ return Bytes(memory);
+#else
+ return Error("Cannot determine the size of main memory");
+#endif
+}
+
+
+// The structure returned by uname describing the currently running system.
+struct UTSInfo
+{
+ std::string sysname; // Operating system name (e.g. Linux).
+ std::string nodename; // Network name of this machine.
+ std::string release; // Release level of the operating system.
+ std::string version; // Version level of the operating system.
+ std::string machine; // Machine hardware platform.
+};
+
+
+// Return the system information.
+inline Try<UTSInfo> uname()
+{
+ struct utsname name;
+
+ if (::uname(&name) < 0) {
+ return ErrnoError();
+ }
+
+ UTSInfo info;
+ info.sysname = name.sysname;
+ info.nodename = name.nodename;
+ info.release = name.release;
+ info.version = name.version;
+ info.machine = name.machine;
+ return info;
+}
+
+
+// Return the operating system name (e.g. Linux).
+inline Try<std::string> sysname()
+{
+ Try<UTSInfo> info = uname();
+ if (info.isError()) {
+ return Error(info.error());
+ }
+
+ return info.get().sysname;
+}
+
+
+// The OS release level.
+struct Release
+{
+ int version;
+ int major;
+ int minor;
+};
+
+
+// Return the OS release numbers.
+inline Try<Release> release()
+{
+ Try<UTSInfo> info = uname();
+ if (info.isError()) {
+ return Error(info.error());
+ }
+
+ Release r;
+ if (::sscanf(
+ info.get().release.c_str(),
+ "%d.%d.%d",
+ &r.version,
+ &r.major,
+ &r.minor) != 3) {
+ return Error("Failed to parse: " + info.get().release);
+ }
+
+ return r;
+}
+
+
+inline Try<bool> alive(pid_t pid)
+{
+ CHECK(pid > 0);
+
+ if (::kill(pid, 0) == 0) {
+ return true;
+ }
+
+ if (errno == ESRCH) {
+ return false;
+ }
+
+ return Try<bool>::error(strerror(errno));
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/owned.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/owned.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/owned.hpp
new file mode 100644
index 0000000..3433f50
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/owned.hpp
@@ -0,0 +1,20 @@
+#ifndef __STOUT_OWNED_HPP__
+#define __STOUT_OWNED_HPP__
+
+#include <boost/shared_ptr.hpp>
+
+// Represents a uniquely owned pointer.
+//
+// TODO(bmahler): For now, Owned only provides shared_ptr semantics.
+// When we make the switch to C++11, we will change to provide
+// unique_ptr semantics. Consequently, each usage of Owned that
+// invoked a copy will have to be adjusted to use move semantics.
+template <typename T>
+class Owned : public boost::shared_ptr<T>
+{
+public:
+ Owned(T* t) : boost::shared_ptr<T>(t) {}
+};
+
+
+#endif // __STOUT_OWNED_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp
new file mode 100644
index 0000000..fda4e04
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/path.hpp
@@ -0,0 +1,76 @@
+#ifndef __STOUT_PATH_HPP__
+#define __STOUT_PATH_HPP__
+
+#include <string>
+#include <vector>
+
+#include "strings.hpp"
+
+namespace path {
+
+inline std::string join(const std::string& path1, const std::string& path2)
+{
+ return
+ strings::remove(path1, "/", strings::SUFFIX) + "/" +
+ strings::remove(path2, "/", strings::PREFIX);
+}
+
+
+inline std::string join(
+ const std::string& path1,
+ const std::string& path2,
+ const std::string& path3)
+{
+ return join(path1, join(path2, path3));
+}
+
+
+inline std::string join(
+ const std::string& path1,
+ const std::string& path2,
+ const std::string& path3,
+ const std::string& path4)
+{
+ return join(path1, join(path2, path3, path4));
+}
+
+
+inline std::string join(
+ const std::string& path1,
+ const std::string& path2,
+ const std::string& path3,
+ const std::string& path4,
+ const std::string& path5)
+{
+ return join(path1, join(path2, join(path3, join(path4, path5))));
+}
+
+
+inline std::string join(
+ const std::string& path1,
+ const std::string& path2,
+ const std::string& path3,
+ const std::string& path4,
+ const std::string& path5,
+ const std::string& path6)
+{
+ return join(path1, join(path2, path3, path4, path5, path6));
+}
+
+
+inline std::string join(const std::vector<std::string>& paths)
+{
+ if (paths.empty()) {
+ return "";
+ }
+
+ std::string result = paths[0];
+ for (size_t i = 1; i < paths.size(); ++i) {
+ result = join(result, paths[i]);
+ }
+ return result;
+}
+
+} // namespace path {
+
+#endif // __STOUT_PATH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/preprocessor.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
new file mode 100644
index 0000000..466e16f
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
@@ -0,0 +1,29 @@
+#ifndef __PROCESS_PREPROCESSOR_HPP__
+#define __PROCESS_PREPROCESSOR_HPP__
+
+#include <boost/preprocessor/cat.hpp>
+
+#include <boost/preprocessor/arithmetic/inc.hpp>
+
+#include <boost/preprocessor/facilities/intercept.hpp>
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+// Provides aliases to a bunch of preprocessor macros useful for
+// creating template definitions that have varying number of
+// parameters (should be removable with C++-11 variadic templates).
+
+#define CAT BOOST_PP_CAT
+#define INC BOOST_PP_INC
+#define INTERCEPT BOOST_PP_INTERCEPT
+#define ENUM_PARAMS BOOST_PP_ENUM_PARAMS
+#define ENUM_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS
+#define ENUM_TRAILING_PARAMS BOOST_PP_ENUM_TRAILING_PARAMS
+#define REPEAT BOOST_PP_REPEAT
+#define REPEAT_FROM_TO BOOST_PP_REPEAT_FROM_TO
+
+#endif // __PROCESS_PREPROCESSOR_HPP__
[08/35] git commit: Removed logging process from Mesos (now in
libprocess).
Posted by be...@apache.org.
Removed logging process from Mesos (now in libprocess).
Review: https://reviews.apache.org/r/11468
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/6ff3edff
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/6ff3edff
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/6ff3edff
Branch: refs/heads/master
Commit: 6ff3edff0351aefbd2858e7ca4b098c09efd3fc5
Parents: 1f14533
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 26 23:27:00 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:18:39 2013 -0700
----------------------------------------------------------------------
src/logging/logging.cpp | 110 +----------------------------------------
1 files changed, 3 insertions(+), 107 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/6ff3edff/src/logging/logging.cpp
----------------------------------------------------------------------
diff --git a/src/logging/logging.cpp b/src/logging/logging.cpp
index c36f7fa..7386e5e 100644
--- a/src/logging/logging.cpp
+++ b/src/logging/logging.cpp
@@ -21,21 +21,12 @@
#include <glog/logging.h>
-#include <map>
#include <string>
-#include <vector>
-#include <process/delay.hpp>
-#include <process/future.hpp>
-#include <process/http.hpp>
#include <process/once.hpp>
-#include <process/process.hpp>
-#include <process/timeout.hpp>
-#include <stout/duration.hpp>
#include <stout/error.hpp>
#include <stout/exit.hpp>
-#include <stout/numify.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/stringify.hpp>
@@ -43,107 +34,14 @@
#include "logging/logging.hpp"
-using namespace process;
-using namespace process::http;
+using process::Once;
-using std::map;
using std::string;
-using std::vector;
namespace mesos {
namespace internal {
namespace logging {
-class LoggingProcess : public Process<LoggingProcess>
-{
-public:
- LoggingProcess()
- : ProcessBase("logging"),
- original(FLAGS_v)
- {
- // Make sure all reads/writes can be done atomically (i.e., to
- // make sure VLOG(*) statements don't read partial writes).
- // TODO(benh): Use "atomics" primitives for doing reads/writes of
- // FLAGS_v anyway to account for proper memory barriers.
- CHECK(sizeof(FLAGS_v) == sizeof(int32_t));
- }
-
- virtual ~LoggingProcess() {}
-
-protected:
- virtual void initialize()
- {
- route("/toggle", &This::toggle);
- }
-
-private:
- Future<Response> toggle(const Request& request)
- {
- Option<string> level = request.query.get("level");
- Option<string> duration = request.query.get("duration");
-
- if (level.isNone() && duration.isNone()) {
- return OK(stringify(FLAGS_v) + "\n");
- }
-
- if (level.isSome() && duration.isNone()) {
- return BadRequest("Expecting 'duration=value' in query.\n");
- } else if (level.isNone() && duration.isSome()) {
- return BadRequest("Expecting 'level=value' in query.\n");
- }
-
- Try<int> v = numify<int>(level.get());
-
- if (v.isError()) {
- return BadRequest(v.error() + ".\n");
- }
-
- if (v.get() < 0) {
- return BadRequest("Invalid level '" + stringify(v.get()) + "'.\n");
- } else if (v.get() < original) {
- return BadRequest("'" + stringify(v.get()) + "' < original level.\n");
- }
-
- Try<Duration> d = Duration::parse(duration.get());
-
- if (d.isError()) {
- return BadRequest(d.error() + ".\n");
- }
-
- // Set the logging level.
- set(v.get());
-
- // Start a revert timer (if necessary).
- if (v.get() != original) {
- timeout = d.get();
- delay(timeout.remaining(), this, &This::revert);
- }
-
- return OK();
- }
-
- void set(int v)
- {
- if (FLAGS_v != v) {
- VLOG(FLAGS_v) << "Setting verbose logging level to " << v;
- FLAGS_v = v;
- __sync_synchronize(); // Ensure 'FLAGS_v' visible in other threads.
- }
- }
-
- void revert()
- {
- if (timeout.remaining() == Seconds(0)) {
- set(original);
- }
- }
-
- Timeout timeout;
-
- const int32_t original; // Original value of FLAGS_v.
-};
-
-
// Persistent copy of argv0 since InitGoogleLogging requires the
// string we pass to it to be accessible indefinitely.
string argv0;
@@ -193,10 +91,6 @@ void initialize(
VLOG(1) << "Logging to " <<
(flags.log_dir.isSome() ? flags.log_dir.get() : "STDERR");
- // TODO(benh): Make sure this always succeeds and never actually
- // exits (i.e., use a supervisor which re-spawns appropriately).
- spawn(new LoggingProcess(), true);
-
if (installFailureSignalHandler) {
// Handles SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, SIGTERM
// by default.
@@ -207,9 +101,11 @@ void initialize(
// of its lovely information.
struct sigaction action;
action.sa_handler = handler;
+
// Do not block additional signals while in the handler.
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
+
if (sigaction(SIGPIPE, &action, NULL) < 0) {
PLOG(FATAL) << "Failed to set sigaction";
}
[31/35] git commit: Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
Renamed 'third_party' to '3rdparty'.
Review: https://reviews.apache.org/r/11470
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/71a01bd9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/71a01bd9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/71a01bd9
Branch: refs/heads/master
Commit: 71a01bd9823f6d3097f633a79ee21b33ae033c8e
Parents: bc531d3
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 26 23:53:37 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:20:25 2013 -0700
----------------------------------------------------------------------
3rdparty/Makefile.am | 101 +
3rdparty/boto-2.0b2.zip | Bin 0 -> 387466 bytes
3rdparty/distribute-0.6.26.tar.gz | Bin 0 -> 621193 bytes
3rdparty/leveldb.tar.gz | Bin 0 -> 688044 bytes
3rdparty/libprocess/3rdparty/Makefile.am | 170 +
3rdparty/libprocess/3rdparty/boost-1.53.0.tar.gz | Bin 0 -> 988528 bytes
3rdparty/libprocess/3rdparty/glog-0.3.1.tar.gz | Bin 0 -> 1018372 bytes
3rdparty/libprocess/3rdparty/gmock-1.6.0.tar.gz | Bin 0 -> 1798225 bytes
3rdparty/libprocess/3rdparty/gperftools-2.0.tar.gz | Bin 0 -> 1261243 bytes
3rdparty/libprocess/3rdparty/libev-4.15.patch | 11 +
3rdparty/libprocess/3rdparty/libev-4.15.tar.gz | Bin 0 -> 513919 bytes
3rdparty/libprocess/3rdparty/protobuf-2.4.1.tar.gz | Bin 0 -> 1935301 bytes
.../3rdparty/ry-http-parser-1c3624a.tar.gz | Bin 0 -> 24625 bytes
3rdparty/libprocess/3rdparty/stout/LICENSE | 177 +
3rdparty/libprocess/3rdparty/stout/Makefile.am | 61 +
3rdparty/libprocess/3rdparty/stout/README | 32 +
3rdparty/libprocess/3rdparty/stout/bootstrap | 11 +
3rdparty/libprocess/3rdparty/stout/configure.ac | 14 +
.../3rdparty/stout/include/stout/bytes.hpp | 160 +
.../3rdparty/stout/include/stout/cache.hpp | 131 +
.../3rdparty/stout/include/stout/duration.hpp | 297 ++
.../3rdparty/stout/include/stout/error.hpp | 72 +
.../3rdparty/stout/include/stout/exit.hpp | 37 +
.../3rdparty/stout/include/stout/fatal.hpp | 43 +
.../3rdparty/stout/include/stout/flags.hpp | 70 +
.../3rdparty/stout/include/stout/flags/flag.hpp | 26 +
.../3rdparty/stout/include/stout/flags/flags.hpp | 481 ++
.../3rdparty/stout/include/stout/flags/loader.hpp | 109 +
.../3rdparty/stout/include/stout/flags/parse.hpp | 55 +
.../3rdparty/stout/include/stout/foreach.hpp | 51 +
.../3rdparty/stout/include/stout/format.hpp | 343 ++
.../libprocess/3rdparty/stout/include/stout/fs.hpp | 53 +
.../3rdparty/stout/include/stout/gtest.hpp | 122 +
.../3rdparty/stout/include/stout/gzip.hpp | 149 +
.../3rdparty/stout/include/stout/hashmap.hpp | 102 +
.../3rdparty/stout/include/stout/hashset.hpp | 57 +
.../3rdparty/stout/include/stout/json.hpp | 202 +
.../3rdparty/stout/include/stout/lambda.hpp | 14 +
.../3rdparty/stout/include/stout/multihashmap.hpp | 109 +
.../3rdparty/stout/include/stout/multimap.hpp | 107 +
.../3rdparty/stout/include/stout/net.hpp | 102 +
.../3rdparty/stout/include/stout/none.hpp | 56 +
.../3rdparty/stout/include/stout/nothing.hpp | 6 +
.../3rdparty/stout/include/stout/numify.hpp | 40 +
.../3rdparty/stout/include/stout/option.hpp | 85 +
.../libprocess/3rdparty/stout/include/stout/os.hpp | 1081 +++++
.../3rdparty/stout/include/stout/owned.hpp | 20 +
.../3rdparty/stout/include/stout/path.hpp | 76 +
.../3rdparty/stout/include/stout/preprocessor.hpp | 29 +
.../3rdparty/stout/include/stout/proc.hpp | 478 ++
.../3rdparty/stout/include/stout/protobuf.hpp | 159 +
.../3rdparty/stout/include/stout/result.hpp | 99 +
.../3rdparty/stout/include/stout/stopwatch.hpp | 70 +
.../3rdparty/stout/include/stout/stringify.hpp | 124 +
.../3rdparty/stout/include/stout/strings.hpp | 263 ++
.../3rdparty/stout/include/stout/try.hpp | 88 +
.../3rdparty/stout/include/stout/utils.hpp | 11 +
.../3rdparty/stout/include/stout/uuid.hpp | 54 +
3rdparty/libprocess/3rdparty/stout/install-sh | 520 +++
.../libprocess/3rdparty/stout/m4/acx_pthread.m4 | 363 ++
.../3rdparty/stout/tests/bytes_tests.cpp | 38 +
.../3rdparty/stout/tests/duration_tests.cpp | 82 +
.../3rdparty/stout/tests/error_tests.cpp | 60 +
.../3rdparty/stout/tests/flags_tests.cpp | 349 ++
.../libprocess/3rdparty/stout/tests/gzip_tests.cpp | 53 +
.../3rdparty/stout/tests/hashset_tests.cpp | 25 +
.../libprocess/3rdparty/stout/tests/json_tests.cpp | 19 +
3rdparty/libprocess/3rdparty/stout/tests/main.cpp | 11 +
.../3rdparty/stout/tests/multimap_tests.cpp | 168 +
.../libprocess/3rdparty/stout/tests/none_tests.cpp | 59 +
.../libprocess/3rdparty/stout/tests/os_tests.cpp | 208 +
.../libprocess/3rdparty/stout/tests/proc_tests.cpp | 162 +
.../3rdparty/stout/tests/strings_tests.cpp | 255 ++
.../libprocess/3rdparty/stout/tests/uuid_tests.cpp | 37 +
3rdparty/libprocess/3rdparty/versions.am | 11 +
3rdparty/libprocess/LICENSE | 177 +
3rdparty/libprocess/Makefile.am | 125 +
3rdparty/libprocess/README | 10 +
3rdparty/libprocess/TODO | 33 +
3rdparty/libprocess/bootstrap | 11 +
3rdparty/libprocess/configure.ac | 117 +
3rdparty/libprocess/examples/example.cpp | 121 +
3rdparty/libprocess/include/process/async.hpp | 231 +
3rdparty/libprocess/include/process/clock.hpp | 32 +
3rdparty/libprocess/include/process/collect.hpp | 125 +
3rdparty/libprocess/include/process/defer.hpp | 438 ++
3rdparty/libprocess/include/process/deferred.hpp | 136 +
3rdparty/libprocess/include/process/delay.hpp | 119 +
3rdparty/libprocess/include/process/dispatch.hpp | 478 ++
3rdparty/libprocess/include/process/event.hpp | 199 +
3rdparty/libprocess/include/process/executor.hpp | 260 ++
3rdparty/libprocess/include/process/filter.hpp | 24 +
3rdparty/libprocess/include/process/future.hpp | 1060 +++++
3rdparty/libprocess/include/process/gc.hpp | 46 +
3rdparty/libprocess/include/process/gmock.hpp | 327 ++
3rdparty/libprocess/include/process/gtest.hpp | 338 ++
3rdparty/libprocess/include/process/http.hpp | 468 ++
3rdparty/libprocess/include/process/id.hpp | 16 +
3rdparty/libprocess/include/process/io.hpp | 44 +
3rdparty/libprocess/include/process/latch.hpp | 33 +
3rdparty/libprocess/include/process/logging.hpp | 111 +
3rdparty/libprocess/include/process/message.hpp | 20 +
3rdparty/libprocess/include/process/mime.hpp | 145 +
3rdparty/libprocess/include/process/once.hpp | 48 +
3rdparty/libprocess/include/process/pid.hpp | 121 +
3rdparty/libprocess/include/process/process.hpp | 370 ++
3rdparty/libprocess/include/process/profiler.hpp | 116 +
3rdparty/libprocess/include/process/protobuf.hpp | 415 ++
3rdparty/libprocess/include/process/run.hpp | 80 +
3rdparty/libprocess/include/process/socket.hpp | 84 +
3rdparty/libprocess/include/process/statistics.hpp | 160 +
3rdparty/libprocess/include/process/thread.hpp | 49 +
3rdparty/libprocess/include/process/time.hpp | 124 +
3rdparty/libprocess/include/process/timeout.hpp | 84 +
3rdparty/libprocess/include/process/timer.hpp | 76 +
.../libprocess/include/process/tuples/details.hpp | 170 +
.../libprocess/include/process/tuples/tuples.hpp | 154 +
3rdparty/libprocess/install-sh | 520 +++
3rdparty/libprocess/m4/acx_pthread.m4 | 363 ++
3rdparty/libprocess/src/config.hpp | 47 +
3rdparty/libprocess/src/decoder.hpp | 412 ++
3rdparty/libprocess/src/encoder.hpp | 262 ++
3rdparty/libprocess/src/fatal.cpp | 26 +
3rdparty/libprocess/src/fatal.hpp | 28 +
3rdparty/libprocess/src/gate.hpp | 103 +
3rdparty/libprocess/src/httpd.cpp | 306 ++
3rdparty/libprocess/src/latch.cpp | 62 +
3rdparty/libprocess/src/net.hpp | 231 +
3rdparty/libprocess/src/pid.cpp | 182 +
3rdparty/libprocess/src/process.cpp | 3446 +++++++++++++++
3rdparty/libprocess/src/statistics.cpp | 508 +++
3rdparty/libprocess/src/synchronized.cpp | 66 +
3rdparty/libprocess/src/synchronized.hpp | 104 +
3rdparty/libprocess/src/test-master.cpp | 62 +
3rdparty/libprocess/src/test-slave.cpp | 61 +
3rdparty/libprocess/src/tests/decoder_tests.cpp | 128 +
3rdparty/libprocess/src/tests/encoder_tests.cpp | 92 +
3rdparty/libprocess/src/tests/http_tests.cpp | 133 +
3rdparty/libprocess/src/tests/io_tests.cpp | 162 +
3rdparty/libprocess/src/tests/main.cpp | 25 +
3rdparty/libprocess/src/tests/process_tests.cpp | 1143 +++++
3rdparty/libprocess/src/tests/statistics_tests.cpp | 184 +
3rdparty/libprocess/src/tests/time_tests.cpp | 46 +
3rdparty/libprocess/src/timer.cpp | 56 +
3rdparty/libprocess/src/timer.hpp | 125 +
3rdparty/versions.am | 24 +
3rdparty/zookeeper-3.3.4.tar.gz | Bin 0 -> 13543276 bytes
LICENSE | 23 +-
Makefile.am | 2 +-
bootstrap | 2 +-
configure.ac | 14 +-
src/Makefile.am | 66 +-
src/examples/python/test-executor.in | 4 +-
src/examples/python/test-framework.in | 4 +-
src/python/setup.py.in | 16 +-
src/tests/zookeeper.cpp | 2 +-
third_party/Makefile.am | 101 -
third_party/boto-2.0b2.zip | Bin 387466 -> 0 bytes
third_party/distribute-0.6.26.tar.gz | Bin 621193 -> 0 bytes
third_party/leveldb.tar.gz | Bin 688044 -> 0 bytes
third_party/libprocess/3rdparty/Makefile.am | 170 -
.../libprocess/3rdparty/boost-1.53.0.tar.gz | Bin 988528 -> 0 bytes
third_party/libprocess/3rdparty/glog-0.3.1.tar.gz | Bin 1018372 -> 0 bytes
third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz | Bin 1798225 -> 0 bytes
.../libprocess/3rdparty/gperftools-2.0.tar.gz | Bin 1261243 -> 0 bytes
third_party/libprocess/3rdparty/libev-4.15.patch | 11 -
third_party/libprocess/3rdparty/libev-4.15.tar.gz | Bin 513919 -> 0 bytes
.../libprocess/3rdparty/protobuf-2.4.1.tar.gz | Bin 1935301 -> 0 bytes
.../3rdparty/ry-http-parser-1c3624a.tar.gz | Bin 24625 -> 0 bytes
third_party/libprocess/3rdparty/stout/LICENSE | 177 -
third_party/libprocess/3rdparty/stout/Makefile.am | 61 -
third_party/libprocess/3rdparty/stout/README | 32 -
third_party/libprocess/3rdparty/stout/bootstrap | 11 -
third_party/libprocess/3rdparty/stout/configure.ac | 14 -
.../3rdparty/stout/include/stout/bytes.hpp | 160 -
.../3rdparty/stout/include/stout/cache.hpp | 131 -
.../3rdparty/stout/include/stout/duration.hpp | 297 --
.../3rdparty/stout/include/stout/error.hpp | 72 -
.../3rdparty/stout/include/stout/exit.hpp | 37 -
.../3rdparty/stout/include/stout/fatal.hpp | 43 -
.../3rdparty/stout/include/stout/flags.hpp | 70 -
.../3rdparty/stout/include/stout/flags/flag.hpp | 26 -
.../3rdparty/stout/include/stout/flags/flags.hpp | 481 --
.../3rdparty/stout/include/stout/flags/loader.hpp | 109 -
.../3rdparty/stout/include/stout/flags/parse.hpp | 55 -
.../3rdparty/stout/include/stout/foreach.hpp | 51 -
.../3rdparty/stout/include/stout/format.hpp | 343 --
.../libprocess/3rdparty/stout/include/stout/fs.hpp | 53 -
.../3rdparty/stout/include/stout/gtest.hpp | 122 -
.../3rdparty/stout/include/stout/gzip.hpp | 149 -
.../3rdparty/stout/include/stout/hashmap.hpp | 102 -
.../3rdparty/stout/include/stout/hashset.hpp | 57 -
.../3rdparty/stout/include/stout/json.hpp | 202 -
.../3rdparty/stout/include/stout/lambda.hpp | 14 -
.../3rdparty/stout/include/stout/multihashmap.hpp | 109 -
.../3rdparty/stout/include/stout/multimap.hpp | 107 -
.../3rdparty/stout/include/stout/net.hpp | 102 -
.../3rdparty/stout/include/stout/none.hpp | 56 -
.../3rdparty/stout/include/stout/nothing.hpp | 6 -
.../3rdparty/stout/include/stout/numify.hpp | 40 -
.../3rdparty/stout/include/stout/option.hpp | 85 -
.../libprocess/3rdparty/stout/include/stout/os.hpp | 1081 -----
.../3rdparty/stout/include/stout/owned.hpp | 20 -
.../3rdparty/stout/include/stout/path.hpp | 76 -
.../3rdparty/stout/include/stout/preprocessor.hpp | 29 -
.../3rdparty/stout/include/stout/proc.hpp | 478 --
.../3rdparty/stout/include/stout/protobuf.hpp | 159 -
.../3rdparty/stout/include/stout/result.hpp | 99 -
.../3rdparty/stout/include/stout/stopwatch.hpp | 70 -
.../3rdparty/stout/include/stout/stringify.hpp | 124 -
.../3rdparty/stout/include/stout/strings.hpp | 263 --
.../3rdparty/stout/include/stout/try.hpp | 88 -
.../3rdparty/stout/include/stout/utils.hpp | 11 -
.../3rdparty/stout/include/stout/uuid.hpp | 54 -
third_party/libprocess/3rdparty/stout/install-sh | 520 ---
.../libprocess/3rdparty/stout/m4/acx_pthread.m4 | 363 --
.../3rdparty/stout/tests/bytes_tests.cpp | 38 -
.../3rdparty/stout/tests/duration_tests.cpp | 82 -
.../3rdparty/stout/tests/error_tests.cpp | 60 -
.../3rdparty/stout/tests/flags_tests.cpp | 349 --
.../libprocess/3rdparty/stout/tests/gzip_tests.cpp | 53 -
.../3rdparty/stout/tests/hashset_tests.cpp | 25 -
.../libprocess/3rdparty/stout/tests/json_tests.cpp | 19 -
.../libprocess/3rdparty/stout/tests/main.cpp | 11 -
.../3rdparty/stout/tests/multimap_tests.cpp | 168 -
.../libprocess/3rdparty/stout/tests/none_tests.cpp | 59 -
.../libprocess/3rdparty/stout/tests/os_tests.cpp | 208 -
.../libprocess/3rdparty/stout/tests/proc_tests.cpp | 162 -
.../3rdparty/stout/tests/strings_tests.cpp | 255 --
.../libprocess/3rdparty/stout/tests/uuid_tests.cpp | 37 -
third_party/libprocess/3rdparty/versions.am | 11 -
third_party/libprocess/LICENSE | 177 -
third_party/libprocess/Makefile.am | 125 -
third_party/libprocess/README | 10 -
third_party/libprocess/TODO | 33 -
third_party/libprocess/bootstrap | 11 -
third_party/libprocess/configure.ac | 117 -
third_party/libprocess/examples/example.cpp | 121 -
third_party/libprocess/include/process/async.hpp | 231 -
third_party/libprocess/include/process/clock.hpp | 32 -
third_party/libprocess/include/process/collect.hpp | 125 -
third_party/libprocess/include/process/defer.hpp | 438 --
.../libprocess/include/process/deferred.hpp | 136 -
third_party/libprocess/include/process/delay.hpp | 119 -
.../libprocess/include/process/dispatch.hpp | 478 --
third_party/libprocess/include/process/event.hpp | 199 -
.../libprocess/include/process/executor.hpp | 260 --
third_party/libprocess/include/process/filter.hpp | 24 -
third_party/libprocess/include/process/future.hpp | 1060 -----
third_party/libprocess/include/process/gc.hpp | 46 -
third_party/libprocess/include/process/gmock.hpp | 327 --
third_party/libprocess/include/process/gtest.hpp | 338 --
third_party/libprocess/include/process/http.hpp | 468 --
third_party/libprocess/include/process/id.hpp | 16 -
third_party/libprocess/include/process/io.hpp | 44 -
third_party/libprocess/include/process/latch.hpp | 33 -
third_party/libprocess/include/process/logging.hpp | 111 -
third_party/libprocess/include/process/message.hpp | 20 -
third_party/libprocess/include/process/mime.hpp | 145 -
third_party/libprocess/include/process/once.hpp | 48 -
third_party/libprocess/include/process/pid.hpp | 121 -
third_party/libprocess/include/process/process.hpp | 370 --
.../libprocess/include/process/profiler.hpp | 116 -
.../libprocess/include/process/protobuf.hpp | 415 --
third_party/libprocess/include/process/run.hpp | 80 -
third_party/libprocess/include/process/socket.hpp | 84 -
.../libprocess/include/process/statistics.hpp | 160 -
third_party/libprocess/include/process/thread.hpp | 49 -
third_party/libprocess/include/process/time.hpp | 124 -
third_party/libprocess/include/process/timeout.hpp | 84 -
third_party/libprocess/include/process/timer.hpp | 76 -
.../libprocess/include/process/tuples/details.hpp | 170 -
.../libprocess/include/process/tuples/tuples.hpp | 154 -
third_party/libprocess/install-sh | 520 ---
third_party/libprocess/m4/acx_pthread.m4 | 363 --
third_party/libprocess/src/config.hpp | 47 -
third_party/libprocess/src/decoder.hpp | 412 --
third_party/libprocess/src/encoder.hpp | 262 --
third_party/libprocess/src/fatal.cpp | 26 -
third_party/libprocess/src/fatal.hpp | 28 -
third_party/libprocess/src/gate.hpp | 103 -
third_party/libprocess/src/httpd.cpp | 306 --
third_party/libprocess/src/latch.cpp | 62 -
third_party/libprocess/src/net.hpp | 231 -
third_party/libprocess/src/pid.cpp | 182 -
third_party/libprocess/src/process.cpp | 3446 ---------------
third_party/libprocess/src/statistics.cpp | 508 ---
third_party/libprocess/src/synchronized.cpp | 66 -
third_party/libprocess/src/synchronized.hpp | 104 -
third_party/libprocess/src/test-master.cpp | 62 -
third_party/libprocess/src/test-slave.cpp | 61 -
third_party/libprocess/src/tests/decoder_tests.cpp | 128 -
third_party/libprocess/src/tests/encoder_tests.cpp | 92 -
third_party/libprocess/src/tests/http_tests.cpp | 133 -
third_party/libprocess/src/tests/io_tests.cpp | 162 -
third_party/libprocess/src/tests/main.cpp | 25 -
third_party/libprocess/src/tests/process_tests.cpp | 1143 -----
.../libprocess/src/tests/statistics_tests.cpp | 184 -
third_party/libprocess/src/tests/time_tests.cpp | 46 -
third_party/libprocess/src/timer.cpp | 56 -
third_party/libprocess/src/timer.hpp | 125 -
third_party/versions.am | 24 -
third_party/zookeeper-3.3.4.tar.gz | Bin 13543276 -> 0 bytes
303 files changed, 24896 insertions(+), 24897 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/Makefile.am b/3rdparty/Makefile.am
new file mode 100644
index 0000000..51a8337
--- /dev/null
+++ b/3rdparty/Makefile.am
@@ -0,0 +1,101 @@
+# 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
+
+# This Makefile is for building third-party packages from
+# tarballs. For autotools-based packages, we configure each of the
+# packages to build static PIC binaries which we can safely link into
+# a shared libmesos, and build it in-place without installing it (even
+# if one runs 'make install' in this directory). Non-autotools based
+# packages may be special cases; this Makefile is responsible for
+# passing any special make or configure flags that might be required.
+
+BUILT_SOURCES = # Initialized to enable using +=.
+
+SUBDIRS = libprocess
+
+# We need to add '--srcdir=.' needed because 'make distcheck' adds
+# '--srcdir=...' when configuring.
+CONFIGURE_ARGS = @CONFIGURE_ARGS@ --enable-shared=no --with-pic --srcdir=.
+
+include versions.am
+
+BOTO = boto-$(BOTO_VERSION)
+DISTRIBUTE = distribute-$(DISTRIBUTE_VERSION)
+LEVELDB = leveldb
+ZOOKEEPER = zookeeper-$(ZOOKEEPER_VERSION)
+
+
+EXTRA_DIST = \
+ $(BOTO).zip \
+ $(DISTRIBUTE).tar.gz \
+ $(LEVELDB).tar.gz \
+ $(ZOOKEEPER).tar.gz
+
+CLEAN_EXTRACTED = \
+ $(BOTO) \
+ $(DISTRIBUTE) \
+ $(LEVELDB) \
+ $(ZOOKEEPER)
+
+
+# This is where the magic happens: we use stamp files as dependencies
+# which cause the packages to get extracted as necessary. We also
+# apply any patches as appropriate.
+%-stamp: %.tar.gz
+ gzip -d -c $^ | tar xf -
+ test ! -e $(srcdir)/$*.patch || patch -d $* -p1 <$(srcdir)/$*.patch
+ touch $@
+
+
+if HAS_PYTHON
+DISTRIBUTE_EGG = \
+ $(DISTRIBUTE)/dist/$(DISTRIBUTE)$(PYTHON_EGG_PUREPY_POSTFIX).egg
+
+$(DISTRIBUTE_EGG): $(DISTRIBUTE)-stamp
+ cd $(DISTRIBUTE) && $(PYTHON) setup.py bdist_egg
+endif
+
+
+# TODO(charles): Figure out PIC options in our configure.ac or create
+# a configure.ac for leveldb.
+$(LEVELDB)/libleveldb.a: $(LEVELDB)-stamp
+ cd $(LEVELDB) && \
+ $(MAKE) $(AM_MAKEFLAGS) CC="$(CXX)" OPT="$(CXXFLAGS) -fPIC"
+
+$(ZOOKEEPER)/src/c/libzookeeper_mt.la: $(ZOOKEEPER)-stamp
+ cd $(ZOOKEEPER)/src/c && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+
+# Dependencies for all-local.
+ALL_LOCAL = $(LEVELDB)/libleveldb.a
+
+if HAS_PYTHON
+ ALL_LOCAL += $(DISTRIBUTE_EGG)
+endif
+
+if WITH_INCLUDED_ZOOKEEPER
+ ALL_LOCAL += $(ZOOKEEPER)/src/c/libzookeeper_mt.la
+else
+ # Now matter what we need to extract ZooKeeper so that we can run
+ # 'make check' (some of our tests need the ZooKeeper JAR).
+ ALL_LOCAL += $(ZOOKEEPER)-stamp
+endif
+
+all-local: $(ALL_LOCAL)
+
+clean-local:
+ rm -r -f $(CLEAN_EXTRACTED)
+ rm -f *-stamp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/boto-2.0b2.zip
----------------------------------------------------------------------
diff --git a/3rdparty/boto-2.0b2.zip b/3rdparty/boto-2.0b2.zip
new file mode 100644
index 0000000..5992473
Binary files /dev/null and b/3rdparty/boto-2.0b2.zip differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/distribute-0.6.26.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/distribute-0.6.26.tar.gz b/3rdparty/distribute-0.6.26.tar.gz
new file mode 100644
index 0000000..3a598cc
Binary files /dev/null and b/3rdparty/distribute-0.6.26.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/leveldb.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/leveldb.tar.gz b/3rdparty/leveldb.tar.gz
new file mode 100644
index 0000000..2326611
Binary files /dev/null and b/3rdparty/leveldb.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/Makefile.am b/3rdparty/libprocess/3rdparty/Makefile.am
new file mode 100644
index 0000000..20599ec
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/Makefile.am
@@ -0,0 +1,170 @@
+# This Makefile is for building third-party packages from
+# tarballs. For autotools-based packages, we configure each of the
+# packages to build static PIC binaries which we can safely link into
+# a shared libmesos, and build it in-place without installing it (even
+# if one runs 'make install' in this directory). Non-autotools based
+# packages may be special cases; this Makefile is responsible for
+# passing any special make or configure flags that might be required.
+
+SUBDIRS = stout
+
+BUILT_SOURCES = # Initialized to enable using +=.
+
+# We need to add '--srcdir=.' needed because 'make distcheck' adds
+# '--srcdir=...' when configuring.
+CONFIGURE_ARGS = @CONFIGURE_ARGS@ --enable-shared=no --with-pic --srcdir=.
+
+include versions.am
+
+STOUT = stout
+BOOST = boost-$(BOOST_VERSION)
+GLOG = glog-$(GLOG_VERSION)
+GMOCK = gmock-$(GMOCK_VERSION)
+GPERFTOOLS = gperftools-$(GPERFTOOLS_VERSION)
+GTEST = $(GMOCK)/gtest
+RY_HTTP_PARSER = ry-http-parser-$(RY_HTTP_PARSER_VERSION)
+LIBEV = libev-$(LIBEV_VERSION)
+PROTOBUF = protobuf-$(PROTOBUF_VERSION)
+
+
+EXTRA_DIST = \
+ $(BOOST).tar.gz \
+ $(GLOG).tar.gz \
+ $(GMOCK).tar.gz \
+ $(GPERFTOOLS).tar.gz \
+ $(LIBEV).tar.gz \
+ $(LIBEV).patch \
+ $(PROTOBUF).tar.gz \
+ $(RY_HTTP_PARSER).tar.gz
+
+CLEAN_EXTRACTED = \
+ $(BOOST) \
+ $(GLOG) \
+ $(GMOCK) \
+ $(GPERFTOOLS) \
+ $(LIBEV) \
+ $(PROTOBUF) \
+ $(RY_HTTP_PARSER)
+
+
+# This is where the magic happens: we use stamp files as dependencies
+# which cause the packages to get extracted as necessary. We also
+# apply any patches as appropriate.
+%-stamp: %.tar.gz
+ gzip -d -c $^ | tar xf -
+ test ! -e $(srcdir)/$*.patch || patch -d $* -p1 <$(srcdir)/$*.patch
+ touch $@
+
+
+# Convenience library for Ryan Dahl's HTTP parser.
+noinst_LTLIBRARIES = libry_http_parser.la
+nodist_libry_http_parser_la_SOURCES = $(RY_HTTP_PARSER)/http_parser.c
+libry_http_parser_la_CPPFLAGS = -I$(RY_HTTP_PARSER)
+
+# We list the sources in BUILT_SOURCES to make sure that the package
+# gets unarchived first.
+BUILT_SOURCES += $(nodist_libry_http_parser_la_SOURCES)
+
+
+# Convenience library for gmock/gtest.
+check_LTLIBRARIES = libgmock.la
+nodist_libgmock_la_SOURCES = \
+ $(GTEST)/src/gtest-all.cc \
+ $(GMOCK)/src/gmock-all.cc
+libgmock_la_CPPFLAGS = \
+ -I$(GTEST)/include -I$(GTEST) \
+ -I$(GMOCK)/include -I$(GMOCK)
+
+# We list the sources in BUILT_SOURCES to make sure that the package
+# gets unarchived first.
+BUILT_SOURCES += $(nodist_libgmock_la_SOURCES)
+
+$(GMOCK)/src/gmock-all.cc: $(GMOCK)-stamp
+$(GTEST)/src/gtest-all.cc: $(GMOCK)-stamp
+
+
+$(BOOST)/boost: $(BOOST)-stamp
+
+$(GLOG)/libglog.la: $(GLOG)-stamp
+ cd $(GLOG) && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+
+if HAS_GPERFTOOLS
+$(GPERFTOOLS)/libprofiler.la: $(GPERFTOOLS)-build-stamp
+
+$(GPERFTOOLS)-build-stamp: $(GPERFTOOLS)-stamp
+ cd $(GPERFTOOLS) && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+ touch $@
+endif
+
+$(LIBEV)/libev.la: $(LIBEV)-stamp
+ cd $(LIBEV) && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+
+$(PROTOBUF)/src/protoc $(PROTOBUF)/src/libprotobuf.la: $(PROTOBUF)-build-stamp
+
+$(PROTOBUF)-build-stamp: $(PROTOBUF)-stamp
+ cd $(PROTOBUF) && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+ touch $@
+
+$(RY_HTTP_PARSER)/http_parser.c: $(RY_HTTP_PARSER)-stamp
+
+
+# Tests for stout.
+check_PROGRAMS = stout-tests
+
+stout_tests_SOURCES = \
+ $(STOUT)/tests/bytes_tests.cpp \
+ $(STOUT)/tests/duration_tests.cpp \
+ $(STOUT)/tests/error_tests.cpp \
+ $(STOUT)/tests/flags_tests.cpp \
+ $(STOUT)/tests/gzip_tests.cpp \
+ $(STOUT)/tests/hashset_tests.cpp \
+ $(STOUT)/tests/json_tests.cpp \
+ $(STOUT)/tests/main.cpp \
+ $(STOUT)/tests/multimap_tests.cpp \
+ $(STOUT)/tests/none_tests.cpp \
+ $(STOUT)/tests/os_tests.cpp \
+ $(STOUT)/tests/strings_tests.cpp \
+ $(STOUT)/tests/uuid_tests.cpp
+
+if OS_LINUX
+ stout_tests_SOURCES += $(STOUT)/tests/proc_tests.cpp
+endif
+
+stout_tests_CPPFLAGS = \
+ -I$(srcdir)/$(STOUT)/include \
+ -I$(BOOST) \
+ -I$(GLOG)/src \
+ -I$(GTEST)/include \
+ -I$(GMOCK)/include \
+ -I$(PROTOBUF)/src \
+ $(AM_CPPFLAGS)
+
+stout_tests_LDADD = \
+ libgmock.la \
+ $(GLOG)/libglog.la \
+ $(PROTOBUF)/src/libprotobuf.la
+
+TESTS = stout-tests
+
+# Dependencies for all-local.
+ALL_LOCAL = \
+ $(STOUT)/Makefile \
+ $(BOOST)-stamp \
+ $(GLOG)/libglog.la \
+ $(LIBEV)/libev.la \
+ $(PROTOBUF)/src/libprotobuf.la \
+ $(PROTOBUF)/src/protoc
+
+if HAS_GPERFTOOLS
+ ALL_LOCAL += $(GPERFTOOLS)/libprofiler.la
+endif
+
+all-local: $(ALL_LOCAL)
+
+clean-local:
+ rm -r -f $(CLEAN_EXTRACTED)
+ rm -f *-stamp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/boost-1.53.0.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/boost-1.53.0.tar.gz b/3rdparty/libprocess/3rdparty/boost-1.53.0.tar.gz
new file mode 100644
index 0000000..770d837
Binary files /dev/null and b/3rdparty/libprocess/3rdparty/boost-1.53.0.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/glog-0.3.1.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/glog-0.3.1.tar.gz b/3rdparty/libprocess/3rdparty/glog-0.3.1.tar.gz
new file mode 100644
index 0000000..19b4b94
Binary files /dev/null and b/3rdparty/libprocess/3rdparty/glog-0.3.1.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/gmock-1.6.0.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/gmock-1.6.0.tar.gz b/3rdparty/libprocess/3rdparty/gmock-1.6.0.tar.gz
new file mode 100644
index 0000000..d45d989
Binary files /dev/null and b/3rdparty/libprocess/3rdparty/gmock-1.6.0.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/gperftools-2.0.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/gperftools-2.0.tar.gz b/3rdparty/libprocess/3rdparty/gperftools-2.0.tar.gz
new file mode 100644
index 0000000..13b03ca
Binary files /dev/null and b/3rdparty/libprocess/3rdparty/gperftools-2.0.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/libev-4.15.patch
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/libev-4.15.patch b/3rdparty/libprocess/3rdparty/libev-4.15.patch
new file mode 100644
index 0000000..2b94532
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/libev-4.15.patch
@@ -0,0 +1,11 @@
+diff -rupN libev-4.15/ev.h libev-4.15-patched/ev.h
+--- libev-4.15/ev.h 2013-03-01 03:05:29.000000000 -0800
++++ libev-4.15-patched/ev.h 2013-05-20 16:01:47.000000000 -0700
+@@ -121,7 +121,7 @@ EV_CPP(extern "C" {)
+ # ifdef _WIN32
+ # define EV_CHILD_ENABLE 0
+ # else
+-# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
++# define EV_CHILD_ENABLE 0
+ #endif
+ #endif
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/libev-4.15.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/libev-4.15.tar.gz b/3rdparty/libprocess/3rdparty/libev-4.15.tar.gz
new file mode 100644
index 0000000..4c282b5
Binary files /dev/null and b/3rdparty/libprocess/3rdparty/libev-4.15.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/protobuf-2.4.1.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/protobuf-2.4.1.tar.gz b/3rdparty/libprocess/3rdparty/protobuf-2.4.1.tar.gz
new file mode 100644
index 0000000..38ec4de
Binary files /dev/null and b/3rdparty/libprocess/3rdparty/protobuf-2.4.1.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz b/3rdparty/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz
new file mode 100644
index 0000000..b811b63
Binary files /dev/null and b/3rdparty/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/LICENSE
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/LICENSE b/3rdparty/libprocess/3rdparty/stout/LICENSE
new file mode 100644
index 0000000..f433b1a
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/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/3rdparty/stout/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/Makefile.am b/3rdparty/libprocess/3rdparty/stout/Makefile.am
new file mode 100644
index 0000000..fdd3482
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/Makefile.am
@@ -0,0 +1,61 @@
+# Makefile for stout.
+
+ACLOCAL_AMFLAGS = -I m4
+
+AUTOMAKE_OPTIONS = foreign
+
+EXTRA_DIST = \
+ include/stout/bytes.hpp \
+ include/stout/cache.hpp \
+ include/stout/duration.hpp \
+ include/stout/error.hpp \
+ include/stout/exit.hpp \
+ include/stout/fatal.hpp \
+ include/stout/flags.hpp \
+ include/stout/flags/flag.hpp \
+ include/stout/flags/flags.hpp \
+ include/stout/flags/loader.hpp \
+ include/stout/flags/parse.hpp \
+ include/stout/foreach.hpp \
+ include/stout/format.hpp \
+ include/stout/fs.hpp \
+ include/stout/gtest.hpp \
+ include/stout/gzip.hpp \
+ include/stout/hashmap.hpp \
+ include/stout/hashset.hpp \
+ include/stout/json.hpp \
+ include/stout/lambda.hpp \
+ include/stout/multihashmap.hpp \
+ include/stout/multimap.hpp \
+ include/stout/net.hpp \
+ include/stout/none.hpp \
+ include/stout/nothing.hpp \
+ include/stout/numify.hpp \
+ include/stout/option.hpp \
+ include/stout/os.hpp \
+ include/stout/owned.hpp \
+ include/stout/path.hpp \
+ include/stout/preprocessor.hpp \
+ include/stout/proc.hpp \
+ include/stout/protobuf.hpp \
+ include/stout/result.hpp \
+ include/stout/stopwatch.hpp \
+ include/stout/stringify.hpp \
+ include/stout/strings.hpp \
+ include/stout/try.hpp \
+ include/stout/utils.hpp \
+ include/stout/uuid.hpp \
+ tests/bytes_tests.cpp \
+ tests/duration_tests.cpp \
+ tests/error_tests.cpp \
+ tests/flags_tests.cpp \
+ tests/gzip_tests.cpp \
+ tests/hashset_tests.cpp \
+ tests/json_tests.cpp \
+ tests/main.cpp \
+ tests/multimap_tests.cpp \
+ tests/none_tests.cpp \
+ tests/os_tests.cpp \
+ tests/proc_tests.cpp \
+ tests/strings_tests.cpp \
+ tests/uuid_tests.cpp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/README
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/README b/3rdparty/libprocess/3rdparty/stout/README
new file mode 100644
index 0000000..685a4ae
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/README
@@ -0,0 +1,32 @@
+Stout is a header-only C++ library.
+
+No action is needed if you would like to use this library in your
+project. Simply add the include folder to your include path during
+compilation.
+
+Depending on which headers you'd like to use, you may require the
+following third party libraries:
+
+ - Boost
+ - Google's glog (this dependency will be removed in the future).
+ - Google's protobuf.
+ - Google's gmock/gtest.
+
+
+Building Tests
+==============
+
+We'll assume you've got a distribution of gmock and have already built
+a static archive called libgmock.a (see gmock's README to learn
+how). We'll also assume the Boost and glog headers can be found via
+the include paths and libglog.* can be found via the library search
+paths. You can then build the tests via:
+
+$ g++ -I${STOUT}/include -I$(GMOCK)/gtest/include -I$(GMOCK)/include \
+ ${STOUT}/tests/tests.cpp libgmock.a -lglog -o tests
+
+Note that if you want to test the gzip headers you'll need to define
+HAVE_LIBZ and link against libz:
+
+$ g++ -I${STOUT}/include -I$(GMOCK)/gtest/include -I$(GMOCK)/include \
+ -DHAVE_LIBZ ${STOUT}/tests/tests.cpp libgmock.a -lglog -lz -o tests
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/bootstrap
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/bootstrap b/3rdparty/libprocess/3rdparty/stout/bootstrap
new file mode 100755
index 0000000..89b9bc8
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/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 "${@}"
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/configure.ac
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/configure.ac b/3rdparty/libprocess/3rdparty/stout/configure.ac
new file mode 100644
index 0000000..86e1ff3
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/configure.ac
@@ -0,0 +1,14 @@
+# Generated with autoscan, then modified appropriately.
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.61])
+AC_INIT([stout], [0.1.0])
+
+AC_LANG([C++])
+
+# Initialize automake.
+AM_INIT_AUTOMAKE([1.10])
+
+AC_CONFIG_FILES([Makefile])
+
+AC_OUTPUT
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/bytes.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/bytes.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/bytes.hpp
new file mode 100644
index 0000000..754fbb2
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/bytes.hpp
@@ -0,0 +1,160 @@
+#ifndef __STOUT_BYTES_HPP__
+#define __STOUT_BYTES_HPP__
+
+#include <ctype.h> // For 'isdigit'.
+#include <stdint.h>
+
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+#include "numify.hpp"
+#include "strings.hpp"
+#include "try.hpp"
+
+
+class Bytes
+{
+public:
+ static Try<Bytes> parse(const std::string& s)
+ {
+ size_t index = 0;
+
+ while (index < s.size()) {
+ if (isdigit(s[index])) {
+ index++;
+ continue;
+ } else if (s[index] == '.') {
+ return Error("Fractional bytes '" + s + "'");
+ }
+
+ Try<uint64_t> value = numify<uint64_t>(s.substr(0, index));
+
+ if (value.isError()) {
+ return Error(value.error());
+ }
+
+ const std::string& unit = strings::upper(s.substr(index));
+
+ if (unit == "B") {
+ return Bytes(value.get(), BYTES);
+ } else if (unit == "KB") {
+ return Bytes(value.get(), KILOBYTES);
+ } else if (unit == "MB") {
+ return Bytes(value.get(), MEGABYTES);
+ } else if (unit == "GB") {
+ return Bytes(value.get(), GIGABYTES);
+ } else if (unit == "TB") {
+ return Bytes(value.get(), TERABYTES);
+ } else {
+ return Error("Unknown bytes unit '" + unit + "'");
+ }
+ }
+ return Error("Invalid bytes '" + s + "'");
+ }
+
+ Bytes(uint64_t bytes = 0) : value(bytes) {}
+ Bytes(uint64_t _value, uint64_t _unit) : value(_value * _unit) {}
+
+ // TODO(bmahler): Consider killing kilobytes to terabyte helpers, given
+ // they implicitly lose precision if not careful.
+ uint64_t bytes() const { return value; }
+ uint64_t kilobytes() const { return value / KILOBYTES; }
+ uint64_t megabytes() const { return value / MEGABYTES; }
+ uint64_t gigabytes() const { return value / GIGABYTES; }
+ uint64_t terabytes() const { return value / TERABYTES; }
+
+ bool operator < (const Bytes& that) const { return value < that.value; }
+ bool operator <= (const Bytes& that) const { return value <= that.value; }
+ bool operator > (const Bytes& that) const { return value > that.value; }
+ bool operator >= (const Bytes& that) const { return value >= that.value; }
+ bool operator == (const Bytes& that) const { return value == that.value; }
+ bool operator != (const Bytes& that) const { return value != that.value; }
+
+ Bytes& operator += (const Bytes& that)
+ {
+ value += that.value;
+ return *this;
+ }
+
+ Bytes& operator -= (const Bytes& that)
+ {
+ value -= that.value;
+ return *this;
+ }
+
+protected:
+ static const uint64_t BYTES = 1;
+ static const uint64_t KILOBYTES = 1024 * BYTES;
+ static const uint64_t MEGABYTES = 1024 * KILOBYTES;
+ static const uint64_t GIGABYTES = 1024 * MEGABYTES;
+ static const uint64_t TERABYTES = 1024 * GIGABYTES;
+
+private:
+ uint64_t value;
+};
+
+
+class Kilobytes : public Bytes
+{
+public:
+ explicit Kilobytes(uint64_t value) : Bytes(value, KILOBYTES) {}
+};
+
+
+class Megabytes : public Bytes
+{
+public:
+ explicit Megabytes(uint64_t value) : Bytes(value, MEGABYTES) {}
+};
+
+
+class Gigabytes : public Bytes
+{
+public:
+ explicit Gigabytes(uint64_t value) : Bytes(value, GIGABYTES) {}
+};
+
+
+class Terabytes : public Bytes
+{
+public:
+ explicit Terabytes(uint64_t value) : Bytes(value, TERABYTES) {}
+};
+
+
+inline std::ostream& operator << (std::ostream& stream, const Bytes& bytes)
+{
+ // Only raise the unit when there is no loss of information.
+ if (bytes.bytes() == 0) {
+ return stream << bytes.bytes() << "B";
+ } else if (bytes.bytes() % 1024 != 0) {
+ return stream << bytes.bytes() << "B";
+ } else if (bytes.kilobytes() % 1024 != 0) {
+ return stream << bytes.kilobytes() << "KB";
+ } else if (bytes.megabytes() % 1024 != 0) {
+ return stream << bytes.megabytes() << "MB";
+ } else if (bytes.gigabytes() % 1024 != 0) {
+ return stream << bytes.gigabytes() << "GB";
+ } else {
+ return stream << bytes.terabytes() << "TB";
+ }
+}
+
+
+inline Bytes operator + (const Bytes& lhs, const Bytes& rhs)
+{
+ Bytes sum = lhs;
+ sum += rhs;
+ return sum;
+}
+
+
+inline Bytes operator - (const Bytes& lhs, const Bytes& rhs)
+{
+ Bytes diff = lhs;
+ diff -= rhs;
+ return diff;
+}
+
+#endif // __STOUT_BYTES_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/cache.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/cache.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/cache.hpp
new file mode 100644
index 0000000..653507c
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/cache.hpp
@@ -0,0 +1,131 @@
+#ifndef __STOUT_CACHE_HPP__
+#define __STOUT_CACHE_HPP__
+
+#include <functional>
+#include <iostream>
+#include <list>
+#include <map>
+
+#include <tr1/functional>
+#include <tr1/unordered_map>
+
+#include "none.hpp"
+#include "option.hpp"
+
+// Forward declaration.
+template <typename Key, typename Value>
+class cache;
+
+// Outputs the key/value pairs from least to most-recently used.
+template <typename Key, typename Value>
+std::ostream& operator << (
+ std::ostream& stream,
+ const cache<Key, Value>& c);
+
+
+// Provides a least-recently used (LRU) cache of some predefined
+// capacity. A "write" and a "read" both count as uses.
+template <typename Key, typename Value>
+class cache
+{
+public:
+ typedef std::list<Key> list;
+ typedef std::tr1::unordered_map<
+ Key, std::pair<Value, typename list::iterator> > map;
+
+ explicit cache(int _capacity) : capacity(_capacity) {}
+
+ void put(const Key& key, const Value& value)
+ {
+ typename map::iterator i = values.find(key);
+ if (i == values.end()) {
+ insert(key, value);
+ } else {
+ (*i).second.first = value;
+ use(i);
+ }
+ }
+
+ Option<Value> get(const Key& key)
+ {
+ typename map::iterator i = values.find(key);
+
+ if (i != values.end()) {
+ use(i);
+ return (*i).second.first;
+ }
+
+ return None();
+ }
+
+private:
+ // Not copyable, not assignable.
+ cache(const cache&);
+ cache& operator = (const cache&);
+
+ // Give the operator access to our internals.
+ friend std::ostream& operator << <>(
+ std::ostream& stream,
+ const cache<Key, Value>& c);
+
+ // Insert key/value into the cache.
+ void insert(const Key& key, const Value& value)
+ {
+ if (keys.size() == capacity) {
+ evict();
+ }
+
+ // Get a "pointer" into the lru list for efficient update.
+ typename list::iterator i = keys.insert(keys.end(), key);
+
+ // Save key/value and "pointer" into lru list.
+ values.insert(std::make_pair(key, std::make_pair(value, i)));
+ }
+
+ // Updates the LRU ordering in the cache for the given iterator.
+ void use(const typename map::iterator& i)
+ {
+ // Move the "pointer" to the end of the lru list.
+ keys.splice(keys.end(), keys, (*i).second.second);
+
+ // Now update the "pointer" so we can do this again.
+ (*i).second.second = --keys.end();
+ }
+
+ // Evict the least-recently used element from the cache.
+ void evict()
+ {
+ const typename map::iterator& i = values.find(keys.front());
+ CHECK(i != values.end());
+ values.erase(i);
+ keys.pop_front();
+ }
+
+ // Size of the cache.
+ int capacity;
+
+ // Cache of values and "pointers" into the least-recently used list.
+ map values;
+
+ // Keys ordered by least-recently used.
+ list keys;
+};
+
+
+template <typename Key, typename Value>
+std::ostream& operator << (
+ std::ostream& stream,
+ const cache<Key, Value>& c)
+{
+ typename cache<Key, Value>::list::const_iterator i1;
+ for (i1 = c.keys.begin(); i1 != c.keys.end(); i1++) {
+ stream << *i1 << ": ";
+ typename cache<Key, Value>::map::const_iterator i2;
+ i2 = c.values.find(*i1);
+ CHECK(i2 != c.values.end());
+ stream << *i2 << std::endl;
+ }
+ return stream;
+}
+
+#endif // __STOUT_CACHE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp
new file mode 100644
index 0000000..47e85ff
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/duration.hpp
@@ -0,0 +1,297 @@
+#ifndef __STOUT_DURATION_HPP__
+#define __STOUT_DURATION_HPP__
+
+#include <ctype.h> // For 'isdigit'.
+#include <limits.h> // For 'LLONG_(MAX|MIN)'
+
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+#include "error.hpp"
+#include "numify.hpp"
+#include "try.hpp"
+
+class Duration
+{
+public:
+ static Try<Duration> parse(const std::string& s)
+ {
+ // TODO(benh): Support negative durations (i.e., starts with '-').
+ size_t index = 0;
+ while (index < s.size()) {
+ if (isdigit(s[index]) || s[index] == '.') {
+ index++;
+ continue;
+ }
+
+ Try<double> value = numify<double>(s.substr(0, index));
+
+ if (value.isError()) {
+ return Error(value.error());
+ }
+
+ const std::string& unit = s.substr(index);
+
+ if (unit == "ns") {
+ return Duration(value.get(), NANOSECONDS);
+ } else if (unit == "us") {
+ return Duration(value.get(), MICROSECONDS);
+ } else if (unit == "ms") {
+ return Duration(value.get(), MILLISECONDS);
+ } else if (unit == "secs") {
+ return Duration(value.get(), SECONDS);
+ } else if (unit == "mins") {
+ return Duration(value.get(), MINUTES);
+ } else if (unit == "hrs") {
+ return Duration(value.get(), HOURS);
+ } else if (unit == "days") {
+ return Duration(value.get(), DAYS);
+ } else if (unit == "weeks") {
+ return Duration(value.get(), WEEKS);
+ } else {
+ return Error("Unknown duration unit '" + unit + "'");
+ }
+ }
+ return Error("Invalid duration '" + s + "'");
+ }
+
+ static Try<Duration> create(double seconds);
+
+ Duration() : nanos(0) {}
+
+ int64_t ns() const { return nanos; }
+ double us() const { return static_cast<double>(nanos) / MICROSECONDS; }
+ double ms() const { return static_cast<double>(nanos) / MILLISECONDS; }
+ double secs() const { return static_cast<double>(nanos) / SECONDS; }
+ double mins() const { return static_cast<double>(nanos) / MINUTES; }
+ double hrs() const { return static_cast<double>(nanos) / HOURS; }
+ double days() const { return static_cast<double>(nanos) / DAYS; }
+ double weeks() const { return static_cast<double>(nanos) / WEEKS; }
+
+ bool operator < (const Duration& d) const { return nanos < d.nanos; }
+ bool operator <= (const Duration& d) const { return nanos <= d.nanos; }
+ bool operator > (const Duration& d) const { return nanos > d.nanos; }
+ bool operator >= (const Duration& d) const { return nanos >= d.nanos; }
+ bool operator == (const Duration& d) const { return nanos == d.nanos; }
+ bool operator != (const Duration& d) const { return nanos != d.nanos; }
+
+ Duration& operator += (const Duration& that)
+ {
+ nanos += that.nanos;
+ return *this;
+ }
+
+ Duration& operator -= (const Duration& that)
+ {
+ nanos -= that.nanos;
+ return *this;
+ }
+
+ Duration& operator *= (double multiplier)
+ {
+ nanos = static_cast<int64_t>(nanos * multiplier);
+ return *this;
+ }
+
+ Duration& operator /= (double divisor)
+ {
+ nanos = static_cast<int64_t>(nanos / divisor);
+ return *this;
+ }
+
+ Duration operator + (const Duration& that) const
+ {
+ Duration sum = *this;
+ sum += that;
+ return sum;
+ }
+
+ Duration operator - (const Duration& that) const
+ {
+ Duration diff = *this;
+ diff -= that;
+ return diff;
+ }
+
+ Duration operator * (double multiplier) const
+ {
+ Duration product = *this;
+ product *= multiplier;
+ return product;
+ }
+
+ Duration operator / (double divisor) const
+ {
+ Duration quotient = *this;
+ quotient /= divisor;
+ return quotient;
+ }
+
+ // TODO(xujyan): Use constexpr for the following variables after
+ // switching to C++11.
+ // A constant holding the maximum value a Duration can have.
+ static Duration max();
+ // A constant holding the minimum (negative) value a Duration can
+ // have.
+ static Duration min();
+ // A constant holding a Duration of a "zero" value.
+ static Duration zero() { return Duration(); }
+
+protected:
+ static const int64_t NANOSECONDS = 1;
+ static const int64_t MICROSECONDS = 1000 * NANOSECONDS;
+ static const int64_t MILLISECONDS = 1000 * MICROSECONDS;
+ static const int64_t SECONDS = 1000 * MILLISECONDS;
+ static const int64_t MINUTES = 60 * SECONDS;
+ static const int64_t HOURS = 60 * MINUTES;
+ static const int64_t DAYS = 24 * HOURS;
+ static const int64_t WEEKS = 7 * DAYS;
+
+ // For the Seconds, Minutes, Hours, Days & Weeks constructor.
+ Duration(int32_t value, int64_t unit)
+ : nanos(value * unit) {}
+
+ // For the Nanoseconds, Microseconds, Milliseconds constructor.
+ Duration(int64_t value, int64_t unit)
+ : nanos(value * unit) {}
+
+private:
+ // Used only by "parse".
+ Duration(double value, int64_t unit)
+ : nanos(static_cast<int64_t>(value * unit)) {}
+
+ int64_t nanos;
+};
+
+
+class Nanoseconds : public Duration
+{
+public:
+ explicit Nanoseconds(int64_t nanoseconds)
+ : Duration(nanoseconds, NANOSECONDS) {}
+
+ Nanoseconds(const Duration& d) : Duration(d) {}
+};
+
+
+class Microseconds : public Duration
+{
+public:
+ explicit Microseconds(int64_t microseconds)
+ : Duration(microseconds, MICROSECONDS) {}
+
+ Microseconds(const Duration& d) : Duration(d) {}
+};
+
+
+class Milliseconds : public Duration
+{
+public:
+ explicit Milliseconds(int64_t milliseconds)
+ : Duration(milliseconds, MILLISECONDS) {}
+
+ Milliseconds(const Duration& d) : Duration(d) {}
+};
+
+
+class Seconds : public Duration
+{
+public:
+ explicit Seconds(int64_t seconds)
+ : Duration(seconds, SECONDS) {}
+
+ Seconds(const Duration& d) : Duration(d) {}
+};
+
+
+class Minutes : public Duration
+{
+public:
+ explicit Minutes(int32_t minutes)
+ : Duration(minutes, MINUTES) {}
+
+ Minutes(const Duration& d) : Duration(d) {}
+};
+
+
+class Hours : public Duration
+{
+public:
+ explicit Hours(int32_t hours)
+ : Duration(hours, HOURS) {}
+
+ Hours(const Duration& d) : Duration(d) {}
+};
+
+
+class Days : public Duration
+{
+public:
+ explicit Days(int32_t days)
+ : Duration(days, DAYS) {}
+
+ Days(const Duration& d) : Duration(d) {}
+};
+
+
+class Weeks : public Duration
+{
+public:
+ explicit Weeks(int32_t value) : Duration(value, WEEKS) {}
+
+ Weeks(const Duration& d) : Duration(d) {}
+};
+
+
+inline std::ostream& operator << (
+ std::ostream& stream,
+ const Duration& duration)
+{
+ long precision = stream.precision();
+
+ // Output the duration in full double precision.
+ stream.precision(std::numeric_limits<double>::digits10);
+
+ if (duration < Microseconds(1)) {
+ stream << duration.ns() << "ns";
+ } else if (duration < Milliseconds(1)) {
+ stream << duration.us() << "us";
+ } else if (duration < Seconds(1)) {
+ stream << duration.ms() << "ms";
+ } else if (duration < Minutes(1)) {
+ stream << duration.secs() << "secs";
+ } else if (duration < Hours(1)) {
+ stream << duration.mins() << "mins";
+ } else if (duration < Days(1)) {
+ stream << duration.hrs() << "hrs";
+ } else if (duration < Weeks(1)) {
+ stream << duration.days() << "days";
+ } else {
+ stream << duration.weeks() << "weeks";
+ }
+
+ // Return the stream to original formatting state.
+ stream.precision(precision);
+
+ return stream;
+}
+
+
+inline Try<Duration> Duration::create(double seconds)
+{
+ if (seconds * SECONDS > LLONG_MAX) {
+ return Error("Argument larger than the maximum number of seconds that "
+ "a Duration can represent due to int64_t's size limit.");
+ }
+
+ return Nanoseconds(static_cast<int64_t>(seconds * SECONDS));
+}
+
+
+inline Duration Duration::max() { return Nanoseconds(LLONG_MAX); }
+
+
+inline Duration Duration::min() { return Nanoseconds(LLONG_MIN); }
+
+#endif // __STOUT_DURATION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp
new file mode 100644
index 0000000..97a5cec
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/error.hpp
@@ -0,0 +1,72 @@
+#ifndef __STOUT_ERROR_HPP__
+#define __STOUT_ERROR_HPP__
+
+#include <errno.h>
+#include <string.h> // For strerror.
+
+#include <string>
+
+#include "result.hpp"
+#include "try.hpp"
+
+// An "error" type that is implicitly convertible to a Try<T> or
+// Result<T> for any T (effectively "syntactic sugar" to make code
+// more readable). The implementation uses cast operators to perform
+// the conversions instead of adding constructors to Try/Result
+// directly. One could imagine revisiting that decision for C++11
+// because the use of rvalue reference could eliminate some
+// unnecessary copies. However, performance is not critical since
+// Error should not get called very often in practice (if so, it's
+// probably being used for things that aren't really errors or there
+// is a more serious problem during execution).
+
+class Error
+{
+public:
+ explicit Error(const std::string& _message) : message(_message) {}
+
+ template <typename T>
+ operator Try<T> () const
+ {
+ return Try<T>::error(message);
+ }
+
+ // Give the compiler some help for nested Try<T>. For example,
+ // enable converting Error to an Option<Try<T>>. Note that this will
+ // bind to the innermost Try<T>.
+ template <template <typename> class S, typename T>
+ operator S<Try<T> > () const
+ {
+ return S<Try<T> >(Try<T>::error(message));
+ }
+
+ template <typename T>
+ operator Result<T> () const
+ {
+ return Result<T>::error(message);
+ }
+
+ // Give the compiler some help for nested Result<T>. For example,
+ // enable converting Error to an Option<Result<T>>. Note that this
+ // will bind to the innermost Result<T>.
+ template <template <typename> class S, typename T>
+ operator S<Result<T> > () const
+ {
+ return S<Result<T> >(Result<T>::error(message));
+ }
+
+ const std::string message;
+};
+
+
+class ErrnoError : public Error
+{
+public:
+ ErrnoError()
+ : Error(std::string(strerror(errno))) {}
+
+ ErrnoError(const std::string& message)
+ : Error(message + ": " + std::string(strerror(errno))) {}
+};
+
+#endif // __STOUT_ERROR_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp
new file mode 100644
index 0000000..e8da726
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/exit.hpp
@@ -0,0 +1,37 @@
+#ifndef __STOUT_EXIT_HPP__
+#define __STOUT_EXIT_HPP__
+
+#include <stdlib.h>
+
+#include <iostream> // For std::cerr.
+#include <ostream>
+#include <sstream>
+#include <string>
+
+// Exit takes an exit status and provides a stream for output prior to
+// exiting. This is like glog's LOG(FATAL) or CHECK, except that it
+// does _not_ print a stack trace.
+//
+// Ex: EXIT(1) << "Cgroups are not present in this system.";
+#define EXIT(status) __Exit(status).stream()
+
+struct __Exit
+{
+ __Exit(int _status) : status(_status) {}
+
+ ~__Exit()
+ {
+ std::cerr << out.str() << std::endl;
+ exit(status);
+ }
+
+ std::ostream& stream()
+ {
+ return out;
+ }
+
+ std::ostringstream out;
+ const int status;
+};
+
+#endif // __STOUT_EXIT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/fatal.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/fatal.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/fatal.hpp
new file mode 100644
index 0000000..eabee3e
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/fatal.hpp
@@ -0,0 +1,43 @@
+#ifndef __STOUT_FATAL_HPP__
+#define __STOUT_FATAL_HPP__
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*
+ * Like the non-debug version except includes the file name and line
+ * number in the output.
+ */
+#define fatal(fmt...) __fatal(__FILE__, __LINE__, fmt)
+inline void __fatal(const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, " (%s:%u)\n", file, line);
+ fflush(stderr);
+ va_end(args);
+ exit(1);
+}
+
+
+/*
+ * Like the non-debug version except includes the file name and line
+ * number in the output.
+ */
+#define fatalerror(fmt...) __fatalerror(__FILE__, __LINE__, fmt)
+inline void __fatalerror(const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, " (%s:%u): ", file, line);
+ perror(NULL);
+ fflush(stderr);
+ va_end(args);
+ exit(1);
+}
+
+#endif // __STOUT_FATAL_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/flags.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/flags.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/flags.hpp
new file mode 100644
index 0000000..0efd079
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/flags.hpp
@@ -0,0 +1,70 @@
+#ifndef __STOUT_FLAGS_HPP__
+#define __STOUT_FLAGS_HPP__
+
+#include <stout/flags/flags.hpp>
+
+// An abstraction for application/library "flags". An example is
+// probably best:
+// -------------------------------------------------------------
+// class MyFlags : public virtual FlagsBase // Use 'virtual' for composition!
+// {
+// public:
+// Flags()
+// {
+// add(&debug,
+// "debug",
+// "Help string for debug",
+// false);
+//
+// add(&name,
+// "name",
+// "Help string for name");
+// }
+
+// bool debug;
+// Option<string> name;
+// };
+//
+// ...
+//
+// map<string, Option<string> > values;
+// values["no-debug"] = None(); // --no-debug
+// values["debug"] = None(); // --debug
+// values["debug"] = Option<string>::some("true"); // --debug=true
+// values["debug"] = Option<string>::some("false"); // --debug=false
+// values["name"] = Option<string>::some("frank"); // --name=frank
+//
+// MyFlags flags;
+// flags.load(values);
+// flags.name.isSome() ...
+// flags.debug ...
+// -------------------------------------------------------------
+//
+// You can also compose flags provided that each has used "virtual
+// inheritance":
+// -------------------------------------------------------------
+// Flags<MyFlags1, MyFlags2> flags;
+// flags.add(...); // Any other flags you want to throw in there.
+// flags.load(values);
+// flags.flag_from_myflags1 ...
+// flags.flag_from_myflags2 ...
+// -------------------------------------------------------------
+//
+// "Fail early, fail often":
+//
+// You can not add duplicate flags, this is checked for you at compile
+// time for composite flags (e.g., Flag<MyFlags1, MyFlags2>) and also
+// checked at runtime for any other flags added via inheritance or
+// Flags::add(...).
+//
+// Flags that can not be loaded (e.g., attempting to use the 'no-'
+// prefix for a flag that is not boolean) will print a message to
+// standard error and abort the process.
+
+// TODO(benh): Provide a boolean which specifies whether or not to
+// abort on duplicates or load errors.
+
+// TODO(benh): Make prefix for environment variables configurable
+// (e.g., "MESOS_").
+
+#endif // __STOUT_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flag.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
new file mode 100644
index 0000000..d31c984
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
@@ -0,0 +1,26 @@
+#ifndef __STOUT_FLAGS_FLAG_HPP__
+#define __STOUT_FLAGS_FLAG_HPP__
+
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+namespace flags {
+
+// Forward declaration.
+class FlagsBase;
+
+struct Flag
+{
+ std::string name;
+ std::string help;
+ bool boolean;
+ std::tr1::function<Try<Nothing>(FlagsBase*, const std::string&)> loader;
+};
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_FLAG_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
new file mode 100644
index 0000000..77d36e6
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
@@ -0,0 +1,481 @@
+#ifndef __STOUT_FLAGS_FLAGS_HPP__
+#define __STOUT_FLAGS_FLAGS_HPP__
+
+#include <stdlib.h> // For abort.
+
+#include <map>
+#include <string>
+#include <typeinfo> // For typeid.
+
+#include <tr1/functional>
+
+#include <stout/error.hpp>
+#include <stout/exit.hpp>
+#include <stout/foreach.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/os.hpp>
+#include <stout/stringify.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+
+#include <stout/flags/flag.hpp>
+#include <stout/flags/loader.hpp>
+#include <stout/flags/parse.hpp>
+
+namespace flags {
+
+class FlagsBase
+{
+public:
+ virtual ~FlagsBase() {}
+
+ // Load any flags from the environment given the variable prefix,
+ // i.e., given prefix 'STOUT_' will load a flag named 'foo' via
+ // environment variables 'STOUT_foo' or 'STOUT_FOO'.
+ virtual Try<Nothing> load(
+ const std::string& prefix,
+ bool unknowns = false);
+
+ // Load any flags from the environment given the variable prefix
+ // (see above) followed by loading from the command line (via 'argc'
+ // and 'argv'). If 'unknowns' is true then we'll ignore unknown
+ // flags we see while loading. If 'duplicates' is true then we'll
+ // ignore any duplicates we see while loading.
+ virtual Try<Nothing> load(
+ const Option<std::string>& prefix,
+ int argc,
+ char** argv,
+ bool unknowns = false,
+ bool duplicates = false);
+
+ Try<Nothing> load(
+ const std::string& prefix,
+ int argc,
+ char** argv,
+ bool unknowns = false,
+ bool duplicates = false);
+
+ virtual Try<Nothing> load(
+ const std::map<std::string, Option<std::string> >& values,
+ bool unknowns = false);
+
+ virtual Try<Nothing> load(
+ const std::map<std::string, std::string>& values,
+ bool unknowns = false);
+
+ // Returns a string describing the flags.
+ std::string usage() const;
+
+ typedef std::map<std::string, Flag>::const_iterator const_iterator;
+
+ const_iterator begin() const { return flags.begin(); }
+ const_iterator end() const { return flags.end(); }
+
+ template <typename T1, typename T2>
+ void add(T1* t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2);
+
+ template <typename T>
+ void add(Option<T>* option,
+ const std::string& name,
+ const std::string& help);
+
+protected:
+ template <typename Flags, typename T1, typename T2>
+ void add(T1 Flags::*t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2);
+
+ template <typename Flags, typename T>
+ void add(Option<T> Flags::*option,
+ const std::string& name,
+ const std::string& help);
+
+ void add(const Flag& flag);
+
+private:
+ std::map<std::string, Flag> flags;
+};
+
+
+// Need to declare/define some explicit subclasses of FlagsBase so
+// that we can overload the 'Flags::operator FlagsN () const'
+// functions for each possible type.
+class _Flags1 : public virtual FlagsBase {};
+class _Flags2 : public virtual FlagsBase {};
+class _Flags3 : public virtual FlagsBase {};
+class _Flags4 : public virtual FlagsBase {};
+class _Flags5 : public virtual FlagsBase {};
+
+
+// TODO(benh): Add some "type constraints" for template paramters to
+// make sure they are all of type FlagsBase.
+template <typename Flags1 = _Flags1,
+ typename Flags2 = _Flags2,
+ typename Flags3 = _Flags3,
+ typename Flags4 = _Flags4,
+ typename Flags5 = _Flags5>
+class Flags : public virtual Flags1,
+ public virtual Flags2,
+ public virtual Flags3,
+ public virtual Flags4,
+ public virtual Flags5 {};
+
+
+template <typename T1, typename T2>
+void FlagsBase::add(
+ T1* t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2)
+{
+ *t1 = t2; // Set the default.
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T1) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &Loader<T1>::load,
+ t1,
+ std::tr1::function<Try<T1>(const std::string&)>(
+ std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
+
+ // Update the help string to include the default value.
+ flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
+ ? " (default: " // On same line, add space.
+ : "(default: "; // On newline.
+ flag.help += stringify(t2);
+ flag.help += ")";
+
+ FlagsBase::add(flag);
+}
+
+
+template <typename T>
+void FlagsBase::add(
+ Option<T>* option,
+ const std::string& name,
+ const std::string& help)
+{
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &OptionLoader<T>::load,
+ option,
+ std::tr1::function<Try<T>(const std::string&)>(
+ std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
+
+ FlagsBase::add(flag);
+}
+
+
+template <typename Flags, typename T1, typename T2>
+void FlagsBase::add(
+ T1 Flags::*t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2)
+{
+ Flags* flags = dynamic_cast<Flags*>(this);
+ if (flags == NULL) {
+ std::cerr << "Attempted to add flag '" << name
+ << "' with incompatible type" << std::endl;
+ abort();
+ } else {
+ flags->*t1 = t2; // Set the default.
+ }
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T1) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &MemberLoader<Flags, T1>::load,
+ std::tr1::placeholders::_1,
+ t1,
+ std::tr1::function<Try<T1>(const std::string&)>(
+ std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2);
+
+ // Update the help string to include the default value.
+ flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
+ ? " (default: " // On same line, add space.
+ : "(default: "; // On newline.
+ flag.help += stringify(t2);
+ flag.help += ")";
+
+ add(flag);
+}
+
+
+template <typename Flags, typename T>
+void FlagsBase::add(
+ Option<T> Flags::*option,
+ const std::string& name,
+ const std::string& help)
+{
+ Flags* flags = dynamic_cast<Flags*>(this);
+ if (flags == NULL) {
+ std::cerr << "Attempted to add flag '" << name
+ << "' with incompatible type" << std::endl;
+ abort();
+ }
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &OptionMemberLoader<Flags, T>::load,
+ std::tr1::placeholders::_1,
+ option,
+ std::tr1::function<Try<T>(const std::string&)>(
+ std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2);
+
+ add(flag);
+}
+
+
+inline void FlagsBase::add(const Flag& flag)
+{
+ if (flags.count(flag.name) > 0) {
+ EXIT(1) << "Attempted to add duplicate flag '" << flag.name << "'";
+ } else if (flag.name.find("no-") == 0) {
+ EXIT(1) << "Attempted to add flag '" << flag.name
+ << "' that starts with the reserved 'no-' prefix";
+ }
+
+ flags[flag.name] = flag;
+}
+
+
+// Extract environment variable "flags" with the specified prefix.
+inline std::map<std::string, Option<std::string> > extract(
+ const std::string& prefix)
+{
+ char** environ = os::environ();
+
+ std::map<std::string, Option<std::string> > values;
+
+ for (int i = 0; environ[i] != NULL; i++) {
+ std::string variable = environ[i];
+ if (variable.find(prefix) == 0) {
+ size_t eq = variable.find_first_of("=");
+ if (eq == std::string::npos) {
+ continue; // Not expecting a missing '=', but ignore anyway.
+ }
+ std::string name = variable.substr(prefix.size(), eq - prefix.size());
+ name = strings::lower(name); // Allow PREFIX_NAME or PREFIX_name.
+ std::string value = variable.substr(eq + 1);
+ values[name] = Option<std::string>::some(value);
+ }
+ }
+
+ return values;
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::string& prefix,
+ bool unknowns)
+{
+ return load(extract(prefix), unknowns);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const Option<std::string>& prefix,
+ int argc,
+ char** argv,
+ bool unknowns,
+ bool duplicates)
+{
+ std::map<std::string, Option<std::string> > values;
+
+ if (prefix.isSome()) {
+ values = extract(prefix.get());
+ }
+
+ // Read flags from the command line.
+ for (int i = 1; i < argc; i++) {
+ const std::string arg(argv[i]);
+
+ std::string name;
+ Option<std::string> value = None();
+ if (arg.find("--") == 0) {
+ size_t eq = arg.find_first_of("=");
+ if (eq == std::string::npos && arg.find("--no-") == 0) { // --no-name
+ name = arg.substr(2);
+ } else if (eq == std::string::npos) { // --name
+ name = arg.substr(2);
+ } else { // --name=value
+ name = arg.substr(2, eq - 2);
+ value = arg.substr(eq + 1);
+ }
+ }
+ name = strings::lower(name);
+
+ if (!duplicates) {
+ if (values.count(name) > 0 ||
+ (name.find("no-") == 0 && values.count(name.substr(3)) > 0)) {
+ return Error("Duplicate flag '" + name + "' on command line");
+ }
+ }
+
+ values[name] = value;
+ }
+
+ return load(values, unknowns);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::string& prefix,
+ int argc,
+ char** argv,
+ bool unknowns,
+ bool duplicates)
+{
+ return load(Option<std::string>::some(prefix),
+ argc,
+ argv,
+ unknowns,
+ duplicates);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::map<std::string, Option<std::string> >& values,
+ bool unknowns)
+{
+ std::map<std::string, Option<std::string> >::const_iterator iterator;
+
+ for (iterator = values.begin(); iterator != values.end(); ++iterator) {
+ const std::string& name = iterator->first;
+ const Option<std::string>& value = iterator->second;
+
+ if (flags.count(name) > 0) {
+ if (value.isSome()) { // --name=value
+ if (flags[name].boolean && value.get() == "") {
+ flags[name].loader(this, "true"); // Should never fail.
+ } else {
+ Try<Nothing> loader = flags[name].loader(this, value.get());
+ if (loader.isError()) {
+ return Error(
+ "Failed to load flag '" + name + "': " + loader.error());
+ }
+ }
+ } else { // --name
+ if (flags[name].boolean) {
+ flags[name].loader(this, "true"); // Should never fail.
+ } else {
+ return Error(
+ "Failed to load non-boolean flag '" + name + "': Missing value");
+ }
+ }
+ } else if (name.find("no-") == 0) {
+ if (flags.count(name.substr(3)) > 0) { // --no-name
+ if (flags[name.substr(3)].boolean) {
+ if (value.isNone() || value.get() == "") {
+ flags[name.substr(3)].loader(this, "false"); // Should never fail.
+ } else {
+ return Error(
+ "Failed to load boolean flag '" + name.substr(3) +
+ "' via '" + name + "' with value '" + value.get() + "'");
+ }
+ } else {
+ return Error(
+ "Failed to load non-boolean flag '" + name.substr(3) +
+ "' via '" + name + "'");
+ }
+ } else {
+ return Error(
+ "Failed to load unknown flag '" + name.substr(3) +
+ "' via '" + name + "'");
+ }
+ } else if (!unknowns) {
+ return Error("Failed to load unknown flag '" + name + "'");
+ }
+ }
+
+ return Nothing();
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::map<std::string, std::string>& _values,
+ bool unknowns)
+{
+ std::map<std::string, Option<std::string> > values;
+ std::map<std::string, std::string>::const_iterator iterator;
+ for (iterator = _values.begin(); iterator != _values.end(); ++iterator) {
+ const std::string& name = iterator->first;
+ const std::string& value = iterator->second;
+ values[name] = Option<std::string>::some(value);
+ }
+ return load(values, unknowns);
+}
+
+
+inline std::string FlagsBase::usage() const
+{
+ const int PAD = 5;
+
+ std::string usage;
+
+ std::map<std::string, std::string> col1; // key -> col 1 string
+
+ // Construct string for the first column and store width of column.
+ size_t width = 0;
+
+ foreachvalue (const flags::Flag& flag, *this) {
+ if (flag.boolean) {
+ col1[flag.name] = " --[no-]" + flag.name;
+ } else {
+ col1[flag.name] = " --" + flag.name + "=VALUE";
+ }
+ width = std::max(width, col1[flag.name].size());
+ }
+
+ foreachvalue (const flags::Flag& flag, *this) {
+ std::string line = col1[flag.name];
+
+ std::string pad(PAD + width - line.size(), ' ');
+ line += pad;
+
+ size_t pos1 = 0, pos2 = 0;
+ pos2 = flag.help.find_first_of("\n\r", pos1);
+ line += flag.help.substr(pos1, pos2 - pos1) + "\n";
+ usage += line;
+
+ while (pos2 != std::string::npos) { // Handle multi-line help strings.
+ line = "";
+ pos1 = pos2 + 1;
+ std::string pad2(PAD + width, ' ');
+ line += pad2;
+ pos2 = flag.help.find_first_of("\n\r", pos1);
+ line += flag.help.substr(pos1, pos2 - pos1) + "\n";
+ usage += line;
+ }
+ }
+ return usage;
+}
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_FLAGS_HPP__
[19/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/tests/os_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/os_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/os_tests.cpp
deleted file mode 100644
index 047778d..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/os_tests.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/proc_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/proc_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/proc_tests.cpp
deleted file mode 100644
index 2305ef5..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/proc_tests.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * 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/third_party/libprocess/3rdparty/stout/tests/strings_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/strings_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/strings_tests.cpp
deleted file mode 100644
index 7ec9446..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/strings_tests.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/uuid_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/uuid_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/uuid_tests.cpp
deleted file mode 100644
index ad1d986..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/uuid_tests.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#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/third_party/libprocess/3rdparty/versions.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/versions.am b/third_party/libprocess/3rdparty/versions.am
deleted file mode 100644
index 0d05698..0000000
--- a/third_party/libprocess/3rdparty/versions.am
+++ /dev/null
@@ -1,11 +0,0 @@
-# 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/third_party/libprocess/LICENSE
----------------------------------------------------------------------
diff --git a/third_party/libprocess/LICENSE b/third_party/libprocess/LICENSE
deleted file mode 100644
index f433b1a..0000000
--- a/third_party/libprocess/LICENSE
+++ /dev/null
@@ -1,177 +0,0 @@
-
- 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/third_party/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/Makefile.am b/third_party/libprocess/Makefile.am
deleted file mode 100644
index b6b8abd..0000000
--- a/third_party/libprocess/Makefile.am
+++ /dev/null
@@ -1,125 +0,0 @@
-# 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/third_party/libprocess/README
----------------------------------------------------------------------
diff --git a/third_party/libprocess/README b/third_party/libprocess/README
deleted file mode 100644
index 89b009f..0000000
--- a/third_party/libprocess/README
+++ /dev/null
@@ -1,10 +0,0 @@
-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/third_party/libprocess/TODO
----------------------------------------------------------------------
diff --git a/third_party/libprocess/TODO b/third_party/libprocess/TODO
deleted file mode 100644
index 9770546..0000000
--- a/third_party/libprocess/TODO
+++ /dev/null
@@ -1,33 +0,0 @@
-/* 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/third_party/libprocess/bootstrap
----------------------------------------------------------------------
diff --git a/third_party/libprocess/bootstrap b/third_party/libprocess/bootstrap
deleted file mode 100755
index 1d3215d..0000000
--- a/third_party/libprocess/bootstrap
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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/third_party/libprocess/configure.ac
----------------------------------------------------------------------
diff --git a/third_party/libprocess/configure.ac b/third_party/libprocess/configure.ac
deleted file mode 100644
index d3b86a3..0000000
--- a/third_party/libprocess/configure.ac
+++ /dev/null
@@ -1,117 +0,0 @@
-# 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/third_party/libprocess/examples/example.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/examples/example.cpp b/third_party/libprocess/examples/example.cpp
deleted file mode 100644
index 3fb4ef5..0000000
--- a/third_party/libprocess/examples/example.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#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/third_party/libprocess/include/process/async.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/async.hpp b/third_party/libprocess/include/process/async.hpp
deleted file mode 100644
index 8fa2771..0000000
--- a/third_party/libprocess/include/process/async.hpp
+++ /dev/null
@@ -1,231 +0,0 @@
-#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/third_party/libprocess/include/process/clock.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/clock.hpp b/third_party/libprocess/include/process/clock.hpp
deleted file mode 100644
index 82ae3c6..0000000
--- a/third_party/libprocess/include/process/clock.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#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/third_party/libprocess/include/process/collect.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/collect.hpp b/third_party/libprocess/include/process/collect.hpp
deleted file mode 100644
index 8050351..0000000
--- a/third_party/libprocess/include/process/collect.hpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#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/third_party/libprocess/include/process/defer.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/defer.hpp b/third_party/libprocess/include/process/defer.hpp
deleted file mode 100644
index 1eb770b..0000000
--- a/third_party/libprocess/include/process/defer.hpp
+++ /dev/null
@@ -1,438 +0,0 @@
-#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/third_party/libprocess/include/process/deferred.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/deferred.hpp b/third_party/libprocess/include/process/deferred.hpp
deleted file mode 100644
index 8907e80..0000000
--- a/third_party/libprocess/include/process/deferred.hpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#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__
[29/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
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());
+}
[12/35] git commit: Added a 'Logging' process to libprocess.
Posted by be...@apache.org.
Added a 'Logging' process to libprocess.
Review: https://reviews.apache.org/r/11467
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/1f145338
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/1f145338
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/1f145338
Branch: refs/heads/master
Commit: 1f145338f5e8435e180d89f2c222a8aa4429eefd
Parents: 29183c1
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 26 23:26:39 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:18:39 2013 -0700
----------------------------------------------------------------------
third_party/libprocess/Makefile.am | 1 +
third_party/libprocess/include/process/logging.hpp | 111 +++++++++++++++
third_party/libprocess/src/process.cpp | 12 ++-
3 files changed, 122 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1f145338/third_party/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/Makefile.am b/third_party/libprocess/Makefile.am
index 0e89be8..c1db145 100644
--- a/third_party/libprocess/Makefile.am
+++ b/third_party/libprocess/Makefile.am
@@ -76,6 +76,7 @@ libprocess_la_SOURCES += \
$(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 \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1f145338/third_party/libprocess/include/process/logging.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/logging.hpp b/third_party/libprocess/include/process/logging.hpp
new file mode 100644
index 0000000..cba2fd4
--- /dev/null
+++ b/third_party/libprocess/include/process/logging.hpp
@@ -0,0 +1,111 @@
+#ifndef __PROCESS_LOGGING_HPP__
+#define __PROCESS_LOGGING_HPP__
+
+#include <glog/logging.h>
+
+#include <process/delay.hpp>
+#include <process/future.hpp>
+#include <process/http.hpp>
+#include <process/process.hpp>
+#include <process/timeout.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/numify.hpp>
+#include <stout/option.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+namespace process {
+
+class Logging : public Process<Logging>
+{
+public:
+ Logging()
+ : ProcessBase("logging"),
+ original(FLAGS_v)
+ {
+ // Make sure all reads/writes can be done atomically (i.e., to
+ // make sure VLOG(*) statements don't read partial writes).
+ // TODO(benh): Use "atomics" primitives for doing reads/writes of
+ // FLAGS_v anyway to account for proper memory barriers.
+ CHECK(sizeof(FLAGS_v) == sizeof(int32_t));
+ }
+
+ virtual ~Logging() {}
+
+protected:
+ virtual void initialize()
+ {
+ route("/toggle", &This::toggle);
+ }
+
+private:
+ Future<http::Response> toggle(const http::Request& request)
+ {
+ Option<std::string> level = request.query.get("level");
+ Option<std::string> duration = request.query.get("duration");
+
+ if (level.isNone() && duration.isNone()) {
+ return http::OK(stringify(FLAGS_v) + "\n");
+ }
+
+ if (level.isSome() && duration.isNone()) {
+ return http::BadRequest("Expecting 'duration=value' in query.\n");
+ } else if (level.isNone() && duration.isSome()) {
+ return http::BadRequest("Expecting 'level=value' in query.\n");
+ }
+
+ Try<int> v = numify<int>(level.get());
+
+ if (v.isError()) {
+ return http::BadRequest(v.error() + ".\n");
+ }
+
+ if (v.get() < 0) {
+ return http::BadRequest("Invalid level '" + stringify(v.get()) + "'.\n");
+ } else if (v.get() < original) {
+ return http::BadRequest("'" + stringify(v.get()) + "' < original level.\n");
+ }
+
+ Try<Duration> d = Duration::parse(duration.get());
+
+ if (d.isError()) {
+ return http::BadRequest(d.error() + ".\n");
+ }
+
+ // Set the logging level.
+ set(v.get());
+
+ // Start a revert timer (if necessary).
+ if (v.get() != original) {
+ timeout = d.get();
+ delay(timeout.remaining(), this, &This::revert);
+ }
+
+ return http::OK();
+ }
+
+ void set(int v)
+ {
+ if (FLAGS_v != v) {
+ VLOG(FLAGS_v) << "Setting verbose logging level to " << v;
+ FLAGS_v = v;
+ __sync_synchronize(); // Ensure 'FLAGS_v' visible in other threads.
+ }
+ }
+
+ void revert()
+ {
+ if (timeout.remaining() == Seconds(0)) {
+ set(original);
+ }
+ }
+
+ Timeout timeout;
+
+ const int32_t original; // Original value of FLAGS_v.
+};
+
+} // namespace process {
+
+#endif // __PROCESS_LOGGING_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1f145338/third_party/libprocess/src/process.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/process.cpp b/third_party/libprocess/src/process.cpp
index 56f1ec5..86414e5 100644
--- a/third_party/libprocess/src/process.cpp
+++ b/third_party/libprocess/src/process.cpp
@@ -55,6 +55,7 @@
#include <process/gc.hpp>
#include <process/id.hpp>
#include <process/io.hpp>
+#include <process/logging.hpp>
#include <process/mime.hpp>
#include <process/process.hpp>
#include <process/profiler.hpp>
@@ -1392,10 +1393,17 @@ void initialize(const string& delegate)
// 'spawn' below for the garbage collector.
initializing = false;
- // Create global garbage collector.
+ // TODO(benh): Make sure creating the garbage collector, logging
+ // process, and profiler always succeeds and use supervisors to make
+ // sure that none terminate.
+
+ // Create global garbage collector process.
gc = spawn(new GarbageCollector());
- // Create the global profiler.
+ // Create the global logging process.
+ spawn(new Logging(), true);
+
+ // Create the global profiler process.
spawn(new Profiler(), true);
// Create the global statistics.
[27/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/delay.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/delay.hpp b/3rdparty/libprocess/include/process/delay.hpp
new file mode 100644
index 0000000..97acd76
--- /dev/null
+++ b/3rdparty/libprocess/include/process/delay.hpp
@@ -0,0 +1,119 @@
+#ifndef __PROCESS_DELAY_HPP__
+#define __PROCESS_DELAY_HPP__
+
+#include <tr1/functional>
+
+#include <process/dispatch.hpp>
+#include <process/timer.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/preprocessor.hpp>
+
+namespace process {
+
+// The 'delay' mechanism enables you to delay a dispatch to a process
+// for some specified number of seconds. Returns a Timer instance that
+// can be cancelled (but it might have already executed or be
+// executing concurrently).
+
+template <typename T>
+Timer delay(const Duration& duration,
+ const PID<T>& pid,
+ void (T::*method)())
+{
+ std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(
+ new std::tr1::function<void(T*)>(
+ std::tr1::bind(method, std::tr1::placeholders::_1)));
+
+ std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
+ new std::tr1::function<void(ProcessBase*)>(
+ std::tr1::bind(&internal::vdispatcher<T>,
+ std::tr1::placeholders::_1,
+ thunk)));
+
+ std::tr1::function<void(void)> dispatch =
+ std::tr1::bind(internal::dispatch,
+ pid,
+ dispatcher,
+ internal::canonicalize(method));
+
+ return Timer::create(duration, dispatch);
+}
+
+
+template <typename T>
+Timer delay(const Duration& duration,
+ const Process<T>& process,
+ void (T::*method)())
+{
+ return delay(duration, process.self(), method);
+}
+
+
+template <typename T>
+Timer delay(const Duration& duration,
+ const Process<T>* process,
+ void (T::*method)())
+{
+ return delay(duration, process->self(), method);
+}
+
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Timer delay(const Duration& duration, \
+ const PID<T>& pid, \
+ void (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk( \
+ new std::tr1::function<void(T*)>( \
+ std::tr1::bind(method, \
+ std::tr1::placeholders::_1, \
+ ENUM_PARAMS(N, a)))); \
+ \
+ std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher( \
+ new std::tr1::function<void(ProcessBase*)>( \
+ std::tr1::bind(&internal::vdispatcher<T>, \
+ std::tr1::placeholders::_1, \
+ thunk))); \
+ \
+ std::tr1::function<void(void)> dispatch = \
+ std::tr1::bind(internal::dispatch, \
+ pid, \
+ dispatcher, \
+ internal::canonicalize(method)); \
+ \
+ return Timer::create(duration, dispatch); \
+ } \
+ \
+ template <typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Timer delay(const Duration& duration, \
+ const Process<T>& process, \
+ void (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ return delay(duration, process.self(), method, ENUM_PARAMS(N, a)); \
+ } \
+ \
+ template <typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Timer delay(const Duration& duration, \
+ const Process<T>* process, \
+ void (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ return delay(duration, process->self(), method, ENUM_PARAMS(N, a)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+} // namespace process {
+
+#endif // __PROCESS_DELAY_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/dispatch.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/dispatch.hpp b/3rdparty/libprocess/include/process/dispatch.hpp
new file mode 100644
index 0000000..b337a87
--- /dev/null
+++ b/3rdparty/libprocess/include/process/dispatch.hpp
@@ -0,0 +1,478 @@
+#ifndef __PROCESS_DISPATCH_HPP__
+#define __PROCESS_DISPATCH_HPP__
+
+#include <string>
+
+#include <tr1/functional>
+#include <tr1/memory> // TODO(benh): Replace all shared_ptr with unique_ptr.
+
+#include <process/process.hpp>
+
+#include <stout/preprocessor.hpp>
+
+namespace process {
+
+// The dispatch mechanism enables you to "schedule" a method to get
+// invoked on a process. The result of that method invocation is
+// accessible via the future that is returned by the dispatch method
+// (note, however, that it might not be the _same_ future as the one
+// returned from the method, if the method even returns a future, see
+// below). Assuming some class 'Fibonacci' has a (visible) method
+// named 'compute' that takes an integer, N (and returns the Nth
+// fibonacci number) you might use dispatch like so:
+//
+// PID<Fibonacci> pid = spawn(new Fibonacci(), true); // Use the GC.
+// Future<int> f = dispatch(pid, &Fibonacci::compute, 10);
+//
+// Because the pid argument is "typed" we can ensure that methods are
+// only invoked on processes that are actually of that type. Providing
+// this mechanism for varying numbers of function types and arguments
+// requires support for variadic templates, slated to be released in
+// C++11. Until then, we use the Boost preprocessor macros to
+// accomplish the same thing (all be it less cleanly). See below for
+// those definitions.
+//
+// Dispatching is done via a level of indirection. The dispatch
+// routine itself creates a promise that is passed as an argument to a
+// partially applied 'dispatcher' function (defined below). The
+// dispatcher routines get passed to the actual process via an
+// internal routine called, not suprisingly, 'dispatch', defined
+// below:
+
+namespace internal {
+
+// The internal dispatch routine schedules a function to get invoked
+// within the context of the process associated with the specified pid
+// (first argument), unless that process is no longer valid. Note that
+// this routine does not expect anything in particular about the
+// specified function (second argument). The semantics are simple: the
+// function gets applied/invoked with the process as its first
+// argument. Currently we wrap the function in a shared_ptr but this
+// will probably change in the future to unique_ptr (or a variant).
+void dispatch(
+ const UPID& pid,
+ const std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> >& f,
+ const std::string& method = std::string());
+
+// For each return type (void, future, value) there is a dispatcher
+// function which should complete the picture. Given the process
+// argument these routines downcast the process to the correct subtype
+// and invoke the thunk using the subtype as the argument
+// (receiver). Note that we must use dynamic_cast because we permit a
+// process to use multiple inheritance (e.g., to expose multiple
+// callback interfaces).
+
+template <typename T>
+void vdispatcher(
+ ProcessBase* process,
+ std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk)
+{
+ assert(process != NULL);
+ T* t = dynamic_cast<T*>(process);
+ assert(t != NULL);
+ (*thunk)(t);
+}
+
+
+template <typename R, typename T>
+void pdispatcher(
+ ProcessBase* process,
+ std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk,
+ std::tr1::shared_ptr<Promise<R> > promise)
+{
+ assert(process != NULL);
+ T* t = dynamic_cast<T*>(process);
+ assert(t != NULL);
+ promise->associate((*thunk)(t));
+}
+
+
+template <typename R, typename T>
+void rdispatcher(
+ ProcessBase* process,
+ std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk,
+ std::tr1::shared_ptr<Promise<R> > promise)
+{
+ assert(process != NULL);
+ T* t = dynamic_cast<T*>(process);
+ assert(t != NULL);
+ promise->set((*thunk)(t));
+}
+
+
+// Canonicalizes a pointer to a member function (i.e., method) into a
+// bytes representation for comparison (e.g., in tests).
+template <typename Method>
+std::string canonicalize(Method method)
+{
+ return std::string(reinterpret_cast<const char*>(&method), sizeof(method));
+}
+
+} // namespace internal {
+
+
+// Okay, now for the definition of the dispatch routines
+// themselves. For each routine we provide the version in C++11 using
+// variadic templates so the reader can see what the Boost
+// preprocessor macros are effectively providing. Using C++11 closures
+// would shorten these definitions even more.
+//
+// First, definitions of dispatch for methods returning void:
+//
+// template <typename T, typename ...P>
+// void dispatch(
+// const PID<T>& pid,
+// void (T::*method)(P...),
+// P... p)
+// {
+// std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(
+// new std::tr1::function<void(T*)>(
+// std::tr1::bind(method,
+// std::tr1::placeholders::_1,
+// std::forward<P>(p)...)));
+//
+// std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
+// new std::tr1::function<void(ProcessBase*)>(
+// std::tr1::bind(&internal::vdispatcher<T>,
+// std::tr1::placeholders::_1,
+// thunk)));
+//
+// internal::dispatch(pid, dispatcher, internal::canonicalize(method));
+// }
+
+template <typename T>
+void dispatch(
+ const PID<T>& pid,
+ void (T::*method)(void))
+{
+ std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(
+ new std::tr1::function<void(T*)>(
+ std::tr1::bind(method, std::tr1::placeholders::_1)));
+
+ std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
+ new std::tr1::function<void(ProcessBase*)>(
+ std::tr1::bind(&internal::vdispatcher<T>,
+ std::tr1::placeholders::_1,
+ thunk)));
+
+ internal::dispatch(pid, dispatcher, internal::canonicalize(method));
+}
+
+template <typename T>
+void dispatch(
+ const Process<T>& process,
+ void (T::*method)(void))
+{
+ dispatch(process.self(), method);
+}
+
+template <typename T>
+void dispatch(
+ const Process<T>* process,
+ void (T::*method)(void))
+{
+ dispatch(process->self(), method);
+}
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ void dispatch( \
+ const PID<T>& pid, \
+ void (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk( \
+ new std::tr1::function<void(T*)>( \
+ std::tr1::bind(method, \
+ std::tr1::placeholders::_1, \
+ ENUM_PARAMS(N, a)))); \
+ \
+ std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher( \
+ new std::tr1::function<void(ProcessBase*)>( \
+ std::tr1::bind(&internal::vdispatcher<T>, \
+ std::tr1::placeholders::_1, \
+ thunk))); \
+ \
+ internal::dispatch(pid, dispatcher, internal::canonicalize(method)); \
+ } \
+ \
+ template <typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ void dispatch( \
+ const Process<T>& process, \
+ void (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ dispatch(process.self(), method, ENUM_PARAMS(N, a)); \
+ } \
+ \
+ template <typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ void dispatch( \
+ const Process<T>* process, \
+ void (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ dispatch(process->self(), method, ENUM_PARAMS(N, a)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+
+// Next, definitions of methods returning a future:
+//
+// template <typename R, typename T, typename ...P>
+// Future<R> dispatch(
+// const PID<T>& pid,
+// Future<R> (T::*method)(P...),
+// P... p)
+// {
+// std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk(
+// new std::tr1::function<Future<R>(T*)>(
+// std::tr1::bind(method,
+// std::tr1::placeholders::_1,
+// std::forward<P>(p)...)));
+//
+// std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+// Future<R> future = promise->future();
+//
+// std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
+// new std::tr1::function<void(ProcessBase*)>(
+// std::tr1::bind(&internal::pdispatcher<R, T>,
+// std::tr1::placeholders::_1,
+// thunk, promise)));
+//
+// internal::dispatch(pid, dispatcher, internal::canonicalize(method));
+//
+// return future;
+// }
+
+template <typename R, typename T>
+Future<R> dispatch(
+ const PID<T>& pid,
+ Future<R> (T::*method)(void))
+{
+ std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk(
+ new std::tr1::function<Future<R>(T*)>(
+ std::tr1::bind(method, std::tr1::placeholders::_1)));
+
+ std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+ Future<R> future = promise->future();
+
+ std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
+ new std::tr1::function<void(ProcessBase*)>(
+ std::tr1::bind(&internal::pdispatcher<R, T>,
+ std::tr1::placeholders::_1,
+ thunk, promise)));
+
+ internal::dispatch(pid, dispatcher, internal::canonicalize(method));
+
+ return future;
+}
+
+template <typename R, typename T>
+Future<R> dispatch(
+ const Process<T>& process,
+ Future<R> (T::*method)(void))
+{
+ return dispatch(process.self(), method);
+}
+
+template <typename R, typename T>
+Future<R> dispatch(
+ const Process<T>* process,
+ Future<R> (T::*method)(void))
+{
+ return dispatch(process->self(), method);
+}
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename R, \
+ typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<R> dispatch( \
+ const PID<T>& pid, \
+ Future<R> (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk( \
+ new std::tr1::function<Future<R>(T*)>( \
+ std::tr1::bind(method, \
+ std::tr1::placeholders::_1, \
+ ENUM_PARAMS(N, a)))); \
+ \
+ std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>()); \
+ Future<R> future = promise->future(); \
+ \
+ std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher( \
+ new std::tr1::function<void(ProcessBase*)>( \
+ std::tr1::bind(&internal::pdispatcher<R, T>, \
+ std::tr1::placeholders::_1, \
+ thunk, promise))); \
+ \
+ internal::dispatch(pid, dispatcher, internal::canonicalize(method)); \
+ \
+ return future; \
+ } \
+ \
+ template <typename R, \
+ typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<R> dispatch( \
+ const Process<T>& process, \
+ Future<R> (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ return dispatch(process.self(), method, ENUM_PARAMS(N, a)); \
+ } \
+ \
+ template <typename R, \
+ typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<R> dispatch( \
+ const Process<T>* process, \
+ Future<R> (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ return dispatch(process->self(), method, ENUM_PARAMS(N, a)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+
+// Next, definitions of methods returning a value.
+//
+// template <typename R, typename T, typename ...P>
+// Future<R> dispatch(
+// const PID<T>& pid,
+// R (T::*method)(P...),
+// P... p)
+// {
+// std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk(
+// new std::tr1::function<R(T*)>(
+// std::tr1::bind(method,
+// std::tr1::placeholders::_1,
+// std::forward<P>(p)...)));
+//
+// std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+// Future<R> future = promise->future();
+//
+// std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
+// new std::tr1::function<void(ProcessBase*)>(
+// std::tr1::bind(&internal::rdispatcher<R, T>,
+// std::tr1::placeholders::_1,
+// thunk, promise)));
+//
+// internal::dispatch(pid, dispatcher, internal::canonicalize(method));
+//
+// return future;
+// }
+
+template <typename R, typename T>
+Future<R> dispatch(
+ const PID<T>& pid,
+ R (T::*method)(void))
+{
+ std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk(
+ new std::tr1::function<R(T*)>(
+ std::tr1::bind(method, std::tr1::placeholders::_1)));
+
+ std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+ Future<R> future = promise->future();
+
+ std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
+ new std::tr1::function<void(ProcessBase*)>(
+ std::tr1::bind(&internal::rdispatcher<R, T>,
+ std::tr1::placeholders::_1,
+ thunk, promise)));
+
+ internal::dispatch(pid, dispatcher, internal::canonicalize(method));
+
+ return future;
+}
+
+template <typename R, typename T>
+Future<R> dispatch(
+ const Process<T>& process,
+ R (T::*method)(void))
+{
+ return dispatch(process.self(), method);
+}
+
+template <typename R, typename T>
+Future<R> dispatch(
+ const Process<T>* process,
+ R (T::*method)(void))
+{
+ return dispatch(process->self(), method);
+}
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename R, \
+ typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<R> dispatch( \
+ const PID<T>& pid, \
+ R (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk( \
+ new std::tr1::function<R(T*)>( \
+ std::tr1::bind(method, \
+ std::tr1::placeholders::_1, \
+ ENUM_PARAMS(N, a)))); \
+ \
+ std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>()); \
+ Future<R> future = promise->future(); \
+ \
+ std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher( \
+ new std::tr1::function<void(ProcessBase*)>( \
+ std::tr1::bind(&internal::rdispatcher<R, T>, \
+ std::tr1::placeholders::_1, \
+ thunk, promise))); \
+ \
+ internal::dispatch(pid, dispatcher, internal::canonicalize(method)); \
+ \
+ return future; \
+ } \
+ \
+ template <typename R, \
+ typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<R> dispatch( \
+ const Process<T>& process, \
+ R (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ return dispatch(process.self(), method, ENUM_PARAMS(N, a)); \
+ } \
+ \
+ template <typename R, \
+ typename T, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<R> dispatch( \
+ const Process<T>* process, \
+ R (T::*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ return dispatch(process->self(), method, ENUM_PARAMS(N, a)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+} // namespace process {
+
+#endif // __PROCESS_DISPATCH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/event.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/event.hpp b/3rdparty/libprocess/include/process/event.hpp
new file mode 100644
index 0000000..84a8790
--- /dev/null
+++ b/3rdparty/libprocess/include/process/event.hpp
@@ -0,0 +1,199 @@
+#ifndef __PROCESS_EVENT_HPP__
+#define __PROCESS_EVENT_HPP__
+
+#include <tr1/functional>
+#include <tr1/memory> // TODO(benh): Replace all shared_ptr with unique_ptr.
+
+#include <process/future.hpp>
+#include <process/http.hpp>
+#include <process/message.hpp>
+#include <process/socket.hpp>
+
+namespace process {
+
+// Forward declarations.
+struct ProcessBase;
+struct MessageEvent;
+struct DispatchEvent;
+struct HttpEvent;
+struct ExitedEvent;
+struct TerminateEvent;
+
+
+struct EventVisitor
+{
+ virtual ~EventVisitor() {}
+ virtual void visit(const MessageEvent& event) {}
+ virtual void visit(const DispatchEvent& event) {}
+ virtual void visit(const HttpEvent& event) {}
+ virtual void visit(const ExitedEvent& event) {}
+ virtual void visit(const TerminateEvent& event) {}
+};
+
+
+struct Event
+{
+ virtual ~Event() {}
+
+ virtual void visit(EventVisitor* visitor) const = 0;
+
+ template <typename T>
+ bool is() const
+ {
+ bool result = false;
+ struct IsVisitor : EventVisitor
+ {
+ IsVisitor(bool* _result) : result(_result) {}
+ virtual void visit(const T& t) { *result = true; }
+ bool* result;
+ } visitor(&result);
+ visit(&visitor);
+ return result;
+ }
+
+ template <typename T>
+ const T& as() const
+ {
+ const T* result = NULL;
+ struct AsVisitor : EventVisitor
+ {
+ AsVisitor(const T** _result) : result(_result) {}
+ virtual void visit(const T& t) { *result = &t; }
+ const T** result;
+ } visitor(&result);
+ visit(&visitor);
+ if (result == NULL) {
+ std::cerr << "Attempting to \"cast\" event incorrectly!" << std::endl;
+ abort();
+ }
+ return *result;
+ }
+};
+
+
+struct MessageEvent : Event
+{
+ MessageEvent(Message* _message)
+ : message(_message) {}
+
+ virtual ~MessageEvent()
+ {
+ delete message;
+ }
+
+ virtual void visit(EventVisitor* visitor) const
+ {
+ visitor->visit(*this);
+ }
+
+ Message* const message;
+
+private:
+ // Not copyable, not assignable.
+ MessageEvent(const MessageEvent&);
+ MessageEvent& operator = (const MessageEvent&);
+};
+
+
+struct HttpEvent : Event
+{
+ HttpEvent(const Socket& _socket, http::Request* _request)
+ : socket(_socket), request(_request) {}
+
+ virtual ~HttpEvent()
+ {
+ delete request;
+ }
+
+ virtual void visit(EventVisitor* visitor) const
+ {
+ visitor->visit(*this);
+ }
+
+ const Socket socket;
+ http::Request* const request;
+
+private:
+ // Not copyable, not assignable.
+ HttpEvent(const HttpEvent&);
+ HttpEvent& operator = (const HttpEvent&);
+};
+
+
+struct DispatchEvent : Event
+{
+ DispatchEvent(
+ const UPID& _pid,
+ const std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> >& _f,
+ const std::string& _method)
+ : pid(_pid),
+ f(_f),
+ method(_method)
+ {}
+
+ virtual void visit(EventVisitor* visitor) const
+ {
+ visitor->visit(*this);
+ }
+
+ // PID receiving the dispatch.
+ const UPID pid;
+
+ // Function to get invoked as a result of this dispatch event.
+ const std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > f;
+
+ // Canonical "byte" representation of a pointer to a member function
+ // (i.e., method) encapsulated in the above function (or empty if
+ // not applicable). Note that we use a byte representation because a
+ // pointer to a member function is not actually a pointer, but
+ // instead a POD.
+ // TODO(benh): Perform canonicalization lazily.
+ const std::string method;
+
+private:
+ // Not copyable, not assignable.
+ DispatchEvent(const DispatchEvent&);
+ DispatchEvent& operator = (const DispatchEvent&);
+};
+
+
+struct ExitedEvent : Event
+{
+ ExitedEvent(const UPID& _pid)
+ : pid(_pid) {}
+
+ virtual void visit(EventVisitor* visitor) const
+ {
+ visitor->visit(*this);
+ }
+
+ const UPID pid;
+
+private:
+ // Not copyable, not assignable.
+ ExitedEvent(const ExitedEvent&);
+ ExitedEvent& operator = (const ExitedEvent&);
+};
+
+
+struct TerminateEvent : Event
+{
+ TerminateEvent(const UPID& _from)
+ : from(_from) {}
+
+ virtual void visit(EventVisitor* visitor) const
+ {
+ visitor->visit(*this);
+ }
+
+ const UPID from;
+
+private:
+ // Not copyable, not assignable.
+ TerminateEvent(const TerminateEvent&);
+ TerminateEvent& operator = (const TerminateEvent&);
+};
+
+} // namespace event {
+
+#endif // __PROCESS_EVENT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/executor.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/executor.hpp b/3rdparty/libprocess/include/process/executor.hpp
new file mode 100644
index 0000000..72fb2f1
--- /dev/null
+++ b/3rdparty/libprocess/include/process/executor.hpp
@@ -0,0 +1,260 @@
+#ifndef __PROCESS_EXECUTOR_HPP__
+#define __PROCESS_EXECUTOR_HPP__
+
+#include <process/deferred.hpp>
+#include <process/dispatch.hpp>
+#include <process/id.hpp>
+#include <process/thread.hpp>
+
+#include <stout/preprocessor.hpp>
+
+namespace process {
+
+// Underlying "process" which handles invoking actual callbacks
+// created through an Executor.
+class ExecutorProcess : public Process<ExecutorProcess>
+{
+private:
+ friend class Executor;
+
+ ExecutorProcess() : ProcessBase(ID::generate("__executor__")) {}
+ virtual ~ExecutorProcess() {}
+
+ // Not copyable, not assignable.
+ ExecutorProcess(const ExecutorProcess&);
+ ExecutorProcess& operator = (const ExecutorProcess&);
+
+ // No arg invoke.
+ void invoke(const std::tr1::function<void(void)>& f) { f(); }
+
+ // Args invoke.
+#define TEMPLATE(Z, N, DATA) \
+ template <ENUM_PARAMS(N, typename A)> \
+ void CAT(invoke, N)( \
+ const std::tr1::function<void(ENUM_PARAMS(N, A))>& f, \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ f(ENUM_PARAMS(N, a)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+};
+
+
+// Provides an abstraction that can take a standard function object
+// and convert it to a 'Deferred'. Each converted function object will
+// get invoked serially with respect to one another.
+class Executor
+{
+public:
+ Executor()
+ {
+ spawn(process);
+ }
+
+ ~Executor()
+ {
+ terminate(process);
+ wait(process);
+ }
+
+ void stop()
+ {
+ terminate(process);
+
+ // TODO(benh): Note that this doesn't wait because that could
+ // cause a deadlock ... thus, the semantics here are that no more
+ // dispatches will occur after this function returns but one may
+ // be occuring concurrently.
+ }
+
+ // 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.
+private:
+#define TEMPLATE(Z, N, DATA) \
+ typedef std::tr1::_Placeholder<INC(N)> _ ## N;
+
+ REPEAT(10, TEMPLATE, _)
+#undef TEMPLATE
+
+public:
+ // We provide wrappers for all standard function objects.
+ Deferred<void(void)> defer(
+ const std::tr1::function<void(void)>& f)
+ {
+ return Deferred<void(void)>(
+ std::tr1::bind(
+ &Executor::dispatcher,
+ process.self(), 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) \
+ { \
+ return Deferred<void(ENUM_PARAMS(N, A))>( \
+ std::tr1::bind( \
+ &Executor::CAT(dispatcher, N)<ENUM_PARAMS(N, A)>, \
+ process.self(), f, \
+ ENUM_BINARY_PARAMS(N, _, () INTERCEPT))); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+ // Unfortunately, it is currently difficult to "forward" type
+ // information from one result to another, so we must explicilty
+ // define wrappers for all std::tr1::bind results. First we start
+ // with the non-member std::tr1::bind results.
+ Deferred<void(void)> defer(
+ const std::tr1::_Bind<void(*(void))(void)>& b)
+ {
+ return defer(std::tr1::function<void(void)>(b));
+ }
+
+#define TEMPLATE(Z, N, DATA) \
+ template <ENUM_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind< \
+ void(*(ENUM_PARAMS(N, _))) \
+ (ENUM_PARAMS(N, A))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+ // Now the member std::tr1::bind results:
+ // 1. Non-const member (function), non-const pointer (receiver).
+ // 2. Const member, non-const pointer.
+ // 3. Const member, const pointer.
+ // 4. Non-const member, non-const reference.
+ // 5. Const member, non-const reference.
+ // 6. Const member, const reference.
+ // 7. Non-const member, value.
+ // 8. Const member, value.
+#define TEMPLATE(Z, N, DATA) \
+ template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind<std::tr1::_Mem_fn< \
+ void(T::*)(ENUM_PARAMS(N, A))> \
+ (T* ENUM_TRAILING_PARAMS(N, _))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ } \
+ \
+ template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind<std::tr1::_Mem_fn< \
+ void(T::*)(ENUM_PARAMS(N, A)) const> \
+ (T* ENUM_TRAILING_PARAMS(N, _))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ } \
+ \
+ template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind<std::tr1::_Mem_fn< \
+ void(T::*)(ENUM_PARAMS(N, A)) const> \
+ (const T* ENUM_TRAILING_PARAMS(N, _))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ } \
+ \
+ template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind<std::tr1::_Mem_fn< \
+ void(T::*)(ENUM_PARAMS(N, A))> \
+ (std::tr1::reference_wrapper<T> ENUM_TRAILING_PARAMS(N, _))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ } \
+ \
+ template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind<std::tr1::_Mem_fn< \
+ void(T::*)(ENUM_PARAMS(N, A)) const> \
+ (std::tr1::reference_wrapper<T> ENUM_TRAILING_PARAMS(N, _))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ } \
+ \
+ template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind<std::tr1::_Mem_fn< \
+ void(T::*)(ENUM_PARAMS(N, A)) const> \
+ (std::tr1::reference_wrapper<const T> ENUM_TRAILING_PARAMS(N, _))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ } \
+ \
+ template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind<std::tr1::_Mem_fn< \
+ void(T::*)(ENUM_PARAMS(N, A))> \
+ (T ENUM_TRAILING_PARAMS(N, _))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ } \
+ \
+ template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
+ Deferred<void(ENUM_PARAMS(N, A))> defer( \
+ const std::tr1::_Bind<std::tr1::_Mem_fn< \
+ void(T::*)(ENUM_PARAMS(N, A)) const> \
+ (T ENUM_TRAILING_PARAMS(N, _))>& b) \
+ { \
+ return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
+ }
+
+ REPEAT(11, TEMPLATE, _) // No args and args A0 -> A9.
+#undef TEMPLATE
+
+private:
+ // Not copyable, not assignable.
+ Executor(const Executor&);
+ Executor& operator = (const Executor&);
+
+ static void dispatcher(
+ const PID<ExecutorProcess>& pid,
+ const std::tr1::function<void(void)>& f)
+ {
+ // TODO(benh): Why not just use internal::dispatch?
+ dispatch(pid, &ExecutorProcess::invoke, f);
+ }
+
+#define TEMPLATE(Z, N, DATA) \
+ template <ENUM_PARAMS(N, typename A)> \
+ static void CAT(dispatcher, N)( \
+ const PID<ExecutorProcess>& pid, \
+ const std::tr1::function<void(ENUM_PARAMS(N, A))>& f, \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ dispatch( \
+ pid, \
+ &ExecutorProcess::CAT(invoke, N)<ENUM_PARAMS(N, A)>, \
+ f, ENUM_PARAMS(N, a)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+ ExecutorProcess process;
+};
+
+
+// Per thread executor pointer. The extra level of indirection from
+// _executor_ to __executor__ is used in order to take advantage of
+// the ThreadLocal operators without needing the extra dereference as
+// well as lazily construct the actual executor.
+extern ThreadLocal<Executor>* _executor_;
+
+#define __executor__ \
+ (*_executor_ == NULL ? *_executor_ = new Executor() : *_executor_)
+
+} // namespace process {
+
+#endif // __PROCESS_EXECUTOR_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/filter.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/filter.hpp b/3rdparty/libprocess/include/process/filter.hpp
new file mode 100644
index 0000000..aa0c91b
--- /dev/null
+++ b/3rdparty/libprocess/include/process/filter.hpp
@@ -0,0 +1,24 @@
+#ifndef __PROCESS_FILTER_HPP__
+#define __PROCESS_FILTER_HPP__
+
+#include <process/event.hpp>
+
+namespace process {
+
+class Filter {
+public:
+ virtual ~Filter() {}
+ virtual bool filter(const MessageEvent& event) { return false; }
+ virtual bool filter(const DispatchEvent& event) { return false; }
+ virtual bool filter(const HttpEvent& event) { return false; }
+ virtual bool filter(const ExitedEvent& event) { return false; }
+};
+
+
+// Use the specified filter on messages that get enqueued (note,
+// however, that you cannot filter timeout messages).
+void filter(Filter* filter);
+
+} // namespace process {
+
+#endif // __PROCESS_FILTER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/future.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/future.hpp b/3rdparty/libprocess/include/process/future.hpp
new file mode 100644
index 0000000..daf4b92
--- /dev/null
+++ b/3rdparty/libprocess/include/process/future.hpp
@@ -0,0 +1,1060 @@
+#ifndef __PROCESS_FUTURE_HPP__
+#define __PROCESS_FUTURE_HPP__
+
+#include <assert.h>
+#include <stdlib.h> // For abort.
+
+#include <iostream>
+#include <list>
+#include <queue>
+#include <set>
+
+#include <glog/logging.h>
+
+#include <tr1/functional>
+#include <tr1/memory> // TODO(benh): Replace shared_ptr with unique_ptr.
+
+#include <process/latch.hpp>
+#include <process/pid.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/option.hpp>
+#include <stout/preprocessor.hpp>
+
+namespace process {
+
+// Forward declaration (instead of include to break circular dependency).
+template <typename _F> struct _Defer;
+
+namespace internal {
+
+template <typename T>
+struct wrap;
+
+template <typename T>
+struct unwrap;
+
+} // namespace internal {
+
+
+// Forward declaration of Promise.
+template <typename T>
+class Promise;
+
+
+// Definition of a "shared" future. A future can hold any
+// copy-constructible value. A future is considered "shared" because
+// by default a future can be accessed concurrently.
+template <typename T>
+class Future
+{
+public:
+ // Constructs a failed future.
+ static Future<T> failed(const std::string& message);
+
+ Future();
+ Future(const T& _t);
+ Future(const Future<T>& that);
+ ~Future();
+
+ // Futures are assignable (and copyable). This results in the
+ // reference to the previous future data being decremented and a
+ // reference to 'that' being incremented.
+ Future<T>& operator = (const Future<T>& that);
+
+ // Comparision operators useful for using futures in collections.
+ bool operator == (const Future<T>& that) const;
+ bool operator < (const Future<T>& that) const;
+
+ // Helpers to get the current state of this future.
+ bool isPending() const;
+ bool isReady() const;
+ bool isDiscarded() const;
+ bool isFailed() const;
+
+ // Discards this future. This is similar to cancelling a future,
+ // however it also occurs when the last reference to this future
+ // gets cleaned up. Returns false if the future could not be
+ // discarded (for example, because it is ready or failed).
+ bool discard();
+
+ // Waits for this future to become ready, discarded, or failed.
+ bool await(const Duration& duration = Seconds(-1)) const;
+
+ // Return the value associated with this future, waits indefinitely
+ // until a value gets associated or until the future is discarded.
+ T get() const;
+
+ // Returns the failure message associated with this future.
+ std::string failure() const;
+
+ // Type of the callback functions that can get invoked when the
+ // future gets set, fails, or is discarded.
+ typedef std::tr1::function<void(const T&)> ReadyCallback;
+ typedef std::tr1::function<void(const std::string&)> FailedCallback;
+ typedef std::tr1::function<void(void)> DiscardedCallback;
+ typedef std::tr1::function<void(const Future<T>&)> AnyCallback;
+
+ // Installs callbacks for the specified events and returns a const
+ // reference to 'this' in order to easily support chaining.
+ const Future<T>& onReady(const ReadyCallback& callback) const;
+ const Future<T>& onFailed(const FailedCallback& callback) const;
+ const Future<T>& onDiscarded(const DiscardedCallback& callback) const;
+ const Future<T>& onAny(const AnyCallback& callback) const;
+
+ // Installs callbacks that get executed when this future is ready
+ // and associates the result of the callback with the future that is
+ // returned to the caller (which may be of a different type).
+ template <typename X>
+ Future<X> then(const std::tr1::function<Future<X>(const T&)>& f) const;
+
+ template <typename X>
+ Future<X> then(const std::tr1::function<X(const T&)>& f) const;
+
+ // Helpers for the compiler to be able to forward std::tr1::bind results.
+ template <typename X>
+ Future<X> then(const std::tr1::_Bind<X(*(void))(void)>& b) const
+ {
+ return then(std::tr1::function<X(const T&)>(b));
+ }
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename X, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<X> then( \
+ const std::tr1::_Bind<X(*(ENUM_PARAMS(N, A))) \
+ (ENUM_PARAMS(N, P))>& b) const \
+ { \
+ return then(std::tr1::function<X(const T&)>(b)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+ template <typename X>
+ Future<X> then(const std::tr1::_Bind<Future<X>(*(void))(void)>& b) const
+ {
+ return then(std::tr1::function<Future<X>(const T&)>(b));
+ }
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename X, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<X> then( \
+ const std::tr1::_Bind<Future<X>(*(ENUM_PARAMS(N, A))) \
+ (ENUM_PARAMS(N, P))>& b) const \
+ { \
+ return then(std::tr1::function<Future<X>(const T&)>(b)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+ // Helpers for the compiler to be able to forward 'defer' results.
+ template <typename X, typename U>
+ Future<X> then(const _Defer<Future<X>(*(PID<U>, X(U::*)(void)))
+ (const PID<U>&, X(U::*)(void))>& d) const
+ {
+ return then(std::tr1::function<Future<X>(const T&)>(d));
+ }
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename X, \
+ typename U, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<X> then( \
+ const _Defer<Future<X>(*(PID<U>, \
+ X(U::*)(ENUM_PARAMS(N, P)), \
+ ENUM_PARAMS(N, A))) \
+ (const PID<U>&, \
+ X(U::*)(ENUM_PARAMS(N, P)), \
+ ENUM_PARAMS(N, P))>& d) const \
+ { \
+ return then(std::tr1::function<Future<X>(const T&)>(d)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+ template <typename X, typename U>
+ Future<X> then(const _Defer<Future<X>(*(PID<U>, Future<X>(U::*)(void)))
+ (const PID<U>&, Future<X>(U::*)(void))>& d) const
+ {
+ return then(std::tr1::function<Future<X>(const T&)>(d));
+ }
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename X, \
+ typename U, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<X> then( \
+ const _Defer<Future<X>(*(PID<U>, \
+ Future<X>(U::*)(ENUM_PARAMS(N, P)), \
+ ENUM_PARAMS(N, A))) \
+ (const PID<U>&, \
+ Future<X>(U::*)(ENUM_PARAMS(N, P)), \
+ ENUM_PARAMS(N, P))>& d) const \
+ { \
+ return then(std::tr1::function<Future<X>(const T&)>(d)); \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+ // C++11 implementation (covers all functors).
+#if __cplusplus >= 201103L
+ template <typename F>
+ auto then(F f) const
+ -> typename internal::wrap<decltype(f(T()))>::Type;
+#endif
+
+private:
+ friend class Promise<T>;
+
+ // Sets the value for this future, unless the future is already set,
+ // failed, or discarded, in which case it returns false.
+ bool set(const T& _t);
+
+ // Sets this future as failed, unless the future is already set,
+ // failed, or discarded, in which case it returns false.
+ bool fail(const std::string& _message);
+
+ void copy(const Future<T>& that);
+ void cleanup();
+
+ enum State {
+ PENDING,
+ READY,
+ FAILED,
+ DISCARDED,
+ };
+
+ int* refs;
+ int* lock;
+ State* state;
+ T** t;
+ std::string** message; // Message associated with failure.
+ std::queue<ReadyCallback>* onReadyCallbacks;
+ std::queue<FailedCallback>* onFailedCallbacks;
+ std::queue<DiscardedCallback>* onDiscardedCallbacks;
+ std::queue<AnyCallback>* onAnyCallbacks;
+ Latch* latch;
+};
+
+
+// TODO(benh): Make Promise a subclass of Future?
+template <typename T>
+class Promise
+{
+public:
+ Promise();
+ Promise(const T& t);
+ ~Promise();
+
+ bool set(const T& _t);
+ bool set(const Future<T>& future); // Alias for associate.
+ bool associate(const Future<T>& future);
+ bool fail(const std::string& message);
+
+ // Returns a copy of the future associated with this promise.
+ Future<T> future() const;
+
+private:
+ // Not copyable, not assignable.
+ Promise(const Promise<T>&);
+ Promise<T>& operator = (const Promise<T>&);
+
+ Future<T> f;
+};
+
+
+template <>
+class Promise<void>;
+
+
+template <typename T>
+class Promise<T&>;
+
+
+template <typename T>
+Promise<T>::Promise() {}
+
+
+template <typename T>
+Promise<T>::Promise(const T& t)
+ : f(t) {}
+
+
+template <typename T>
+Promise<T>::~Promise() {}
+
+
+template <typename T>
+bool Promise<T>::set(const T& t)
+{
+ return f.set(t);
+}
+
+
+template <typename T>
+bool Promise<T>::set(const Future<T>& future)
+{
+ return associate(future);
+}
+
+
+template <typename T>
+bool Promise<T>::associate(const Future<T>& future)
+{
+ if (!f.isPending()) {
+ return false;
+ }
+
+ future
+ .onReady(std::tr1::bind(&Future<T>::set, f, std::tr1::placeholders::_1))
+ .onFailed(std::tr1::bind(&Future<T>::fail, f, std::tr1::placeholders::_1))
+ .onDiscarded(std::tr1::bind(&Future<T>::discard, f));
+
+ return true;
+}
+
+
+template <typename T>
+bool Promise<T>::fail(const std::string& message)
+{
+ return f.fail(message);
+}
+
+
+template <typename T>
+Future<T> Promise<T>::future() const
+{
+ return f;
+}
+
+
+// Internal helper utilities.
+namespace internal {
+
+template <typename T>
+struct wrap
+{
+ typedef Future<T> Type;
+};
+
+
+template <typename X>
+struct wrap<Future<X> >
+{
+ typedef Future<X> Type;
+};
+
+
+template <typename T>
+struct unwrap
+{
+ typedef T Type;
+};
+
+
+template <typename X>
+struct unwrap<Future<X> >
+{
+ typedef X Type;
+};
+
+
+inline void acquire(int* lock)
+{
+ while (!__sync_bool_compare_and_swap(lock, 0, 1)) {
+ asm volatile ("pause");
+ }
+}
+
+
+inline void release(int* lock)
+{
+ // Unlock via a compare-and-swap so we get a memory barrier too.
+ bool unlocked = __sync_bool_compare_and_swap(lock, 1, 0);
+ assert(unlocked);
+}
+
+
+template <typename T>
+void select(
+ const Future<T>& future,
+ std::tr1::shared_ptr<Promise<Future<T > > > promise)
+{
+ // We never fail the future associated with our promise.
+ assert(!promise->future().isFailed());
+
+ if (promise->future().isPending()) { // No-op if it's discarded.
+ if (future.isReady()) { // We only set the promise if a future is ready.
+ promise->set(future);
+ }
+ }
+}
+
+} // namespace internal {
+
+
+// TODO(benh): Move select and discard into 'futures' namespace.
+
+// Returns a future that captures any ready future in a set. Note that
+// select DOES NOT capture a future that has failed or been discarded.
+template <typename T>
+Future<Future<T> > select(const std::set<Future<T> >& futures)
+{
+ std::tr1::shared_ptr<Promise<Future<T> > > promise(
+ new Promise<Future<T> >());
+
+ Future<Future<T> > future = promise->future();
+
+ std::tr1::function<void(const Future<T>&)> select =
+ std::tr1::bind(&internal::select<T>,
+ std::tr1::placeholders::_1,
+ promise);
+
+ typename std::set<Future<T> >::iterator iterator;
+ for (iterator = futures.begin(); iterator != futures.end(); ++iterator) {
+ (*iterator).onAny(std::tr1::bind(select, std::tr1::placeholders::_1));
+ }
+
+ return future;
+}
+
+
+template <typename T>
+void discard(const std::set<Future<T> >& futures)
+{
+ typename std::set<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();
+ }
+}
+
+
+template <typename T>
+void discard(const std::list<Future<T> >& futures)
+{
+ 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();
+ }
+}
+
+
+template <class T>
+void fail(const std::vector<Promise<T>*>& promises, const std::string& message)
+{
+ typename std::vector<Promise<T>*>::const_iterator iterator;
+ for (iterator = promises.begin(); iterator != promises.end(); ++iterator) {
+ Promise<T>* promise = *iterator;
+ promise->fail(message);
+ }
+}
+
+
+template <class T>
+void fail(const std::list<Promise<T>*>& promises, const std::string& message)
+{
+ typename std::list<Promise<T>*>::const_iterator iterator;
+ for (iterator = promises.begin(); iterator != promises.end(); ++iterator) {
+ Promise<T>* promise = *iterator;
+ promise->fail(message);
+ }
+}
+
+
+template <typename T>
+Future<T> Future<T>::failed(const std::string& message)
+{
+ Future<T> future;
+ future.fail(message);
+ return future;
+}
+
+
+template <typename T>
+Future<T>::Future()
+ : refs(new int(1)),
+ lock(new int(0)),
+ state(new State(PENDING)),
+ t(new T*(NULL)),
+ message(new std::string*(NULL)),
+ onReadyCallbacks(new std::queue<ReadyCallback>()),
+ onFailedCallbacks(new std::queue<FailedCallback>()),
+ onDiscardedCallbacks(new std::queue<DiscardedCallback>()),
+ onAnyCallbacks(new std::queue<AnyCallback>()),
+ latch(new Latch()) {}
+
+
+template <typename T>
+Future<T>::Future(const T& _t)
+ : refs(new int(1)),
+ lock(new int(0)),
+ state(new State(PENDING)),
+ t(new T*(NULL)),
+ message(new std::string*(NULL)),
+ onReadyCallbacks(new std::queue<ReadyCallback>()),
+ onFailedCallbacks(new std::queue<FailedCallback>()),
+ onDiscardedCallbacks(new std::queue<DiscardedCallback>()),
+ onAnyCallbacks(new std::queue<AnyCallback>()),
+ latch(new Latch())
+{
+ set(_t);
+}
+
+
+template <typename T>
+Future<T>::Future(const Future<T>& that)
+{
+ copy(that);
+}
+
+
+template <typename T>
+Future<T>::~Future()
+{
+ cleanup();
+}
+
+
+template <typename T>
+Future<T>& Future<T>::operator = (const Future<T>& that)
+{
+ if (this != &that) {
+ cleanup();
+ copy(that);
+ }
+ return *this;
+}
+
+
+template <typename T>
+bool Future<T>::operator == (const Future<T>& that) const
+{
+ assert(latch != NULL);
+ assert(that.latch != NULL);
+ return *latch == *that.latch;
+}
+
+
+template <typename T>
+bool Future<T>::operator < (const Future<T>& that) const
+{
+ assert(latch != NULL);
+ assert(that.latch != NULL);
+ return *latch < *that.latch;
+}
+
+
+template <typename T>
+bool Future<T>::discard()
+{
+ bool result = false;
+
+ assert(lock != NULL);
+ internal::acquire(lock);
+ {
+ assert(state != NULL);
+ if (*state == PENDING) {
+ *state = DISCARDED;
+ latch->trigger();
+ result = true;
+ }
+ }
+ internal::release(lock);
+
+ // Invoke all callbacks associated with this future being
+ // DISCARDED. We don't need a lock because the state is now in
+ // DISCARDED so there should not be any concurrent modifications.
+ if (result) {
+ while (!onDiscardedCallbacks->empty()) {
+ // TODO(*): Invoke callbacks in another execution context.
+ onDiscardedCallbacks->front()();
+ onDiscardedCallbacks->pop();
+ }
+
+ while (!onAnyCallbacks->empty()) {
+ // TODO(*): Invoke callbacks in another execution context.
+ onAnyCallbacks->front()(*this);
+ onAnyCallbacks->pop();
+ }
+ }
+
+ return result;
+}
+
+
+template <typename T>
+bool Future<T>::isPending() const
+{
+ assert(state != NULL);
+ return *state == PENDING;
+}
+
+
+template <typename T>
+bool Future<T>::isReady() const
+{
+ assert(state != NULL);
+ return *state == READY;
+}
+
+
+template <typename T>
+bool Future<T>::isDiscarded() const
+{
+ assert(state != NULL);
+ return *state == DISCARDED;
+}
+
+
+template <typename T>
+bool Future<T>::isFailed() const
+{
+ assert(state != NULL);
+ return *state == FAILED;
+}
+
+
+template <typename T>
+bool Future<T>::await(const Duration& duration) const
+{
+ if (!isReady() && !isDiscarded() && !isFailed()) {
+ assert(latch != NULL);
+ return latch->await(duration);
+ }
+ return true;
+}
+
+
+template <typename T>
+T Future<T>::get() const
+{
+ if (!isReady()) {
+ await();
+ }
+
+ CHECK(!isPending()) << "Future was in PENDING after await()";
+
+ if (!isReady()) {
+ if (isFailed()) {
+ std::cerr << "Future::get() but state == FAILED: "
+ << failure() << std::endl;
+ } else if (isDiscarded()) {
+ std::cerr << "Future::get() but state == DISCARDED" << std::endl;
+ }
+ abort();
+ }
+
+ assert(t != NULL);
+ assert(*t != NULL);
+ return **t;
+}
+
+
+template <typename T>
+std::string Future<T>::failure() const
+{
+ assert(message != NULL);
+ if (*message != NULL) {
+ return **message;
+ }
+
+ return "";
+}
+
+
+template <typename T>
+const Future<T>& Future<T>::onReady(const ReadyCallback& callback) const
+{
+ bool run = false;
+
+ assert(lock != NULL);
+ internal::acquire(lock);
+ {
+ assert(state != NULL);
+ if (*state == READY) {
+ run = true;
+ } else if (*state == PENDING) {
+ onReadyCallbacks->push(callback);
+ }
+ }
+ internal::release(lock);
+
+ // TODO(*): Invoke callback in another execution context.
+ if (run) {
+ callback(**t);
+ }
+
+ return *this;
+}
+
+
+template <typename T>
+const Future<T>& Future<T>::onFailed(const FailedCallback& callback) const
+{
+ bool run = false;
+
+ assert(lock != NULL);
+ internal::acquire(lock);
+ {
+ assert(state != NULL);
+ if (*state == FAILED) {
+ run = true;
+ } else if (*state == PENDING) {
+ onFailedCallbacks->push(callback);
+ }
+ }
+ internal::release(lock);
+
+ // TODO(*): Invoke callback in another execution context.
+ if (run) {
+ callback(**message);
+ }
+
+ return *this;
+}
+
+
+template <typename T>
+const Future<T>& Future<T>::onDiscarded(
+ const DiscardedCallback& callback) const
+{
+ bool run = false;
+
+ assert(lock != NULL);
+ internal::acquire(lock);
+ {
+ assert(state != NULL);
+ if (*state == DISCARDED) {
+ run = true;
+ } else if (*state == PENDING) {
+ onDiscardedCallbacks->push(callback);
+ }
+ }
+ internal::release(lock);
+
+ // TODO(*): Invoke callback in another execution context.
+ if (run) {
+ callback();
+ }
+
+ return *this;
+}
+
+
+template <typename T>
+const Future<T>& Future<T>::onAny(const AnyCallback& callback) const
+{
+ bool run = false;
+
+ assert(lock != NULL);
+ internal::acquire(lock);
+ {
+ assert(state != NULL);
+ if (*state != PENDING) {
+ run = true;
+ } else if (*state == PENDING) {
+ onAnyCallbacks->push(callback);
+ }
+ }
+ internal::release(lock);
+
+ // TODO(*): Invoke callback in another execution context.
+ if (run) {
+ callback(*this);
+ }
+
+ return *this;
+}
+
+
+namespace internal {
+
+template <typename T, typename X>
+void thenf(const std::tr1::shared_ptr<Promise<X> >& promise,
+ const std::tr1::function<Future<X>(const T&)>& f,
+ const Future<T>& future)
+{
+ if (future.isReady()) {
+ promise->associate(f(future.get()));
+ } else if (future.isFailed()) {
+ promise->fail(future.failure());
+ } else if (future.isDiscarded()) {
+ promise->future().discard();
+ }
+}
+
+
+template <typename T, typename X>
+void then(const std::tr1::shared_ptr<Promise<X> >& promise,
+ const std::tr1::function<X(const T&)>& f,
+ const Future<T>& future)
+{
+ if (future.isReady()) {
+ promise->set(f(future.get()));
+ } else if (future.isFailed()) {
+ promise->fail(future.failure());
+ } else if (future.isDiscarded()) {
+ promise->future().discard();
+ }
+}
+
+} // namespace internal {
+
+
+template <typename T>
+template <typename X>
+Future<X> Future<T>::then(const std::tr1::function<Future<X>(const T&)>& f) const
+{
+ std::tr1::shared_ptr<Promise<X> > promise(new Promise<X>());
+
+ std::tr1::function<void(const Future<T>&)> thenf =
+ std::tr1::bind(&internal::thenf<T, X>,
+ promise,
+ f,
+ std::tr1::placeholders::_1);
+
+ onAny(thenf);
+
+ // Propagate discarding up the chain (note that we bind with a copy
+ // of this future since 'this' might no longer be valid but other
+ // references might still exist.
+ // TODO(benh): Need to pass 'future' as a weak_ptr so that we can
+ // avoid reference counting cycles!
+ std::tr1::function<void(void)> discard =
+ std::tr1::bind(&Future<T>::discard, *this);
+
+ promise->future().onDiscarded(discard);
+
+ return promise->future();
+}
+
+
+template <typename T>
+template <typename X>
+Future<X> Future<T>::then(const std::tr1::function<X(const T&)>& f) const
+{
+ std::tr1::shared_ptr<Promise<X> > promise(new Promise<X>());
+
+ std::tr1::function<void(const Future<T>&)> then =
+ std::tr1::bind(&internal::then<T, X>,
+ promise,
+ f,
+ std::tr1::placeholders::_1);
+
+ onAny(then);
+
+ // Propagate discarding up the chain (note that we bind with a copy
+ // of this future since 'this' might no longer be valid but other
+ // references might still exist.
+ // TODO(benh): Need to pass 'future' as a weak_ptr so that we can
+ // avoid reference counting cycles!
+ std::tr1::function<void(void)> discard =
+ std::tr1::bind(&Future<T>::discard, *this);
+
+ promise->future().onDiscarded(discard);
+
+ return promise->future();
+}
+
+
+#if __cplusplus >= 201103L
+template <typename T>
+template <typename F>
+auto Future<T>::then(F f) const
+ -> typename internal::wrap<decltype(f(T()))>::Type
+{
+ typedef typename internal::unwrap<decltype(f(T()))>::Type X;
+
+ std::tr1::shared_ptr<Promise<X>> promise(new Promise<X>());
+
+ onAny([=] (const Future<T>& future) {
+ if (future.isReady()) {
+ promise->set(f(future.get()));
+ } else if (future.isFailed()) {
+ promise->fail(future.failure());
+ } else if (future.isDiscarded()) {
+ promise->future().discard();
+ }
+ });
+
+ // TODO(benh): Need to use weak_ptr here so that we can avoid
+ // reference counting cycles!
+ Future<T> future(*this);
+
+ promise->future().onDiscarded([=] () {
+ future.discard(); // Need a non-const copy to discard.
+ });
+
+ return promise->future();
+}
+#endif
+
+
+template <typename T>
+bool Future<T>::set(const T& _t)
+{
+ bool result = false;
+
+ assert(lock != NULL);
+ internal::acquire(lock);
+ {
+ assert(state != NULL);
+ if (*state == PENDING) {
+ *t = new T(_t);
+ *state = READY;
+ latch->trigger();
+ result = true;
+ }
+ }
+ internal::release(lock);
+
+ // Invoke all callbacks associated with this future being READY. We
+ // don't need a lock because the state is now in READY so there
+ // should not be any concurrent modications.
+ if (result) {
+ while (!onReadyCallbacks->empty()) {
+ // TODO(*): Invoke callbacks in another execution context.
+ onReadyCallbacks->front()(**t);
+ onReadyCallbacks->pop();
+ }
+
+ while (!onAnyCallbacks->empty()) {
+ // TODO(*): Invoke callbacks in another execution context.
+ onAnyCallbacks->front()(*this);
+ onAnyCallbacks->pop();
+ }
+ }
+
+ return result;
+}
+
+
+template <typename T>
+bool Future<T>::fail(const std::string& _message)
+{
+ bool result = false;
+
+ assert(lock != NULL);
+ internal::acquire(lock);
+ {
+ assert(state != NULL);
+ if (*state == PENDING) {
+ *message = new std::string(_message);
+ *state = FAILED;
+ latch->trigger();
+ result = true;
+ }
+ }
+ internal::release(lock);
+
+ // Invoke all callbacks associated with this future being FAILED. We
+ // don't need a lock because the state is now in FAILED so there
+ // should not be any concurrent modications.
+ if (result) {
+ while (!onFailedCallbacks->empty()) {
+ // TODO(*): Invoke callbacks in another execution context.
+ onFailedCallbacks->front()(**message);
+ onFailedCallbacks->pop();
+ }
+
+ while (!onAnyCallbacks->empty()) {
+ // TODO(*): Invoke callbacks in another execution context.
+ onAnyCallbacks->front()(*this);
+ onAnyCallbacks->pop();
+ }
+ }
+
+ return result;
+}
+
+
+template <typename T>
+void Future<T>::copy(const Future<T>& that)
+{
+ assert(that.refs > 0);
+ __sync_fetch_and_add(that.refs, 1);
+ refs = that.refs;
+ lock = that.lock;
+ state = that.state;
+ t = that.t;
+ message = that.message;
+ onReadyCallbacks = that.onReadyCallbacks;
+ onFailedCallbacks = that.onFailedCallbacks;
+ onDiscardedCallbacks = that.onDiscardedCallbacks;
+ onAnyCallbacks = that.onAnyCallbacks;
+ latch = that.latch;
+}
+
+
+template <typename T>
+void Future<T>::cleanup()
+{
+ assert(refs != NULL);
+ if (__sync_sub_and_fetch(refs, 1) == 0) {
+ // Discard the future if it is still pending (so we invoke any
+ // discarded callbacks that have been setup). Note that we put the
+ // reference count back at 1 here in case one of the callbacks
+ // decides it wants to keep a reference.
+ assert(state != NULL);
+ if (*state == PENDING) {
+ *refs = 1;
+ discard();
+ __sync_sub_and_fetch(refs, 1);
+ }
+
+ // Now try and cleanup again (this time we know the future has
+ // either been discarded or was not pending). Note that one of the
+ // callbacks might have stored the future, in which case we'll
+ // just return without doing anything, but the state will forever
+ // be "discarded".
+ assert(refs != NULL);
+ if (*refs == 0) {
+ delete refs;
+ refs = NULL;
+ assert(lock != NULL);
+ delete lock;
+ lock = NULL;
+ assert(state != NULL);
+ delete state;
+ state = NULL;
+ assert(t != NULL);
+ delete *t;
+ delete t;
+ t = NULL;
+ assert(message != NULL);
+ delete *message;
+ delete message;
+ message = NULL;
+ assert(onReadyCallbacks != NULL);
+ delete onReadyCallbacks;
+ onReadyCallbacks = NULL;
+ assert(onFailedCallbacks != NULL);
+ delete onFailedCallbacks;
+ onFailedCallbacks = NULL;
+ assert(onDiscardedCallbacks != NULL);
+ delete onDiscardedCallbacks;
+ onDiscardedCallbacks = NULL;
+ assert(onAnyCallbacks != NULL);
+ delete onAnyCallbacks;
+ onAnyCallbacks = NULL;
+ assert(latch != NULL);
+ delete latch;
+ latch = NULL;
+ }
+ }
+}
+
+} // namespace process {
+
+#endif // __PROCESS_FUTURE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/gc.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/gc.hpp b/3rdparty/libprocess/include/process/gc.hpp
new file mode 100644
index 0000000..e83c636
--- /dev/null
+++ b/3rdparty/libprocess/include/process/gc.hpp
@@ -0,0 +1,46 @@
+#ifndef __PROCESS_GC_HPP__
+#define __PROCESS_GC_HPP__
+
+#include <map>
+
+#include <process/process.hpp>
+
+
+namespace process {
+
+class GarbageCollector : public Process<GarbageCollector>
+{
+public:
+ GarbageCollector() : ProcessBase("__gc__") {}
+ virtual ~GarbageCollector() {}
+
+ template <typename T>
+ void manage(const T* t)
+ {
+ const ProcessBase* process = t;
+ if (process != NULL) {
+ processes[process->self()] = process;
+ link(process->self());
+ }
+ }
+
+protected:
+ virtual void exited(const UPID& pid)
+ {
+ if (processes.count(pid) > 0) {
+ const ProcessBase* process = processes[pid];
+ processes.erase(pid);
+ delete process;
+ }
+ }
+
+private:
+ std::map<UPID, const ProcessBase*> processes;
+};
+
+
+extern PID<GarbageCollector> gc;
+
+} // namespace process {
+
+#endif // __PROCESS_GC_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/gmock.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/gmock.hpp b/3rdparty/libprocess/include/process/gmock.hpp
new file mode 100644
index 0000000..a8cab4c
--- /dev/null
+++ b/3rdparty/libprocess/include/process/gmock.hpp
@@ -0,0 +1,327 @@
+#ifndef __PROCESS_GMOCK_HPP__
+#define __PROCESS_GMOCK_HPP__
+
+#include <pthread.h>
+
+#include <gmock/gmock.h>
+
+#include <tr1/tuple>
+
+#include <process/dispatch.hpp>
+#include <process/event.hpp>
+#include <process/filter.hpp>
+#include <process/pid.hpp>
+
+#include <stout/exit.hpp>
+#include <stout/nothing.hpp>
+
+
+// THIS IS DEPRECATED AND BROKEN! REPLACE ALL USES!
+#define EXPECT_MESSAGE(name, from, to) \
+ EXPECT_CALL(*new process::MockFilter(), \
+ filter(testing::A<const process::MessageEvent&>())) \
+ .With(process::MessageMatcher(name, from, to))
+
+
+// THIS IS DEPRECATED AND BROKEN! REPLACE ALL USES!
+#define EXPECT_DISPATCH(pid, method) \
+ EXPECT_CALL(*new process::MockFilter(), \
+ filter(testing::A<const process::DispatchEvent&>())) \
+ .With(process::DispatchMatcher(pid, method))
+
+
+#define FUTURE_MESSAGE(name, from, to) \
+ process::FutureMessage(name, from, to)
+
+#define DROP_MESSAGE(name, from, to) \
+ process::FutureMessage(name, from, to, true)
+
+#define FUTURE_DISPATCH(pid, method) \
+ process::FutureDispatch(pid, method)
+
+#define DROP_DISPATCH(pid, method) \
+ process::FutureDispatch(pid, method, true)
+
+#define DROP_MESSAGES(name, from, to) \
+ process::DropMessages(name, from, to)
+
+#define DROP_DISPATCHES(pid, method) \
+ process::DropDispatches(pid, method)
+
+
+ACTION_TEMPLATE(PromiseArg,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_1_VALUE_PARAMS(promise))
+{
+ // TODO(benh): Use a shared_ptr for promise to defend against this
+ // action getting invoked more than once (e.g., used via
+ // WillRepeatedly). We won't be able to set it a second time but at
+ // least we won't get a segmentation fault. We could also consider
+ // warning users if they attempted to set it more than once.
+ promise->set(std::tr1::get<k>(args));
+ delete promise;
+}
+
+
+template <int index, typename T>
+PromiseArgActionP<index, process::Promise<T>*> FutureArg(
+ process::Future<T>* future)
+{
+ process::Promise<T>* promise = new process::Promise<T>();
+ *future = promise->future();
+ return PromiseArg<index>(promise);
+}
+
+
+ACTION_TEMPLATE(PromiseArgField,
+ HAS_1_TEMPLATE_PARAMS(int, k),
+ AND_2_VALUE_PARAMS(field, promise))
+{
+ // TODO(benh): Use a shared_ptr for promise to defend against this
+ // action getting invoked more than once (e.g., used via
+ // WillRepeatedly). We won't be able to set it a second time but at
+ // least we won't get a segmentation fault. We could also consider
+ // warning users if they attempted to set it more than once.
+ promise->set(*(std::tr1::get<k>(args).*field));
+ delete promise;
+}
+
+
+template <int index, typename Field, typename T>
+PromiseArgFieldActionP2<index, Field, process::Promise<T>*> FutureArgField(
+ Field field,
+ process::Future<T>* future)
+{
+ process::Promise<T>* promise = new process::Promise<T>();
+ *future = promise->future();
+ return PromiseArgField<index>(field, promise);
+}
+
+
+ACTION_P2(PromiseSatisfy, promise, value)
+{
+ promise->set(value);
+ delete promise;
+}
+
+
+template <typename T>
+PromiseSatisfyActionP2<process::Promise<T>*, T> FutureSatisfy(
+ process::Future<T>* future,
+ T t)
+{
+ process::Promise<T>* promise = new process::Promise<T>();
+ *future = promise->future();
+ return PromiseSatisfy(promise, t);
+}
+
+
+inline PromiseSatisfyActionP2<process::Promise<Nothing>*, Nothing>
+FutureSatisfy(process::Future<Nothing>* future)
+{
+ process::Promise<Nothing>* promise = new process::Promise<Nothing>();
+ *future = promise->future();
+ return PromiseSatisfy(promise, Nothing());
+}
+
+
+namespace process {
+
+class MockFilter : public Filter
+{
+public:
+ MockFilter()
+ {
+ EXPECT_CALL(*this, filter(testing::A<const MessageEvent&>()))
+ .WillRepeatedly(testing::Return(false));
+ EXPECT_CALL(*this, filter(testing::A<const DispatchEvent&>()))
+ .WillRepeatedly(testing::Return(false));
+ EXPECT_CALL(*this, filter(testing::A<const HttpEvent&>()))
+ .WillRepeatedly(testing::Return(false));
+ EXPECT_CALL(*this, filter(testing::A<const ExitedEvent&>()))
+ .WillRepeatedly(testing::Return(false));
+ }
+
+ MOCK_METHOD1(filter, bool(const MessageEvent&));
+ MOCK_METHOD1(filter, bool(const DispatchEvent&));
+ MOCK_METHOD1(filter, bool(const HttpEvent&));
+ MOCK_METHOD1(filter, bool(const ExitedEvent&));
+};
+
+
+// A definition of a libprocess filter to enable waiting for events
+// (such as messages or dispatches) via in tests. This is not meant to
+// be used directly by tests; tests should use macros like
+// FUTURE_MESSAGE and FUTURE_DISPATCH instead.
+class TestsFilter : public Filter
+{
+public:
+ TestsFilter()
+ {
+ // We use a recursive mutex here in the event that satisfying the
+ // future created in FutureMessage or FutureDispatch via the
+ // FutureArgField or FutureSatisfy actions invokes callbacks (from
+ // Future::then or Future::onAny, etc) that themselves invoke
+ // FutureDispatch or FutureMessage.
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&mutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+ }
+
+ virtual bool filter(const MessageEvent& event) { return handle(event); }
+ virtual bool filter(const DispatchEvent& event) { return handle(event); }
+ virtual bool filter(const HttpEvent& event) { return handle(event); }
+ virtual bool filter(const ExitedEvent& event) { return handle(event); }
+
+ template <typename T>
+ bool handle(const T& t)
+ {
+ pthread_mutex_lock(&mutex);
+ bool drop = mock.filter(t);
+ pthread_mutex_unlock(&mutex);
+ return drop;
+ }
+
+ MockFilter mock;
+ pthread_mutex_t mutex;;
+};
+
+
+class FilterTestEventListener : public ::testing::EmptyTestEventListener
+{
+public:
+ // Returns the singleton instance of the listener.
+ static FilterTestEventListener* instance()
+ {
+ static FilterTestEventListener* listener = new FilterTestEventListener();
+ return listener;
+ }
+
+ // Installs and returns the filter, creating it if necessary.
+ TestsFilter* install()
+ {
+ if (!started) {
+ EXIT(1)
+ << "To use FUTURE/DROP_MESSAGE/DISPATCH, etc. you need to do the "
+ << "following before you invoke RUN_ALL_TESTS():\n\n"
+ << "\t::testing::TestEventListeners& listeners =\n"
+ << "\t ::testing::UnitTest::GetInstance()->listeners();\n"
+ << "\tlisteners.Append(process::FilterTestEventListener::instance());";
+ }
+
+ if (filter != NULL) {
+ return filter;
+ }
+
+ filter = new TestsFilter();
+
+ // Set the filter in libprocess.
+ process::filter(filter);
+
+ return filter;
+ }
+
+ virtual void OnTestProgramStart(const ::testing::UnitTest&)
+ {
+ started = true;
+ }
+
+ virtual void OnTestEnd(const ::testing::TestInfo&)
+ {
+ if (filter != NULL) {
+ // Remove the filter in libprocess _before_ deleting.
+ process::filter(NULL);
+ delete filter;
+ filter = NULL;
+ }
+ }
+
+private:
+ FilterTestEventListener() : filter(NULL), started(false) {}
+
+ TestsFilter* filter;
+
+ // Indicates if we got the OnTestProgramStart callback in order to
+ // detect if we have been properly added as a listener.
+ bool started;
+};
+
+
+MATCHER_P3(MessageMatcher, name, from, to, "")
+{
+ const MessageEvent& event = ::std::tr1::get<0>(arg);
+ return (testing::Matcher<std::string>(name).Matches(event.message->name) &&
+ testing::Matcher<UPID>(from).Matches(event.message->from) &&
+ testing::Matcher<UPID>(to).Matches(event.message->to));
+}
+
+
+MATCHER_P2(DispatchMatcher, pid, method, "")
+{
+ const DispatchEvent& event = ::std::tr1::get<0>(arg);
+ return (testing::Matcher<UPID>(pid).Matches(event.pid) &&
+ testing::Matcher<std::string>(internal::canonicalize(method))
+ .Matches(event.method));
+}
+
+
+template <typename Name, typename From, typename To>
+Future<Message> FutureMessage(Name name, From from, To to, bool drop = false)
+{
+ TestsFilter* filter = FilterTestEventListener::instance()->install();
+ pthread_mutex_lock(&filter->mutex);
+ Future<Message> future;
+ EXPECT_CALL(filter->mock, filter(testing::A<const MessageEvent&>()))
+ .With(MessageMatcher(name, from, to))
+ .WillOnce(testing::DoAll(FutureArgField<0>(&MessageEvent::message, &future),
+ testing::Return(drop)))
+ .RetiresOnSaturation(); // Don't impose any subsequent expectations.
+ pthread_mutex_unlock(&filter->mutex);
+ return future;
+}
+
+
+template <typename PID, typename Method>
+Future<Nothing> FutureDispatch(PID pid, Method method, bool drop = false)
+{
+ TestsFilter* filter = FilterTestEventListener::instance()->install();
+ pthread_mutex_lock(&filter->mutex);
+ Future<Nothing> future;
+ EXPECT_CALL(filter->mock, filter(testing::A<const DispatchEvent&>()))
+ .With(DispatchMatcher(pid, method))
+ .WillOnce(testing::DoAll(FutureSatisfy(&future),
+ testing::Return(drop)))
+ .RetiresOnSaturation(); // Don't impose any subsequent expectations.
+ pthread_mutex_unlock(&filter->mutex);
+ return future;
+}
+
+
+template <typename Name, typename From, typename To>
+void DropMessages(Name name, From from, To to)
+{
+ TestsFilter* filter = FilterTestEventListener::instance()->install();
+ pthread_mutex_lock(&filter->mutex);
+ EXPECT_CALL(filter->mock, filter(testing::A<const MessageEvent&>()))
+ .With(MessageMatcher(name, from, to))
+ .WillRepeatedly(testing::Return(true));
+ pthread_mutex_unlock(&filter->mutex);
+}
+
+
+template <typename PID, typename Method>
+void DropDispatches(PID pid, Method method)
+{
+ TestsFilter* filter = FilterTestEventListener::instance()->install();
+ pthread_mutex_lock(&filter->mutex);
+ EXPECT_CALL(filter->mock, filter(testing::A<const DispatchEvent&>()))
+ .With(DispatchMatcher(pid, method))
+ .WillRepeatedly(testing::Return(true));
+ pthread_mutex_unlock(&filter->mutex);
+}
+
+} // namespace process {
+
+#endif // __PROCESS_GMOCK_HPP__
[20/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/proc.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/proc.hpp b/third_party/libprocess/3rdparty/stout/include/stout/proc.hpp
deleted file mode 100644
index b59735f..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/proc.hpp
+++ /dev/null
@@ -1,478 +0,0 @@
-/**
- * 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/third_party/libprocess/3rdparty/stout/include/stout/protobuf.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/protobuf.hpp b/third_party/libprocess/3rdparty/stout/include/stout/protobuf.hpp
deleted file mode 100644
index eb79e7b..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/protobuf.hpp
+++ /dev/null
@@ -1,159 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/include/stout/result.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/result.hpp b/third_party/libprocess/3rdparty/stout/include/stout/result.hpp
deleted file mode 100644
index f918f86..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/result.hpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/include/stout/stopwatch.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/stopwatch.hpp b/third_party/libprocess/3rdparty/stout/include/stout/stopwatch.hpp
deleted file mode 100644
index bcff8c6..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/stopwatch.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/include/stout/stringify.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/stringify.hpp b/third_party/libprocess/3rdparty/stout/include/stout/stringify.hpp
deleted file mode 100644
index 136316d..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/stringify.hpp
+++ /dev/null
@@ -1,124 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/include/stout/strings.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/strings.hpp b/third_party/libprocess/3rdparty/stout/include/stout/strings.hpp
deleted file mode 100644
index ed14106..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/strings.hpp
+++ /dev/null
@@ -1,263 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/include/stout/try.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/try.hpp b/third_party/libprocess/3rdparty/stout/include/stout/try.hpp
deleted file mode 100644
index 787bffd..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/try.hpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/include/stout/utils.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/utils.hpp b/third_party/libprocess/3rdparty/stout/include/stout/utils.hpp
deleted file mode 100644
index 0f4bba2..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/utils.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/include/stout/uuid.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/uuid.hpp b/third_party/libprocess/3rdparty/stout/include/stout/uuid.hpp
deleted file mode 100644
index c6c290d..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/uuid.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/install-sh
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/install-sh b/third_party/libprocess/3rdparty/stout/install-sh
deleted file mode 100755
index 6781b98..0000000
--- a/third_party/libprocess/3rdparty/stout/install-sh
+++ /dev/null
@@ -1,520 +0,0 @@
-#!/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/third_party/libprocess/3rdparty/stout/m4/acx_pthread.m4
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/m4/acx_pthread.m4 b/third_party/libprocess/3rdparty/stout/m4/acx_pthread.m4
deleted file mode 100644
index 2cf20de..0000000
--- a/third_party/libprocess/3rdparty/stout/m4/acx_pthread.m4
+++ /dev/null
@@ -1,363 +0,0 @@
-# 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/third_party/libprocess/3rdparty/stout/tests/bytes_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/bytes_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/bytes_tests.cpp
deleted file mode 100644
index 18b2474..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/bytes_tests.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/duration_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/duration_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/duration_tests.cpp
deleted file mode 100644
index e0910d4..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/duration_tests.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/error_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/error_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/error_tests.cpp
deleted file mode 100644
index 75e365e..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/error_tests.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/flags_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/flags_tests.cpp
deleted file mode 100644
index 2809280..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/flags_tests.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/gzip_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/gzip_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/gzip_tests.cpp
deleted file mode 100644
index 13296d8..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/gzip_tests.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/hashset_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/hashset_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/hashset_tests.cpp
deleted file mode 100644
index 72f65c4..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/hashset_tests.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/json_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/json_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/json_tests.cpp
deleted file mode 100644
index c582d70..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/json_tests.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/main.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/main.cpp b/third_party/libprocess/3rdparty/stout/tests/main.cpp
deleted file mode 100644
index 0f1e9cb..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/main.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/multimap_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/multimap_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/multimap_tests.cpp
deleted file mode 100644
index 79e7200..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/multimap_tests.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-#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/third_party/libprocess/3rdparty/stout/tests/none_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/none_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/none_tests.cpp
deleted file mode 100644
index 38d25bb..0000000
--- a/third_party/libprocess/3rdparty/stout/tests/none_tests.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#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());
-}
[10/35] git commit: Replaced flags and configurator in Mesos with
flags in stout.
Posted by be...@apache.org.
Replaced flags and configurator in Mesos with flags in stout.
Review: https://reviews.apache.org/r/11466
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/29183c1b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/29183c1b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/29183c1b
Branch: refs/heads/master
Commit: 29183c1b04f9060ba60f59d657c30ff9266b17c8
Parents: 190a3bb
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 26 22:29:26 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:18:39 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 10 +-
src/configurator/configuration.cpp | 43 ---
src/configurator/configuration.hpp | 158 ------------
src/configurator/configurator.cpp | 428 -------------------------------
src/configurator/configurator.hpp | 385 ---------------------------
src/configurator/get_conf.cpp | 52 ----
src/configurator/option.hpp | 153 -----------
src/examples/test_framework.cpp | 5 +-
src/flags/flag.hpp | 23 --
src/flags/flags.hpp | 344 -------------------------
src/flags/loader.hpp | 109 --------
src/flags/parse.hpp | 55 ----
src/local/flags.hpp | 6 +-
src/local/local.cpp | 25 +-
src/local/local.hpp | 6 +-
src/local/main.cpp | 34 ++--
src/log/main.cpp | 27 +--
src/logging/flags.hpp | 3 +-
src/logging/logging.hpp | 3 -
src/master/flags.hpp | 3 +-
src/master/main.cpp | 27 +--
src/master/master.cpp | 2 -
src/master/master.hpp | 4 -
src/mesos/main.cpp | 105 +--------
src/sched/sched.cpp | 46 ++---
src/slave/flags.hpp | 3 +-
src/slave/main.cpp | 28 +--
src/tests/allocator_tests.cpp | 2 -
src/tests/configurator_tests.cpp | 261 -------------------
src/tests/environment.cpp | 15 +-
src/tests/flags.hpp | 3 +-
src/tests/flags_tests.cpp | 223 ----------------
src/tests/main.cpp | 28 +-
33 files changed, 123 insertions(+), 2496 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 644e1ca..738c18f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -185,7 +185,6 @@ libmesos_no_third_party_la_SOURCES = \
exec/exec.cpp \
common/lock.cpp \
detector/detector.cpp \
- configurator/configurator.cpp \
common/date_utils.cpp \
common/resources.cpp \
common/attributes.cpp \
@@ -218,11 +217,9 @@ libmesos_no_third_party_la_SOURCES += common/attributes.hpp \
common/protobuf_utils.hpp \
common/lock.hpp common/resources.hpp common/process_utils.hpp \
common/type_utils.hpp common/thread.hpp common/units.hpp \
- common/values.hpp configurator/configuration.hpp \
- configurator/configurator.hpp configurator/option.hpp \
+ common/values.hpp \
detector/detector.hpp examples/utils.hpp files/files.hpp \
- flags/flag.hpp flags/flags.hpp flags/loader.hpp \
- flags/parse.hpp launcher/launcher.hpp linux/cgroups.hpp \
+ launcher/launcher.hpp linux/cgroups.hpp \
linux/fs.hpp local/flags.hpp local/local.hpp \
logging/check_some.hpp logging/flags.hpp logging/logging.hpp \
master/allocator.hpp \
@@ -804,14 +801,13 @@ mesos_tests_SOURCES = tests/main.cpp tests/utils.cpp \
tests/gc_tests.cpp \
tests/resource_offers_tests.cpp \
tests/fault_tolerance_tests.cpp \
- tests/files_tests.cpp tests/flags_tests.cpp \
+ tests/files_tests.cpp \
tests/isolator_tests.cpp \
tests/log_tests.cpp \
tests/monitor_tests.cpp \
tests/resources_tests.cpp \
tests/script.cpp \
tests/examples_tests.cpp \
- tests/configurator_tests.cpp \
tests/protobuf_io_tests.cpp \
tests/zookeeper_url_tests.cpp \
tests/killtree_tests.cpp \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/configurator/configuration.cpp
----------------------------------------------------------------------
diff --git a/src/configurator/configuration.cpp b/src/configurator/configuration.cpp
deleted file mode 100644
index fded13c..0000000
--- a/src/configurator/configuration.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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 <mesos.h>
-
-#include "configuration.hpp"
-
-
-using namespace mesos;
-using namespace mesos::internal;
-
-
-int params_get_int(const char *params, const char *key, int defVal)
-{
- return Params(params).getInt(key, defVal);
-}
-
-
-int32_t params_get_int32(const char *params, const char *key, int32_t defVal)
-{
- return Params(params).getInt32(key, defVal);
-}
-
-
-int64_t params_get_int64(const char *params, const char *key, int64_t defVal)
-{
- return Params(params).getInt64(key, defVal);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/configurator/configuration.hpp
----------------------------------------------------------------------
diff --git a/src/configurator/configuration.hpp b/src/configurator/configuration.hpp
deleted file mode 100644
index 95effd2..0000000
--- a/src/configurator/configuration.hpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * 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 __CONFIGURATION_HPP__
-#define __CONFIGURATION_HPP__
-
-#include <map>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <boost/lexical_cast.hpp>
-
-#include <stout/foreach.hpp>
-#include <stout/none.hpp>
-#include <stout/option.hpp>
-#include <stout/strings.hpp>
-
-
-namespace mesos {
-namespace internal {
-
-struct ParseException : std::exception
-{
- ParseException(const std::string& _message) : message(_message) {}
- ~ParseException() throw () {}
- const char* what() const throw () { return message.c_str(); }
- const std::string message;
-};
-
-
-/**
- * Stores a set of key-value pairs that can be accessed as strings,
- * ints, etc.
- */
-class Configuration
-{
-private:
- std::map<std::string, std::string> params;
-
-public:
- Configuration() {}
-
- Configuration(const std::map<std::string, std::string>& params_)
- : params(params_) {}
-
- Configuration(const std::string& str)
- {
- loadString(str);
- }
-
- /**
- * Load key-value pairs from a map into this Configuration object.
- */
- void loadMap(const std::map<std::string, std::string>& params_)
- {
- foreachpair (const std::string& k, const std::string& v, params_) {
- params[k] = v;
- }
- }
-
- /**
- * Load key-value pairs from a string into this Configuration
- * object. The string should contain pairs of the form key=value,
- * one per line.
- */
- void loadString(const std::string& str)
- {
- std::vector<std::string> lines = strings::tokenize(str, "\n\r");
- foreach (std::string& line, lines) {
- std::vector<std::string> parts = strings::tokenize(line, "=");
- if (parts.size() != 2) {
- const Try<std::string>& error =
- strings::format("Failed to parse '%s'", line);
- throw ParseException(error.isSome() ? error.get() : "Failed to parse");
- }
- params[parts[0]] = parts[1];
- }
- }
-
- std::string& operator[] (const std::string& key)
- {
- return params[key];
- }
-
- template <typename T>
- Option<T> get(const std::string& key) const
- {
- std::map<std::string, std::string>::const_iterator it = params.find(key);
- if (it != params.end()) {
- return boost::lexical_cast<T>(it->second);
- }
-
- return None();
- }
-
- template <typename T>
- T get(const std::string& key, const T& defaultValue) const
- {
- std::map<std::string, std::string>::const_iterator it = params.find(key);
- if (it != params.end()) {
- return boost::lexical_cast<T>(it->second);
- }
-
- return defaultValue;
- }
-
- template <typename T>
- void set(const std::string& key, T value)
- {
- params[key] = boost::lexical_cast<std::string>(value);
- }
-
- std::string str() const
- {
- std::ostringstream oss;
- foreachpair (const std::string& key, const std::string& value, params) {
- oss << key << "=" << value << "\n";
- }
- return oss.str();
- }
-
- std::map<std::string, std::string>& getMap()
- {
- return params;
- }
-
- const std::map<std::string, std::string>& getMap() const
- {
- return params;
- }
-
- bool contains(const std::string& key) const
- {
- return params.find(key) != params.end();
- }
-};
-
-
-} // namespace internal {
-} // namespace mesos {
-
-#endif // __CONFIGURATION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/configurator/configurator.cpp
----------------------------------------------------------------------
diff --git a/src/configurator/configurator.cpp b/src/configurator/configurator.cpp
deleted file mode 100644
index bf45939..0000000
--- a/src/configurator/configurator.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/**
- * 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 <libgen.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include <algorithm>
-#include <fstream>
-#include <iostream>
-
-#include <stout/foreach.hpp>
-#include <stout/os.hpp>
-#include <stout/strings.hpp>
-
-#include "configurator.hpp"
-#include "configuration.hpp"
-
-using namespace mesos::internal;
-
-using std::ifstream;
-using std::map;
-using std::string;
-using std::vector;
-
-
-const char* Configurator::DEFAULT_CONFIG_DIR = "conf";
-const char* Configurator::CONFIG_FILE_NAME = "mesos.conf";
-const char* Configurator::ENV_VAR_PREFIX = "MESOS_";
-
-
-// Define a function for accessing the list of environment variables
-// in a platform-independent way.
-// On Mac OS X, the environ symbol isn't visible to shared libraries,
-// so we must use the _NSGetEnviron() function (see man environ on OS X).
-// On other platforms, it's fine to access environ from shared libraries.
-#ifdef __APPLE__
-#include "crt_externs.h"
-namespace {
-char** getEnviron() { return *_NSGetEnviron(); }
-}
-#else
-extern char** environ;
-namespace {
-char** getEnviron() { return environ; }
-}
-#endif /* __APPLE__ */
-
-
-void Configurator::validate()
-{
- foreachpair (const string& key, const ConfigOption& opt, options) {
- if (conf.contains(key) && opt.validator &&
- !opt.validator->isValid(conf[key])) {
- string msg = "Invalid value for '" + key + "' option: " + conf[key];
- throw ConfigurationException(msg.c_str());
- }
- }
-}
-
-
-Configuration& Configurator::load(int argc, char** argv)
-{
- loadEnv();
- loadCommandLine(argc, argv);
- loadConfigFileIfGiven();
- loadDefaults();
- validate();
- return conf;
-}
-
-
-Configuration& Configurator::load()
-{
- loadEnv();
- loadConfigFileIfGiven();
- loadDefaults();
- validate();
- return conf;
-}
-
-
-Configuration& Configurator::load(const map<string, string>& _params)
-{
- loadEnv();
- conf.loadMap(_params);
- loadConfigFileIfGiven();
- loadDefaults();
- validate();
- return conf;
-}
-
-
-void Configurator::loadConfigFileIfGiven(bool overwrite) {
- if (conf.contains("conf")) {
- // If conf param is given, always look for a config file in that directory.
- Try<string> path =
- os::realpath(conf["conf"] + "/" + CONFIG_FILE_NAME);
-
- if (path.isError()) {
- LOG(WARNING) << "Cannot load config file: " << path.error();
- } else {
- loadConfigFile(path.get(), overwrite);
- }
- }
-}
-
-
-void Configurator::loadEnv(bool overwrite)
-{
- char** environ = getEnviron();
- int i = 0;
- while (environ[i] != NULL) {
- string line = environ[i];
- if (line.find(ENV_VAR_PREFIX) == 0) {
- string key, val;
- size_t eq = line.find_first_of("=");
- if (eq == string::npos)
- continue; // ignore malformed lines (they shouldn't occur in environ!)
- key = line.substr(strlen(ENV_VAR_PREFIX), eq - strlen(ENV_VAR_PREFIX));
- std::transform(key.begin(), key.end(), key.begin(), ::tolower);
- val = line.substr(eq + 1);
- // Disallow setting home through the environment, because it should
- // always be resolved from the running Mesos binary (if any)
- if ((overwrite || !conf.contains(key))) {
- conf[key] = val;
- }
- }
- i++;
- }
-}
-
-
-void Configurator::loadCommandLine(int argc,
- char** argv,
- bool overwrite)
-{
- // Convert args 1 and above to STL strings
- vector<string> args;
- for (int i=1; i < argc; i++) {
- args.push_back(string(argv[i]));
- }
-
- // Remember number of times we see each key to warn the user if we see a
- // key multiple times (since right now we only use the first value)
- map<string, int> timesSeen;
-
- for (size_t i = 0; i < args.size(); i++) {
- string key, val;
- bool set = false;
- if (args[i].find("--", 0) == 0) {
- // handle "--" case
- size_t eq = args[i].find_first_of("=");
- if (eq == string::npos &&
- args[i].find("--no-", 0) == 0) { // handle --no-blah
- key = args[i].substr(5);
- val = "0";
- set = true;
- checkCommandLineParamFormat(key, true);
- } else if (eq == string::npos) { // handle --blah
- key = args[i].substr(2);
- val = "1";
- set = true;
- checkCommandLineParamFormat(key, true);
- } else { // handle --blah=25
- key = args[i].substr(2, eq-2);
- val = args[i].substr(eq+1);
- set = true;
- checkCommandLineParamFormat(key, false);
- }
- } else if (args[i].find_first_of("-", 0) == 0 &&
- args[i].size() > 1) {
- // handle "-" case
- char shortName = '\0';
- if (args[i].find("-no-",0) == 0 && args[i].size() == 5) {
- shortName = args[i][4];
- } else if (args[i].size() == 2) {
- shortName = args[i][1];
- }
- if (shortName == '\0' || getLongName(shortName) == "") {
- string message = "Short option '" + args[i] + "' unrecognized ";
- throw ConfigurationException(message.c_str());
- }
- key = getLongName(shortName);
- if (args[i].find("-no-",0) == 0) { // handle -no-b
- val = "0";
- set = true;
- checkCommandLineParamFormat(key, true);
- } else if (options[key].validator->isBool() ||
- i+1 == args.size() ) { // handle -b
- val = "1";
- set = true;
- checkCommandLineParamFormat(key, true);
- } else { // handle -b 25
- val = args[i+1];
- set = true;
- i++; // we've consumed next parameter as a "value"-parameter
- }
- }
- std::transform(key.begin(), key.end(), key.begin(), ::tolower);
- // Check whether the key has already appeared in the command line
- timesSeen[key]++;
- if (timesSeen[key] == 2) {
- LOG(WARNING) << "\"" << key << "\" option appears multiple times in "
- << "command line; only the first value will be used";
- }
- if (set && (overwrite || !conf.contains(key)) && timesSeen[key] == 1) {
- conf[key] = val;
- }
- }
-}
-
-
-void Configurator::loadConfigFile(const string& fname, bool overwrite)
-{
- ifstream cfg(fname.c_str(), std::ios::in);
- if (!cfg.is_open()) {
- string message = "Couldn't read Mesos config file: " + fname;
- throw ConfigurationException(message.c_str());
- }
-
- // Remember number of times we see each key to warn the user if we see a
- // key multiple times (since right now we only use the first value)
- map<string, int> timesSeen;
-
- string line, originalLine;
-
- while (!cfg.eof()) {
- getline(cfg, line);
- originalLine = line;
- // Strip any comment at end of line
- size_t hash = line.find_first_of("#"); // strip comments
- if (hash != string::npos) {
- line = line.substr(0, hash);
- }
- // Check for empty line
- line = strings::trim(line);
- if (line == "") {
- continue;
- }
- // Split line by = and trim to get key and value
- vector<string> tokens = strings::tokenize(line, "=");
- if (tokens.size() != 2) {
- string message = "Malformed line in config file: '" +
- strings::trim(originalLine) + "'";
- throw ConfigurationException(message.c_str());
- }
- string key = strings::trim(tokens[0]);
- string value = strings::trim(tokens[1]);
- // Check whether the key has already appeared in this config file
- timesSeen[key]++;
- if (timesSeen[key] == 2) {
- LOG(WARNING) << "\"" << key << "\" option appears multiple times in "
- << fname << "; only the first value will be used";
- }
- if ((overwrite || !conf.contains(key)) && timesSeen[key] == 1) {
- conf[key] = value;
- }
- }
- cfg.close();
-}
-
-
-string Configurator::getUsage() const
-{
- const int PAD = 5;
- string usage;
-
- map<string,string> col1; // key -> col 1 string
- size_t maxLen = 0;
-
- // construct string for the first column and get size of column
- foreachpair (const string& key, const ConfigOption& opt, options) {
- string val;
- if (opt.validator->isBool())
- val = " --[no-]" + key;
- else
- val = " --" + key + "=VAL";
-
- if (opt.hasShortName) {
- if (opt.validator->isBool())
- val += string(" (or -[no-]") + opt.shortName + ")";
- else
- val += string(" (or -") + opt.shortName + " VAL)";
- }
-
- col1[key] = val;
- maxLen = val.size() > maxLen ? val.size() : maxLen;
- }
-
- foreachpair (const string& key, const ConfigOption& opt, options) {
- string helpStr = opt.helpString;
- string line = col1[key];
-
- if (opt.defaultValue != "") { // add default value
- // Place a space between help string and (default: VAL) if the
- // help string does not end with a newline itself
- size_t lastNewLine = helpStr.find_last_of("\n\r");
- if (helpStr.size() > 0 && lastNewLine != helpStr.size() - 1) {
- helpStr += " ";
- }
- string defval = opt.defaultValue;
- if (opt.validator->isBool())
- defval = opt.defaultValue == "0" ? "false" : "true";
-
- helpStr += "(default: " + defval + ")";
- }
-
- string pad(PAD + maxLen - line.size(), ' ');
- line += pad;
- size_t pos1 = 0, pos2 = 0;
- pos2 = helpStr.find_first_of("\n\r", pos1);
- line += helpStr.substr(pos1, pos2 - pos1) + "\n";
- usage += line;
-
- while(pos2 != string::npos) { // handle multi line help strings
- line = "";
- pos1 = pos2 + 1;
- string pad2(PAD + maxLen, ' ');
- line += pad2;
- pos2 = helpStr.find_first_of("\n\r", pos1);
- line += helpStr.substr(pos1, pos2 - pos1) + "\n";
- usage += line;
- }
-
- }
- return usage;
-}
-
-
-void Configurator::loadDefaults()
-{
- foreachpair (const string& key, const ConfigOption& option, options) {
- if (option.hasDefault && !conf.contains(key)) {
- conf[key] = option.defaultValue;
- }
- }
-}
-
-
-vector<string> Configurator::getOptions() const
-{
- vector<string> ret;
- foreachkey (const string& key, options) {
- ret.push_back(key);
- }
- return ret;
-}
-
-
-Configuration& Configurator::getConfiguration()
-{
- return conf;
-}
-
-string Configurator::getLongName(char shortName) const
-{
- foreachpair (const string& key, const ConfigOption& opt, options) {
- if (opt.hasShortName && opt.shortName == shortName)
- return key;
- }
- return "";
-}
-
-
-void Configurator::clearMesosEnvironmentVars()
-{
- char** environ = getEnviron();
- int i = 0;
- vector<string> toRemove;
- while (environ[i] != NULL) {
- string line = environ[i];
- if (line.find(ENV_VAR_PREFIX) == 0) {
- string key;
- size_t eq = line.find_first_of("=");
- if (eq == string::npos)
- continue; // ignore malformed lines (they shouldn't occur in environ!)
- key = line.substr(strlen(ENV_VAR_PREFIX), eq - strlen(ENV_VAR_PREFIX));
- toRemove.push_back(key);
- }
- i++;
- }
- foreach (string& str, toRemove) {
- unsetenv(str.c_str());
- }
-}
-
-
-void Configurator::checkCommandLineParamFormat(const string& key, bool gotBool)
- throw(ConfigurationException)
-{
- if (options.find(key) != options.end() &&
- options[key].validator->isBool() != gotBool) {
- string message = "Option '" + key + "' should ";
- if (gotBool)
- message += "not ";
- message += "be a boolean.";
-
- throw ConfigurationException(message.c_str());
- }
-}
-
-
-void Configurator::dumpToGoogleLog()
-{
- LOG(INFO) << "Dumping configuration options:";
- const map<string, string>& params = conf.getMap();
- foreachpair (const string& key, const string& val, params) {
- LOG(INFO) << " " << key << " = " << val;
- }
- LOG(INFO) << "End configuration dump";
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/configurator/configurator.hpp
----------------------------------------------------------------------
diff --git a/src/configurator/configurator.hpp b/src/configurator/configurator.hpp
deleted file mode 100644
index 8449e05..0000000
--- a/src/configurator/configurator.hpp
+++ /dev/null
@@ -1,385 +0,0 @@
-/**
- * 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 __CONFIGURATOR_HPP__
-#define __CONFIGURATOR_HPP__
-
-#include <algorithm>
-#include <map>
-#include <string>
-
-#include <glog/logging.h>
-
-#include "configurator/configuration.hpp"
-#include "configurator/option.hpp"
-
-#include "flags/flag.hpp"
-#include "flags/flags.hpp"
-
-namespace mesos {
-namespace internal {
-
-/**
- * Exception type thrown by Configurator.
- */
-struct ConfigurationException : std::exception
-{
- ConfigurationException(const std::string& _message) : message(_message) {}
- ~ConfigurationException() throw () {}
- const char* what() const throw () { return message.c_str(); }
- const std::string message;
-};
-
-
-/**
- * This class populates a Configuration object, which can be retrieved
- * with getConfiguration(), by reading variables from the command
- * line, a config file or the environment.
- *
- * It currently supports 3 input types:
- * (i) Environment variables. It adds all variables starting with MESOS_.
- * (ii) Command line variables. Supports "--key=val" "-key val" "-opt" "--opt"
- * (iii) Config file. It ignores comments "#". It finds the file mesos.conf
- * in the directory specified by the "conf" option.
- **/
-class Configurator
-{
-public:
- static const char* DEFAULT_CONFIG_DIR;
- static const char* CONFIG_FILE_NAME;
- static const char* ENV_VAR_PREFIX;
-
-private:
- Configuration conf;
- std::map<std::string, ConfigOption> options;
-
-public:
-
- /**
- * Initializes a Configurator with no options set and only the "conf"
- * option registered.
- **/
- Configurator()
- {
- addOption<std::string>("conf",
- "Specifies a config directory from which to\n"
- "read Mesos config files.");
- }
-
- /**
- * Initializes a Configurator out of a Flags.
- **/
- template <typename Flags>
- Configurator(const Flags& flags)
- {
- addOption<std::string>("conf",
- "Specifies a config directory from which to\n"
- "read Mesos config files.");
-
- foreachvalue (const flags::Flag& flag, flags) {
- if (!flag.boolean) {
- addOption<std::string>(flag.name, flag.help);
- } else {
- addOption<bool>(flag.name, flag.help);
- }
- }
- }
-
-
- /**
- * Returns the Configuration object parsed by this Configurator.
- * @return Configuration populated configuration object
- **/
- Configuration& getConfiguration();
-
-
- /**
- * Returns a usage string with all registered options
- * @see addOption()
- * @return usage string
- **/
- std::string getUsage() const;
-
-
-private:
- /**
- * Private method for adding an option with, potentially, a default
- * value and a short name.
- * @param optName name of the option, e.g. "home"
- * @param helpString description of the option, may contain line breaks
- * @param hasShortName whether the option has a short name
- * @param shortName character representing short name of option, e.g. 'h'
- * @param hasDefault whether the option has a default value
- * @param defaultValue default value of the option, as a string.
- * The default option is put in the internal conf,
- * unless the option already has a value in conf.
- **/
- template <class T>
- void addOption(const std::string& optName,
- const std::string& helpString,
- bool hasShortName,
- char shortName,
- bool hasDefault,
- const std::string& defaultValue)
- {
- std::string name = optName;
- std::transform(name.begin(), name.end(), name.begin(), ::tolower);
- if (options.find(name) != options.end()) {
- std::string message = "Duplicate option registration: " + name;
- throw ConfigurationException(message.c_str());
- }
- options[name] = ConfigOption(helpString,
- Validator<T>(),
- hasShortName,
- shortName,
- hasDefault,
- defaultValue);
- }
-
-public:
- /**
- * Adds a registered option together with a help string.
- * @param optName name of the option, e.g. "home"
- * @param helpString description of the option, may contain line breaks
- **/
- template <class T>
- void addOption(const std::string& optName, const std::string& helpString)
- {
- addOption<T>(optName, helpString, false, '\0', false, "");
- }
-
- /**
- * Adds a registered option with a short name and help string.
- * @param optName name of the option, e.g. "home"
- * @param shortName character representing short name of option, e.g. 'h'
- * @param helpString description of the option, may contain line breaks
- **/
- template <class T>
- void addOption(const std::string& optName,
- char shortName,
- const std::string& helpString)
- {
- addOption<T>(optName, helpString, true, shortName, false, "");
- }
-
- /**
- * Adds a registered option with a default value and a help string.
- * @param optName name of the option, e.g. "home"
- * @param helpString description of the option, may contain line breaks
- * @param defaultValue default value of option.
- * The default option is put in the internal conf,
- * unless the option already has a value in conf.
- * Its type must support operator<<(ostream,...)
- **/
- template <class T>
- void addOption(const std::string& optName,
- const std::string& helpString,
- const T& defaultValue)
- {
- std::string defaultStr = boost::lexical_cast<std::string>(defaultValue);
- addOption<T>(optName, helpString, false, '\0', true, defaultStr);
- }
-
- /**
- * Adds a registered option with a default value, short name and help string.
- * @param optName name of the option, e.g. "home"
- * @param helpString description of the option, may contain line breaks
- * @param defaultValue default value of option.
- * The default option is put in the internal conf,
- * unless the option already has a value in conf.
- * Its type must support operator<<(ostream,...)
- **/
- template <class T>
- void addOption(const std::string& optName,
- char shortName,
- const std::string& helpString,
- const T& defaultValue)
- {
- std::string defaultStr = boost::lexical_cast<std::string>(defaultValue);
- addOption<T>(optName, helpString, true, shortName, true, defaultStr);
- }
-
- /**
- * Returns the names of all registered options.
- * @return name of every registered option
- **/
- std::vector<std::string> getOptions() const;
-
-
- /**
- * Validates the values of all keys that it has a default option for.
- * @throws ConfigurationError if a key has the wrong type.
- **/
- void validate();
-
-
- /**
- * Populates its internal Configuration with key/value parameters
- * from environment, command line, and config file.
- *
- * <i>Environment:</i><br>
- * Parses the environment variables and populates a Configuration.
- * It picks all environment variables that start with MESOS_.
- * The environment var MESOS_FOO=/dir would lead to key=foo val=/dir<br>
- *
- * <i>Command line:</i><br>
- * It extracts four type of command line parameters:
- * "--key=val", "-key val", "--key", "-key". The two last cases will
- * have default value "1" in the Configuration. <br>
- *
- * <i>Config file:</i><br>
- * The config file should contain key=value pairs, one per line.
- * Comments, which should start with #, are ignored.
- *
- * @param argc is the number of parameters in argv
- * @param argv is an array of c-strings containing parameters
- * @return the loaded Configuration object
- **/
- Configuration& load(int argc, char** argv);
-
-
- /**
- * Populates its internal Configuration with key/value parameters
- * from environment, and config file.
- *
- * <i>Environment:</i><br>
- * Parses the environment variables and populates a Configuration.
- * It picks all environment variables that start with MESOS_.
- * The environment var MESOS_FOO=/dir would lead to key=foo val=/dir <br>
- *
- * <i>Config file:</i><br>
- * The config file should contain key=value pairs, one per line.
- * Comments, which should start with #, are ignored.
- *
- * @return the loaded Configuration object
- **/
- Configuration& load();
-
-
- /**
- * Populates its internal Configuration with key/value parameters
- * from environment, a provided map, and config file.
- *
- * <i>Environment:</i><br>
- * Parses the environment variables and populates a Configuration.
- * It picks all environment variables that start with MESOS_.
- * The environment var MESOS_FOO=/dir would lead to key=foo val=/dir <br>
- *
- * <i>Map:</i><br>
- * Containing a string to string map. <br>
- *
- * <i>Config file:</i><br>
- * The config file should contain key=value pairs, one per line.
- * Comments, which should start with #, are ignored.
- *
- * @param params map containing key value pairs to be loaded
- * @return the loaded Configuration object
- **/
- Configuration& load(const std::map<std::string, std::string>& params);
-
- /**
- * Clears all Mesos environment variables (useful for tests).
- */
- static void clearMesosEnvironmentVars();
-
-private:
- /**
- * Parses the environment variables and populates a Configuration.
- * It picks all environment variables that start with MESOS_.
- * The environment variable MESOS_FOO=/dir would lead to key=foo val=/dir
- * @param overwrite whether to overwrite keys that already have values
- * in the internal params (true by default)
- **/
- void loadEnv(bool overwrite = true);
-
- /**
- * Populates its internal Configuration with key/value parameters
- * from command line.
- *
- * It extracts four type of command line parameters:
- * "--key=val", "-key val", "--key", "-key". The two last cases will
- * have default value "1" in the Params.
- *
- * @param argc is the number of parameters in argv
- * @param argv is an array of c-strings containing parameters
- * @param overwrite whether to overwrite keys that already have values
- * in the internal params (true by default)
- **/
- void loadCommandLine(int argc,
- char** argv,
- bool overwrite = true);
-
- /**
- * Populates its internal Configuration with key/value parameters
- * from a config file.
- *
- * Values in the config file DO NOT override values already loaded into
- * conf (i.e. having been defined in the environment or command line), as
- * is typically expected for programs that allow configuration both ways.
- *
- * The config file should contain key=value pairs, one per line.
- * Comments, which should start with #, are ignored.
- *
- * @param fname is the name of the config file to open
- * @param overwrite whether to overwrite keys that already have values
- * in the internal params (false by default)
- **/
- void loadConfigFile(const std::string& fname, bool overwrite = false);
-
- /**
- * Load the config file set through the command line or environment, if any.
- * @param overwrite whether to overwrite keys that already have values
- * in the internal params (false by default)
- */
- void loadConfigFileIfGiven(bool overwrite = false);
-
- /**
- * Load default values of options whose values have not already been set.
- */
- void loadDefaults();
-
- /**
- * Gets the first long name option associated with the provided short name.
- * @param shortName character representing the short name of the option
- * @return first long name option matching the short name, "" if none found.
- */
- std::string getLongName(char shortName) const;
-
- /**
- * Check whether a command-line flag is valid, based on whether it was
- * passed in boolean form (--flag or --no-flag) versus key-value form
- * (--flag=value). We test whether this option was actually registered
- * as a bool (or non-bool), and throw an error if it is passed in
- * the wrong format.
- *
- * @param key the option name parsed from the flag (without --no)
- * @param gotBool whether the option was passed as a bool
- */
- void checkCommandLineParamFormat(const std::string& key, bool gotBool)
- throw(ConfigurationException);
-
- /**
- * Dump the values of all config options to Google Log
- */
- void dumpToGoogleLog();
-};
-
-} // namespace internal {
-} // namespace mesos {
-
-#endif // __CONFIGURATOR_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/configurator/get_conf.cpp
----------------------------------------------------------------------
diff --git a/src/configurator/get_conf.cpp b/src/configurator/get_conf.cpp
deleted file mode 100644
index aa2bb7b..0000000
--- a/src/configurator/get_conf.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 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 <iostream>
-#include <string>
-
-#include "configurator.hpp"
-
-using namespace mesos::internal;
-
-using std::cout;
-using std::string;
-
-
-int main(int argc, char** argv)
-{
- if (argc == 1) {
- cout << "Usage: mesos-getconf OPTION [arg1 arg2 ... ]\n\n";
- cout << "OPTION\t\tis the name option whose value is to be extracted\n";
- cout << "arg1 ...\tOptional arguments passed to mesos, e.g. --quiet\n\n";
- cout << "This utility gives shell scripts access to Mesos parameters.\n\n";
- return 1;
- }
-
- Configurator configurator;
- configurator.load(argc, argv, true);
-
- string param(argv[1]);
- transform(param.begin(), param.end(), param.begin(), tolower);
-
- Configuration conf = configurator.getConfiguration();
- if (conf.contains(param)) {
- cout << conf[param] << "\n";
- }
-
- return 0;
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/configurator/option.hpp
----------------------------------------------------------------------
diff --git a/src/configurator/option.hpp b/src/configurator/option.hpp
deleted file mode 100644
index fc79491..0000000
--- a/src/configurator/option.hpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * 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 __CONFIGURATOR_OPTION_HPP__
-#define __CONFIGURATOR_OPTION_HPP__
-
-#include <string>
-
-
-namespace mesos { namespace internal {
-
-
-/**
- * Interface of a validator
- **/
-class ValidatorBase {
-public:
- virtual ValidatorBase* clone() const = 0;
- virtual bool isBool() const = 0;
- /**
- * Checks if the provided string can be cast to a T.
- * @param val value associated with some option
- * @return true if val can be cast to a T, otherwise false.
- **/
- virtual bool isValid(const std::string& val) const = 0;
-
- virtual ~ValidatorBase() {}
-
-protected:
- template <class T>
- bool isValidInternal(const std::string& val) const
- {
- try {
- boost::lexical_cast<T>(val);
- }
- catch(const boost::bad_lexical_cast& ex) {
- return false;
- }
- return true;
- }
-};
-
-
-/**
- * Validator that checks if a string can be cast to its templated type.
- **/
-template <typename T>
-class Validator : public ValidatorBase {
-public:
- virtual bool isValid(const std::string& val) const {
- return isValidInternal<T>(val);
- }
-
- virtual bool isBool() const { return false; }
-
- virtual ValidatorBase* clone() const {
- return new Validator<T>();
- }
-};
-
-
-/**
- * Validator for bools that checks if a string can be cast to its templated type.
- **/
-template <>
-class Validator <bool> : public ValidatorBase {
-public:
- bool isValid(const std::string& val) const {
- return isValidInternal<bool>(val);
- }
-
- bool isBool() const { return true; }
-
- ValidatorBase* clone() const {
- return new Validator<bool>();
- }
-};
-
-
-/**
- * Registered option with help string and default value
- **/
-class ConfigOption {
-public:
- ConfigOption() : hasDefault(false), validator(NULL) {}
-
- ConfigOption(const std::string& _helpString,
- const ValidatorBase& _validator,
- bool _hasShortName,
- char _shortName,
- bool _hasDefault,
- const std::string& _defaultValue)
- : helpString(_helpString),
- hasDefault(_hasDefault),
- defaultValue(_defaultValue),
- hasShortName(_hasShortName),
- shortName(_shortName)
- {
- validator = _validator.clone();
- }
-
- ConfigOption(const ConfigOption& opt)
- : helpString(opt.helpString),
- hasDefault(opt.hasDefault),
- defaultValue(opt.defaultValue),
- hasShortName(opt.hasShortName),
- shortName(opt.shortName)
- {
- validator = (opt.validator == NULL) ? NULL : opt.validator->clone();
- }
-
- ConfigOption &operator=(const ConfigOption& opt)
- {
- helpString = opt.helpString;
- hasDefault = opt.hasDefault;
- hasShortName = opt.hasShortName;
- shortName = opt.shortName;
- defaultValue = opt.defaultValue;
- validator = opt.validator == NULL ? NULL : opt.validator->clone();
- return *this;
- }
-
- ~ConfigOption()
- {
- if (validator != 0) delete validator;
- }
-
- std::string helpString;
- bool hasDefault;
- std::string defaultValue;
- bool hasShortName;
- char shortName;
- ValidatorBase *validator;
-};
-
-} } // end mesos :: internal namespace
-
-#endif // __CONFIGURATOR_OPTION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/examples/test_framework.cpp
----------------------------------------------------------------------
diff --git a/src/examples/test_framework.cpp b/src/examples/test_framework.cpp
index b3608ba..2c46c24 100644
--- a/src/examples/test_framework.cpp
+++ b/src/examples/test_framework.cpp
@@ -154,7 +154,10 @@ public:
const SlaveID& slaveID,
int status) {}
- virtual void error(SchedulerDriver* driver, const string& message) {}
+ virtual void error(SchedulerDriver* driver, const string& message)
+ {
+ cout << message << endl;
+ }
private:
const ExecutorInfo executor;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/flags/flag.hpp
----------------------------------------------------------------------
diff --git a/src/flags/flag.hpp b/src/flags/flag.hpp
deleted file mode 100644
index 46509f7..0000000
--- a/src/flags/flag.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __FLAGS_FLAG_HPP__
-#define __FLAGS_FLAG_HPP__
-
-#include <string>
-
-#include <tr1/functional>
-
-namespace flags {
-
-// Forward declaration.
-class FlagsBase;
-
-struct Flag
-{
- std::string name;
- std::string help;
- bool boolean;
- std::tr1::function<void(FlagsBase*, const std::string&)> loader;
-};
-
-} // namespace flags {
-
-#endif // __FLAGS_FLAG_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/src/flags/flags.hpp b/src/flags/flags.hpp
deleted file mode 100644
index 5a9c30c..0000000
--- a/src/flags/flags.hpp
+++ /dev/null
@@ -1,344 +0,0 @@
-#ifndef __FLAGS_FLAGS_HPP__
-#define __FLAGS_FLAGS_HPP__
-
-#include <stdlib.h> // For abort.
-
-#include <map>
-#include <string>
-#include <typeinfo> // For typeid.
-
-#include <tr1/functional>
-
-#include <stout/option.hpp>
-#include <stout/stringify.hpp>
-#include <stout/try.hpp>
-
-#include "flags/flag.hpp"
-#include "flags/loader.hpp"
-#include "flags/parse.hpp"
-
-// An abstraction for application/library "flags". An example is
-// probably best:
-// -------------------------------------------------------------
-// class MyFlags : public virtual FlagsBase // Use 'virtual' for composition!
-// {
-// public:
-// Flags()
-// {
-// add(&debug,
-// "debug",
-// "Help string for debug",
-// false);
-//
-// add(&name,
-// "name",
-// "Help string for name");
-// }
-
-// bool debug;
-// Option<string> name;
-// };
-//
-// ...
-//
-// map<string, Option<string> > values;
-// values["no-debug"] = None(); // --no-debug
-// values["debug"] = None(); // --debug
-// values["debug"] = Option<string>::some("true"); // --debug=true
-// values["debug"] = Option<string>::some("false"); // --debug=false
-// values["name"] = Option<string>::some("frank"); // --name=frank
-//
-// MyFlags flags;
-// flags.load(values);
-// flags.name.isSome() ...
-// flags.debug ...
-// -------------------------------------------------------------
-//
-// You can also compose flags provided that each has used "virtual
-// inheritance":
-// -------------------------------------------------------------
-// Flags<MyFlags1, MyFlags2> flags;
-// flags.add(...); // Any other flags you want to throw in there.
-// flags.load(values);
-// flags.flag_from_myflags1 ...
-// flags.flag_from_myflags2 ...
-// -------------------------------------------------------------
-//
-// "Fail early, fail often":
-//
-// You can not add duplicate flags, this is checked for you at compile
-// time for composite flags (e.g., Flag<MyFlags1, MyFlags2>) and also
-// checked at runtime for any other flags added via inheritance or
-// Flags::add(...).
-//
-// Flags that can not be loaded (e.g., attempting to use the 'no-'
-// prefix for a flag that is not boolean) will print a message to
-// standard error and abort the process.
-
-// TODO(benh): Provide a boolean which specifies whether or not to
-// abort on duplicates or load errors.
-
-// TODO(benh): Make prefix for environment variables configurable
-// (e.g., "MESOS_").
-
-namespace flags {
-
-class FlagsBase
-{
-public:
- virtual ~FlagsBase() {}
- virtual void load(const std::map<std::string, Option<std::string> >& values);
- virtual void load(const std::map<std::string, std::string>& values);
-
- typedef std::map<std::string, Flag>::const_iterator const_iterator;
-
- const_iterator begin() const { return flags.begin(); }
- const_iterator end() const { return flags.end(); }
-
- template <typename T1, typename T2>
- void add(T1* t1,
- const std::string& name,
- const std::string& help,
- const T2& t2);
-
- template <typename T>
- void add(Option<T>* option,
- const std::string& name,
- const std::string& help);
-
-protected:
- template <typename Flags, typename T1, typename T2>
- void add(T1 Flags::*t1,
- const std::string& name,
- const std::string& help,
- const T2& t2);
-
- template <typename Flags, typename T>
- void add(Option<T> Flags::*option,
- const std::string& name,
- const std::string& help);
-
- void add(const Flag& flag);
-
-private:
- std::map<std::string, Flag> flags;
-};
-
-
-// Need to declare/define some explicit subclasses of FlagsBase so
-// that we can overload the 'Flags::operator FlagsN () const'
-// functions for each possible type.
-class _Flags1 : public virtual FlagsBase {};
-class _Flags2 : public virtual FlagsBase {};
-class _Flags3 : public virtual FlagsBase {};
-class _Flags4 : public virtual FlagsBase {};
-class _Flags5 : public virtual FlagsBase {};
-
-
-// TODO(benh): Add some "type constraints" for template paramters to
-// make sure they are all of type FlagsBase.
-template <typename Flags1 = _Flags1,
- typename Flags2 = _Flags2,
- typename Flags3 = _Flags3,
- typename Flags4 = _Flags4,
- typename Flags5 = _Flags5>
-class Flags : public virtual Flags1,
- public virtual Flags2,
- public virtual Flags3,
- public virtual Flags4,
- public virtual Flags5 {};
-
-
-template <typename T1, typename T2>
-void FlagsBase::add(
- T1* t1,
- const std::string& name,
- const std::string& help,
- const T2& t2)
-{
- *t1 = t2; // Set the default.
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T1) == typeid(bool);
- flag.loader = std::tr1::bind(
- &Loader<T1>::load,
- t1,
- std::tr1::function<Try<T1>(const std::string&)>(
- std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
-
- // Update the help string to include the default value.
- flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
- ? " (default: " // On same line, add space.
- : "(default: "; // On newline.
- flag.help += stringify(t2);
- flag.help += ")";
-
- FlagsBase::add(flag);
-}
-
-
-template <typename T>
-void FlagsBase::add(
- Option<T>* option,
- const std::string& name,
- const std::string& help)
-{
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T) == typeid(bool);
- flag.loader = std::tr1::bind(
- &OptionLoader<T>::load,
- option,
- std::tr1::function<Try<T>(const std::string&)>(
- std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
-
- FlagsBase::add(flag);
-}
-
-
-template <typename Flags, typename T1, typename T2>
-void FlagsBase::add(
- T1 Flags::*t1,
- const std::string& name,
- const std::string& help,
- const T2& t2)
-{
- Flags* flags = dynamic_cast<Flags*>(this);
- if (flags == NULL) {
- std::cerr << "Attempted to add flag '" << name
- << "' with incompatible type" << std::endl;
- abort();
- } else {
- flags->*t1 = t2; // Set the default.
- }
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T1) == typeid(bool);
- flag.loader = std::tr1::bind(
- &MemberLoader<Flags, T1>::load,
- std::tr1::placeholders::_1,
- t1,
- std::tr1::function<Try<T1>(const std::string&)>(
- std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2);
-
- // Update the help string to include the default value.
- flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
- ? " (default: " // On same line, add space.
- : "(default: "; // On newline.
- flag.help += stringify(t2);
- flag.help += ")";
-
- flag.help += ")";
-
- add(flag);
-}
-
-
-template <typename Flags, typename T>
-void FlagsBase::add(
- Option<T> Flags::*option,
- const std::string& name,
- const std::string& help)
-{
- Flags* flags = dynamic_cast<Flags*>(this);
- if (flags == NULL) {
- std::cerr << "Attempted to add flag '" << name
- << "' with incompatible type" << std::endl;
- abort();
- }
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T) == typeid(bool);
- flag.loader = std::tr1::bind(
- &OptionMemberLoader<Flags, T>::load,
- std::tr1::placeholders::_1,
- option,
- std::tr1::function<Try<T>(const std::string&)>(
- std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2);
-
- add(flag);
-}
-
-
-inline void FlagsBase::add(const Flag& flag)
-{
- if (flags.count(flag.name) > 0) {
- std::cerr << "Attempted to add duplicate flag '"
- << flag.name << "'" << std::endl;
- abort();
- }
-
- flags[flag.name] = flag;
-}
-
-
-inline void FlagsBase::load(const std::map<std::string, Option<std::string> >& values)
-{
- std::map<std::string, Option<std::string> >::const_iterator iterator;
-
- for (iterator = values.begin(); iterator != values.end(); ++iterator) {
- const std::string& name = iterator->first;
- const Option<std::string>& value = iterator->second;
-
- if (flags.count(name) > 0) {
- if (value.isSome()) {
- flags[name].loader(this, value.get()); // --name=value
- } else if (flags[name].boolean) {
- flags[name].loader(this, "true"); // --name
- } else {
- std::cerr << "Failed to load non-boolean flag via '"
- << name << "'" << std::endl;
- abort();
- }
- } else if (name.find("no-") == 0 && flags.count(name.substr(3)) > 0) {
- if (flags[name.substr(3)].boolean) {
- if (value.isNone()) {
- flags[name.substr(3)].loader(this, "false"); // --no-name
- } else {
- std::cerr << "Failed to load boolean flag '"
- << name.substr(3) << "' via '" << name
- << "' with value '" << value.get()
- << "'" << std::endl;
- abort();
- }
- } else {
- std::cerr << "Failed to load non-boolean flag '"
- << name.substr(3) << "' via '"
- << name << "'" << std::endl;
- abort();
- }
- }
- }
-}
-
-
-inline void FlagsBase::load(const std::map<std::string, std::string>& _values)
-{
- std::map<std::string, Option<std::string> > values;
- std::map<std::string, std::string>::const_iterator iterator;
- for (iterator = _values.begin(); iterator != _values.end(); ++iterator) {
- const std::string& name = iterator->first;
- const std::string& value = iterator->second;
- values[name] = Option<std::string>::some(value);
- }
- load(values);
-}
-
-} // namespace flags {
-
-#endif // __FLAGS_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/flags/loader.hpp
----------------------------------------------------------------------
diff --git a/src/flags/loader.hpp b/src/flags/loader.hpp
deleted file mode 100644
index 2226172..0000000
--- a/src/flags/loader.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef __FLAGS_LOADER_HPP__
-#define __FLAGS_LOADER_HPP__
-
-#include <string>
-
-#include <tr1/functional>
-
-#include <stout/option.hpp>
-#include <stout/try.hpp>
-
-namespace flags {
-
-// Forward declaration.
-class FlagsBase;
-
-template <typename T>
-struct Loader
-{
- static void load(T* flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- Try<T> t = parse(value);
- if (t.isSome()) {
- *flag = t.get();
- } else {
- std::cerr << "Failed to load value '" << value
- << "' for flag '" << name
- << "': " << t.error() << std::endl;
- abort();
- }
- }
-};
-
-
-template <typename T>
-struct OptionLoader
-{
- static void load(Option<T>* flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- Try<T> t = parse(value);
- if (t.isSome()) {
- *flag = Option<T>::some(t.get());
- } else {
- std::cerr << "Failed to load value '" << value
- << "' for flag '" << name
- << "': " << t.error() << std::endl;
- abort();
- }
- }
-};
-
-
-template <typename F, typename T>
-struct MemberLoader
-{
- static void load(FlagsBase* base,
- T F::*flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- F* f = dynamic_cast<F*>(base);
- if (f != NULL) {
- Try<T> t = parse(value);
- if (t.isSome()) {
- f->*flag = t.get();
- } else {
- std::cerr << "Failed to load value '" << value
- << "' for flag '" << name
- << "': " << t.error() << std::endl;
- abort();
- }
- }
- }
-};
-
-
-template <typename F, typename T>
-struct OptionMemberLoader
-{
- static void load(FlagsBase* base,
- Option<T> F::*flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- F* f = dynamic_cast<F*>(base);
- if (f != NULL) {
- Try<T> t = parse(value);
- if (t.isSome()) {
- f->*flag = Option<T>::some(t.get());
- } else {
- std::cerr << "Failed to load value '" << value
- << "' for flag '" << name
- << "': " << t.error() << std::endl;
- abort();
- }
- }
- }
-};
-
-} // namespace flags {
-
-#endif // __FLAGS_LOADER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/flags/parse.hpp
----------------------------------------------------------------------
diff --git a/src/flags/parse.hpp b/src/flags/parse.hpp
deleted file mode 100644
index 88923fe..0000000
--- a/src/flags/parse.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __FLAGS_PARSE_HPP__
-#define __FLAGS_PARSE_HPP__
-
-#include <sstream> // For istringstream.
-#include <string>
-
-#include <tr1/functional>
-
-#include <stout/duration.hpp>
-#include <stout/error.hpp>
-#include <stout/try.hpp>
-
-namespace flags {
-
-template <typename T>
-Try<T> parse(const std::string& value)
-{
- T t;
- std::istringstream in(value);
- in >> t;
- if (!in.good() && !in.eof()) {
- return Error("Failed to convert into required type");
- }
- return t;
-}
-
-
-template <>
-inline Try<std::string> parse(const std::string& value)
-{
- return value;
-}
-
-
-template <>
-inline Try<bool> parse(const std::string& value)
-{
- if (value == "true" || value == "1") {
- return true;
- } else if (value == "false" || value == "0") {
- return false;
- }
- return Error("Expecting a boolean (e.g., true or false)");
-}
-
-
-template <>
-inline Try<Duration> parse(const std::string& value)
-{
- return Duration::parse(value);
-}
-
-} // namespace flags {
-
-#endif // __FLAGS_PARSE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/local/flags.hpp
----------------------------------------------------------------------
diff --git a/src/local/flags.hpp b/src/local/flags.hpp
index 75cd15a..54e8831 100644
--- a/src/local/flags.hpp
+++ b/src/local/flags.hpp
@@ -19,13 +19,15 @@
#ifndef __LOCAL_FLAGS_HPP__
#define __LOCAL_FLAGS_HPP__
-#include "flags/flags.hpp"
+#include <stout/flags.hpp>
+
+#include "logging/flags.hpp"
namespace mesos {
namespace internal {
namespace local {
-class Flags : public virtual flags::FlagsBase
+class Flags : public logging::Flags
{
public:
Flags()
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/local/local.cpp
----------------------------------------------------------------------
diff --git a/src/local/local.cpp b/src/local/local.cpp
index eb33e5d..c35c19a 100644
--- a/src/local/local.cpp
+++ b/src/local/local.cpp
@@ -25,9 +25,6 @@
#include "local.hpp"
-#include "configurator/configuration.hpp"
-#include "configurator/configurator.hpp"
-
#include "detector/detector.hpp"
#include "logging/flags.hpp"
@@ -74,10 +71,8 @@ static MasterDetector* detector = NULL;
static Files* files = NULL;
-PID<Master> launch(const Configuration& configuration, Allocator* _allocator)
+PID<Master> launch(const Flags& flags, Allocator* _allocator)
{
- int numSlaves = configuration.get<int>("num_slaves", 1);
-
if (master != NULL) {
LOG(FATAL) << "Can only launch one local cluster at a time (for now)";
}
@@ -97,7 +92,11 @@ PID<Master> launch(const Configuration& configuration, Allocator* _allocator)
{
master::Flags flags;
- flags.load(configuration.getMap());
+ Try<Nothing> load = flags.load("MESOS_", true); // Allow unknown flags.
+ if (load.isError()) {
+ EXIT(1) << "Failed to start a local cluster while loading "
+ << "master flags from the environment: " << load.error();
+ }
master = new Master(_allocator, files, flags);
}
@@ -105,13 +104,17 @@ PID<Master> launch(const Configuration& configuration, Allocator* _allocator)
vector<UPID> pids;
- slave::Flags flags;
- flags.load(configuration.getMap());
-
- for (int i = 0; i < numSlaves; i++) {
+ for (int i = 0; i < flags.num_slaves; i++) {
// TODO(benh): Create a local isolator?
ProcessIsolator* isolator = new ProcessIsolator();
+ slave::Flags flags;
+ Try<Nothing> load = flags.load("MESOS_", true); // Allow unknown flags.
+ if (load.isError()) {
+ EXIT(1) << "Failed to start a local cluster while loading "
+ << "slave flags from the environment: " << load.error();
+ }
+
// Use a different work directory for each slave.
flags.work_dir = path::join(flags.work_dir, stringify(i));
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/local/local.hpp
----------------------------------------------------------------------
diff --git a/src/local/local.hpp b/src/local/local.hpp
index 51324e2..a165265 100644
--- a/src/local/local.hpp
+++ b/src/local/local.hpp
@@ -21,6 +21,8 @@
#include <process/process.hpp>
+#include "local/flags.hpp"
+
namespace mesos {
namespace internal {
@@ -36,9 +38,9 @@ class Configuration;
namespace local {
-// Launch a local cluster with a given configuration.
+// Launch a local cluster with the given flags.
process::PID<master::Master> launch(
- const Configuration& configuration,
+ const Flags& flags,
master::Allocator* _allocator = NULL);
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/local/main.cpp
----------------------------------------------------------------------
diff --git a/src/local/main.cpp b/src/local/main.cpp
index d2e632a..5995c53 100644
--- a/src/local/main.cpp
+++ b/src/local/main.cpp
@@ -22,8 +22,6 @@
#include <stout/os.hpp>
#include <stout/stringify.hpp>
-#include "configurator/configurator.hpp"
-
#include "detector/detector.hpp"
#include "local/flags.hpp"
@@ -45,14 +43,14 @@ using std::endl;
using std::string;
-void usage(const char* argv0, const Configurator& configurator)
+void usage(const char* argv0, const flags::FlagsBase& flags)
{
cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
<< endl
- << "Launches a cluster within a single OS process."
+ << "Launches an in-memory cluster within a single process."
<< endl
<< "Supported options:" << endl
- << configurator.getUsage();
+ << flags.usage();
}
@@ -60,7 +58,11 @@ int main(int argc, char **argv)
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
- flags::Flags<logging::Flags, local::Flags> flags;
+ // TODO(benh): Inherit from both slave::Flags and master::Flags in
+ // order to pass those flags on to the master. Alternatively, add a
+ // way to load flags and ignore unknowns in order to load
+ // master::flags, then slave::Flags, then local::Flags.
+ local::Flags flags;
// The following flags are executable specific (e.g., since we only
// have one instance of libprocess per execution, we only want to
@@ -77,20 +79,18 @@ int main(int argc, char **argv)
"Prints this help message",
false);
- Configurator configurator(flags);
- Configuration configuration;
- try {
- configuration = configurator.load(argc, argv);
- } catch (ConfigurationException& e) {
- cerr << "Configuration error: " << e.what() << endl;
- usage(argv[0], configurator);
+ // Load flags from environment and command line but allow unknown
+ // flags since we might have some master/slave flags as well.
+ Try<Nothing> load = flags.load("MESOS_", argc, argv, true);
+
+ if (load.isError()) {
+ cerr << load.error() << endl;
+ usage(argv[0], flags);
exit(1);
}
- flags.load(configuration.getMap());
-
if (help) {
- usage(argv[0], configurator);
+ usage(argv[0], flags);
exit(1);
}
@@ -105,7 +105,7 @@ int main(int argc, char **argv)
logging::initialize(argv[0], flags);
- process::wait(local::launch(configuration));
+ process::wait(local::launch(flags));
return 0;
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/log/main.cpp
----------------------------------------------------------------------
diff --git a/src/log/main.cpp b/src/log/main.cpp
index 24b9d8b..18a1b23 100644
--- a/src/log/main.cpp
+++ b/src/log/main.cpp
@@ -22,15 +22,12 @@
#include <process/process.hpp>
+#include <stout/flags.hpp>
#include <stout/foreach.hpp>
+#include <stout/none.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
-#include "configurator/configurator.hpp"
-#include "configurator/configuration.hpp"
-
-#include "flags/flags.hpp"
-
#include "log/replica.hpp"
#include "logging/flags.hpp"
@@ -46,12 +43,12 @@ using std::endl;
using std::string;
-void usage(const char* argv0, const Configurator& configurator)
+void usage(const char* argv0, const flags::FlagsBase& flags)
{
cerr << "Usage: " << os::basename(argv0).get() << " [...] path/to/log"
<< endl
<< "Supported options:" << endl
- << configurator.getUsage();
+ << flags.usage();
}
@@ -75,20 +72,16 @@ int main(int argc, char** argv)
"Prints this help message",
false);
- Configurator configurator(flags);
- Configuration configuration;
- try {
- configuration = configurator.load(argc, argv);
- } catch (ConfigurationException& e) {
- cerr << "Configuration error: " << e.what() << endl;
- usage(argv[0], configurator);
+ Try<Nothing> load = flags.load(None(), argc, argv);
+
+ if (load.isError()) {
+ cerr << load.error() << endl;
+ usage(argv[0], flags);
exit(1);
}
- flags.load(configuration.getMap());
-
if (help) {
- usage(argv[0], configurator);
+ usage(argv[0], flags);
exit(1);
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/logging/flags.hpp
----------------------------------------------------------------------
diff --git a/src/logging/flags.hpp b/src/logging/flags.hpp
index 4a96316..e2e4afc 100644
--- a/src/logging/flags.hpp
+++ b/src/logging/flags.hpp
@@ -21,10 +21,9 @@
#include <string>
+#include <stout/flags.hpp>
#include <stout/option.hpp>
-#include "flags/flags.hpp"
-
namespace mesos {
namespace internal {
namespace logging {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/logging/logging.hpp
----------------------------------------------------------------------
diff --git a/src/logging/logging.hpp b/src/logging/logging.hpp
index 0e90ef1..56fbbd4 100644
--- a/src/logging/logging.hpp
+++ b/src/logging/logging.hpp
@@ -23,9 +23,6 @@
#include <glog/logging.h> // Includes LOG(*), PLOG(*), CHECK, etc.
-#include "configurator/configuration.hpp"
-#include "configurator/configurator.hpp"
-
#include "logging/check_some.hpp"
#include "logging/flags.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/master/flags.hpp
----------------------------------------------------------------------
diff --git a/src/master/flags.hpp b/src/master/flags.hpp
index 23154f3..f4ce8c1 100644
--- a/src/master/flags.hpp
+++ b/src/master/flags.hpp
@@ -22,8 +22,7 @@
#include <string>
#include <stout/duration.hpp>
-
-#include "flags/flags.hpp"
+#include <stout/flags.hpp>
#include "logging/flags.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/master/main.cpp
----------------------------------------------------------------------
diff --git a/src/master/main.cpp b/src/master/main.cpp
index 06c265a..79a912c 100644
--- a/src/master/main.cpp
+++ b/src/master/main.cpp
@@ -18,19 +18,16 @@
#include <mesos/mesos.hpp>
+#include <stout/flags.hpp>
+#include <stout/nothing.hpp>
#include <stout/os.hpp>
#include <stout/stringify.hpp>
#include <stout/try.hpp>
#include "common/build.hpp"
-#include "configurator/configuration.hpp"
-#include "configurator/configurator.hpp"
-
#include "detector/detector.hpp"
-#include "flags/flags.hpp"
-
#include "logging/flags.hpp"
#include "logging/logging.hpp"
@@ -49,12 +46,12 @@ using std::endl;
using std::string;
-void usage(const char* argv0, const Configurator& configurator)
+void usage(const char* argv0, const flags::FlagsBase& flags)
{
cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
<< endl
<< "Supported options:" << endl
- << configurator.getUsage();
+ << flags.usage();
}
@@ -89,20 +86,16 @@ int main(int argc, char** argv)
"Prints this help message",
false);
- Configurator configurator(flags);
- Configuration configuration;
- try {
- configuration = configurator.load(argc, argv);
- } catch (ConfigurationException& e) {
- cerr << "Configuration error: " << e.what() << endl;
- usage(argv[0], configurator);
+ Try<Nothing> load = flags.load("MESOS_", argc, argv);
+
+ if (load.isError()) {
+ cerr << load.error() << endl;
+ usage(argv[0], flags);
exit(1);
}
- flags.load(configuration.getMap());
-
if (help) {
- usage(argv[0], configurator);
+ usage(argv[0], flags);
exit(1);
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index 5ee7763..cbc40e1 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -36,8 +36,6 @@
#include "common/date_utils.hpp"
#include "common/protobuf_utils.hpp"
-#include "flags/flags.hpp"
-
#include "logging/flags.hpp"
#include "logging/logging.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 38d2a51..82e3596 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -41,10 +41,6 @@
#include "common/type_utils.hpp"
#include "common/units.hpp"
-#include "flags/flags.hpp"
-
-#include "logging/flags.hpp"
-
#include "files/files.hpp"
#include "master/constants.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/mesos/main.cpp
----------------------------------------------------------------------
diff --git a/src/mesos/main.cpp b/src/mesos/main.cpp
index e7d0837..f633ae1 100644
--- a/src/mesos/main.cpp
+++ b/src/mesos/main.cpp
@@ -1,109 +1,8 @@
-#include <process/process.hpp>
-#include <process/protobuf.hpp>
-
-#include <stout/os.hpp>
-
-#include "configurator/configurator.hpp"
-
-#include "messages/messages.hpp"
-
-using namespace mesos::internal;
-
-using namespace process;
-
-using std::cerr;
-using std::cout;
-using std::endl;
-using std::string;
-
-
-void usage(const char* argv0, const Configurator& configurator)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << configurator.getUsage();
-}
+#include <stout/exit.hpp>
int main(int argc, char** argv)
{
- GOOGLE_PROTOBUF_VERIFY_VERSION;
-
- Configurator configurator;
-
- // The following options are executable specific (e.g., since we
- // only have one instance of libprocess per execution, we only want
- // to advertise the port and ip option once, here).
- configurator.addOption<int>("port", 'p', "Port to listen on", 5050);
- configurator.addOption<string>("ip", "IP address to listen on");
- configurator.addOption<string>(
- "master",
- 'm',
- "May be one of:\n"
- " host:port\n"
- " zk://host1:port1,host2:port2,.../path\n"
- " zk://username:password@host1:port1,host2:port2,.../path\n"
- " file://path/to/file (where file contains one of the above)");
-
- if (argc == 2 && string("--help") == argv[1]) {
- usage(argv[0], configurator);
- exit(1);
- }
-
- Configuration conf;
- try {
- conf = configurator.load(argc, argv);
- } catch (const ConfigurationException& e) {
- cerr << "Configuration error: " << e.what() << endl;
- exit(1);
- }
-
- // Initialize libprocess.
- process::initialize();
-
- if (!conf.contains("master")) {
- cerr << "Missing required option --master (-m)" << endl;
- usage(argv[0], configurator);
- exit(1);
- }
-
- // TODO(vinod): Parse 'master' when we add ZooKeeper support.
- UPID master(conf["master"]);
-
- if (!master) {
- cerr << "Could not parse --master=" << conf["master"] << endl;
- usage(argv[0], configurator);
- exit(1);
- }
-
- if (!conf.contains("name")) {
- // TODO(benh): Need to add '--name' as an option.
- cerr << "Missing --name (-n)" << endl;
- usage(argv[0], configurator);
- exit(1);
- }
-
- LOG(INFO) << "Submitting scheduler ...";
-
- Protocol<SubmitSchedulerRequest, SubmitSchedulerResponse> submit;
-
- SubmitSchedulerRequest request;
- request.set_name(conf["name"]);
-
- Future<SubmitSchedulerResponse> future = submit(master, request);
-
- future.await(Seconds(5));
-
- if (future.isReady()) {
- if (future.get().okay()) {
- cout << "Scheduler submitted successfully" << endl;
- } else {
- cout << "Failed to submit scheduler" << endl;
- }
- } else {
- cout << "Timed out waiting for response from submitting scheduler" << endl;
- }
-
+ EXIT(1) << "Unimplemented";
return 0;
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/sched/sched.cpp
----------------------------------------------------------------------
diff --git a/src/sched/sched.cpp b/src/sched/sched.cpp
index e19251b..248e12e 100644
--- a/src/sched/sched.cpp
+++ b/src/sched/sched.cpp
@@ -40,21 +40,16 @@
#include <stout/duration.hpp>
#include <stout/error.hpp>
-#include <stout/fatal.hpp>
+#include <stout/flags.hpp>
#include <stout/hashmap.hpp>
#include <stout/os.hpp>
#include <stout/uuid.hpp>
-#include "configurator/configuration.hpp"
-#include "configurator/configurator.hpp"
-
#include "common/lock.hpp"
#include "common/type_utils.hpp"
#include "detector/detector.hpp"
-#include "flags/flags.hpp"
-
#include "local/local.hpp"
#include "logging/flags.hpp"
@@ -676,35 +671,26 @@ MesosSchedulerDriver::MesosSchedulerDriver(
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
- // Load the configuration. For now, we just load all key/value pairs
- // from the environment (and possibly a file if specified) but don't
- // actually do any validation on them (since we don't register any
- // options). Any "validation" necessary will be done when we load
- // the configuration into flags (i.e., below when we initialize
- // logging or inside of local::launch).
- Configurator configurator;
- Configuration configuration;
- try {
- configuration = configurator.load();
- } catch (ConfigurationException& e) {
+ // Load any flags from the environment (we use local::Flags in the
+ // event we run in 'local' mode, since it inherits
+ // logging::Flags). In the future, just as the TODO in
+ // local/main.cpp discusses, we'll probably want a way to load
+ // master::Flags and slave::Flags as well. For now, we need to allow
+ // unknown flags in the event there are flags for the master/slave
+ // in the environment.
+ local::Flags flags;
+
+ Try<Nothing> load = flags.load("MESOS_", true); // Allow unknown flags.
+
+ if (load.isError()) {
status = DRIVER_ABORTED;
- string message = string("Configuration error: ") + e.what();
- scheduler->error(this, message);
+ scheduler->error(this, load.error());
return;
}
- flags::Flags<logging::Flags> flags;
-
- flags.load(configuration.getMap());
-
// Initialize libprocess.
process::initialize();
- // TODO(benh): Consider eliminating 'localquiet' so that we don't
- // have to have weird semantics when the 'quiet' option is set to
- // false but 'localquiet' is being used.
- configuration.set("quiet", master == "localquiet");
-
// TODO(benh): Replace whitespace in framework.name() with '_'?
logging::initialize(framework.name(), flags);
@@ -729,8 +715,8 @@ MesosSchedulerDriver::MesosSchedulerDriver(
// Launch a local cluster if necessary.
Option<UPID> pid;
- if (master == "local" || master == "localquiet") {
- pid = local::launch(configuration);
+ if (master == "local") {
+ pid = local::launch(flags);
}
CHECK(process == NULL);
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/slave/flags.hpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp
index f3cbe3d..9612983 100644
--- a/src/slave/flags.hpp
+++ b/src/slave/flags.hpp
@@ -22,10 +22,9 @@
#include <string>
#include <stout/duration.hpp>
+#include <stout/flags.hpp>
#include <stout/option.hpp>
-#include "flags/flags.hpp"
-
#include "logging/flags.hpp"
#include "slave/constants.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/slave/main.cpp
----------------------------------------------------------------------
diff --git a/src/slave/main.cpp b/src/slave/main.cpp
index 97c818a..1d3431f 100644
--- a/src/slave/main.cpp
+++ b/src/slave/main.cpp
@@ -18,20 +18,16 @@
#include <mesos/mesos.hpp>
+#include <stout/flags.hpp>
+#include <stout/nothing.hpp>
#include <stout/os.hpp>
#include <stout/stringify.hpp>
#include <stout/try.hpp>
#include "common/build.hpp"
-#include "configurator/configuration.hpp"
-#include "configurator/configurator.hpp"
-
#include "detector/detector.hpp"
-#include "flags/flags.hpp"
-
-#include "logging/flags.hpp"
#include "logging/logging.hpp"
#include "slave/slave.hpp"
@@ -46,12 +42,12 @@ using std::endl;
using std::string;
-void usage(const char* argv0, const Configurator& configurator)
+void usage(const char* argv0, const flags::FlagsBase& flags)
{
cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
<< endl
<< "Supported options:" << endl
- << configurator.getUsage();
+ << flags.usage();
}
@@ -90,20 +86,16 @@ int main(int argc, char** argv)
"Prints this help message",
false);
- Configurator configurator(flags);
- Configuration configuration;
- try {
- configuration = configurator.load(argc, argv);
- } catch (ConfigurationException& e) {
- cerr << "Configuration error: " << e.what() << endl;
- usage(argv[0], configurator);
+ Try<Nothing> load = flags.load("MESOS_", argc, argv);
+
+ if (load.isError()) {
+ cerr << load.error() << endl;
+ usage(argv[0], flags);
exit(1);
}
- flags.load(configuration.getMap());
-
if (help) {
- usage(argv[0], configurator);
+ usage(argv[0], flags);
exit(1);
}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/tests/allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/allocator_tests.cpp b/src/tests/allocator_tests.cpp
index 52e2b03..b153dee 100644
--- a/src/tests/allocator_tests.cpp
+++ b/src/tests/allocator_tests.cpp
@@ -26,8 +26,6 @@
#include <process/gmock.hpp>
#include <process/pid.hpp>
-#include "configurator/configuration.hpp"
-
#include "detector/detector.hpp"
#include "master/allocator.hpp"
[25/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/timer.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/timer.hpp b/3rdparty/libprocess/include/process/timer.hpp
new file mode 100644
index 0000000..333a806
--- /dev/null
+++ b/3rdparty/libprocess/include/process/timer.hpp
@@ -0,0 +1,76 @@
+#ifndef __PROCESS_TIMER_HPP__
+#define __PROCESS_TIMER_HPP__
+
+#include <stdlib.h> // For abort.
+
+#include <tr1/functional>
+
+#include <process/timeout.hpp>
+
+#include <stout/duration.hpp>
+
+namespace process {
+
+// Timer support!
+
+class Timer
+{
+public:
+ Timer() : id(0), pid(process::UPID()), thunk(&abort) {}
+
+ static Timer create(
+ const Duration& duration,
+ const std::tr1::function<void(void)>& thunk);
+
+ static bool cancel(const Timer& timer);
+
+ bool operator == (const Timer& that) const
+ {
+ return id == that.id;
+ }
+
+ // Invokes this timer's thunk.
+ void operator () () const
+ {
+ thunk();
+ }
+
+ // Returns the timeout associated with this timer.
+ Timeout timeout() const
+ {
+ return t;
+ }
+
+ // Returns the PID of the running process when this timer was
+ // created (via timers::create) or an empty PID if no process was
+ // running when this timer was created.
+ process::UPID creator() const
+ {
+ return pid;
+ }
+
+private:
+ Timer(long _id,
+ const Timeout& _t,
+ const process::UPID& _pid,
+ const std::tr1::function<void(void)>& _thunk)
+ : id(_id), t(_t), pid(_pid), thunk(_thunk)
+ {}
+
+ uint64_t id; // Used for equality.
+
+ Timeout t;
+
+ // We store the PID of the "issuing" (i.e., "running") process (if
+ // there is one). We don't store a pointer to the process because we
+ // can't dereference it since it might no longer be valid. (Instead,
+ // the PID can be used internally to check if the process is still
+ // valid and get a refernce to it.)
+ process::UPID pid;
+
+ std::tr1::function<void(void)> thunk;
+};
+
+} // namespace process {
+
+#endif // __PROCESS_TIMER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/tuples/details.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/tuples/details.hpp b/3rdparty/libprocess/include/process/tuples/details.hpp
new file mode 100644
index 0000000..34a9fb5
--- /dev/null
+++ b/3rdparty/libprocess/include/process/tuples/details.hpp
@@ -0,0 +1,170 @@
+template <MSGID ID> class tuple;
+
+#undef IDENTITY
+#define IDENTITY(...) __VA_ARGS__
+
+#undef TUPLE
+#define TUPLE(ID, types) \
+ template <> class tuple<ID> : public boost::tuple<IDENTITY types> \
+ { \
+ public: \
+ tuple(const boost::tuple<IDENTITY types> &t) \
+ : boost::tuple<IDENTITY types>(t) {} \
+ \
+ tuple(const std::string &data) \
+ { \
+ std::istringstream is(data); \
+ process::tuples::deserializer d(is); \
+ deserialize(d, *this); \
+ } \
+ \
+ operator std::string () const \
+ { \
+ std::ostringstream os; \
+ process::tuples::serializer s(os); \
+ serialize(s, *this); \
+ return os.str(); \
+ } \
+ }
+
+
+inline void serialize(process::tuples::serializer &s,
+ const boost::tuples::null_type &)
+{
+}
+
+
+template <typename H, typename T>
+inline void serialize(process::tuples::serializer &s,
+ const boost::tuples::cons<H, T> &c)
+{
+ s & c.get_head();
+ serialize(s, c.get_tail());
+}
+
+
+inline void deserialize(process::tuples::deserializer &d,
+ const boost::tuples::null_type &)
+{
+}
+
+
+template <typename H, typename T>
+inline void deserialize(process::tuples::deserializer &d,
+ boost::tuples::cons<H, T> &c)
+{
+ d & c.get_head();
+ deserialize(d, c.get_tail());
+}
+
+
+template <MSGID ID>
+tuple<ID> pack()
+{
+ return tuple<ID>(::boost::make_tuple());
+}
+
+
+template <MSGID ID, typename T0>
+tuple<ID> pack(const T0 &t0)
+{
+ return tuple<ID>(::boost::make_tuple(t0));
+}
+
+
+template <MSGID ID, typename T0, typename T1>
+tuple<ID> pack(const T0 &t0, const T1 &t1)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1));
+}
+
+
+template <MSGID ID, typename T0, typename T1, typename T2>
+tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1, t2));
+}
+
+
+template <MSGID ID,
+ typename T0, typename T1, typename T2, typename T3>
+tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3));
+}
+
+
+template <MSGID ID,
+ typename T0, typename T1, typename T2, typename T3, typename T4>
+tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
+ const T4 &t4)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4));
+}
+
+
+template <MSGID ID,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5>
+tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
+ const T4 &t4, const T5 &t5)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5));
+}
+
+
+template <MSGID ID,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6>
+tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
+ const T4 &t4, const T5 &t5, const T6 &t6)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5, t6));
+}
+
+
+template <MSGID ID,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7>
+tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
+ const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5, t6, t7));
+}
+
+
+template <MSGID ID,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8>
+tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
+ const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7,
+ const T8 &t8)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5, t6, t7, t8));
+}
+
+
+template <MSGID ID,
+ typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8, typename T9>
+tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
+ const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7,
+ const T8 &t8, const T9 &t9)
+{
+ return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9));
+}
+
+
+template <MSGID ID>
+tuple<ID> unpack(const std::string &data)
+{
+ return tuple<ID>(data);
+}
+
+
+template <MSGID ID, int N>
+typename boost::tuples::element<N, tuple<ID> >::type unpack(
+ const std::string &data)
+{
+ return boost::tuples::get<N>(unpack<ID>(data));
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/tuples/tuples.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/tuples/tuples.hpp b/3rdparty/libprocess/include/process/tuples/tuples.hpp
new file mode 100644
index 0000000..16445fa
--- /dev/null
+++ b/3rdparty/libprocess/include/process/tuples/tuples.hpp
@@ -0,0 +1,154 @@
+#ifndef __PROCESS_TUPLES_HPP__
+#define __PROCESS_TUPLES_HPP__
+
+#include <stdlib.h>
+
+#include <arpa/inet.h>
+
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include <boost/tuple/tuple.hpp>
+
+
+namespace process { namespace tuples {
+
+// TODO(benh): Check stream errors! Report errors! Ahhhh!
+
+struct serializer
+{
+ std::ostringstream& stream;
+
+ serializer(std::ostringstream& s) : stream(s) {}
+
+ void operator & (const int32_t & i)
+ {
+ uint32_t netInt = htonl((uint32_t) i);
+ stream.write((char *) &netInt, sizeof(netInt));
+ }
+
+ void operator & (const int64_t & i)
+ {
+ uint32_t hiInt = htonl((uint32_t) (i >> 32));
+ uint32_t loInt = htonl((uint32_t) (i & 0xFFFFFFFF));
+ stream.write((char *) &hiInt, sizeof(hiInt));
+ stream.write((char *) &loInt, sizeof(loInt));
+ }
+
+#ifdef __APPLE__
+ void operator & (const intptr_t &i)
+ {
+ if (sizeof(intptr_t) == sizeof(int32_t))
+ *this & ((int32_t &) i);
+ else if (sizeof(intptr_t) == sizeof(int64_t))
+ *this & ((int64_t &) i);
+ else
+ abort();
+ }
+#endif
+
+ void operator & (const size_t &i)
+ {
+ if (sizeof(size_t) == sizeof(int32_t))
+ *this & ((int32_t &) i);
+ else if (sizeof(size_t) == sizeof(int64_t))
+ *this & ((int64_t &) i);
+ else
+ abort();
+ }
+
+ void operator & (const double &d)
+ {
+ // TODO(*): Deal with endian issues?
+ stream.write((char *) &d, sizeof(d));
+ }
+
+ void operator & (const std::string &s)
+ {
+ size_t size = s.size();
+ *this & (size);
+ stream.write(s.data(), size);
+ }
+
+ void operator & (const PID &pid)
+ {
+ *this & ((int32_t) pid.pipe);
+ *this & ((int32_t) pid.ip);
+ *this & ((int32_t) pid.port);
+ }
+};
+
+
+struct deserializer
+{
+ std::istringstream &stream;
+
+ deserializer(std::istringstream &s) : stream(s) {}
+
+ void operator & (int32_t &i)
+ {
+ uint32_t netInt;
+ stream.read((char *) &netInt, sizeof(netInt));
+ i = ntohl(netInt);
+ }
+
+ void operator & (int64_t &i)
+ {
+ uint32_t hiInt, loInt;
+ stream.read((char *) &hiInt, sizeof(hiInt));
+ stream.read((char *) &loInt, sizeof(loInt));
+ int64_t hi64 = ntohl(hiInt);
+ int64_t lo64 = ntohl(loInt);
+ i = (hi64 << 32) | lo64;
+ }
+
+#ifdef __APPLE__
+ void operator & (intptr_t &i)
+ {
+ if (sizeof(intptr_t) == sizeof(int32_t))
+ *this & ((int32_t &) i);
+ else if (sizeof(intptr_t) == sizeof(int64_t))
+ *this & ((int64_t &) i);
+ else
+ abort();
+ }
+#endif
+
+ void operator & (size_t &i)
+ {
+ if (sizeof(size_t) == sizeof(int32_t))
+ *this & ((int32_t &) i);
+ else if (sizeof(size_t) == sizeof(int64_t))
+ *this & ((int64_t &) i);
+ else
+ abort();
+ }
+
+ void operator & (double &d)
+ {
+ // TODO(*): Deal with endian issues?
+ stream.read((char *) &d, sizeof(d));
+ }
+
+ void operator & (std::string &s)
+ {
+ size_t size;
+ *this & (size);
+ s.resize(size);
+ stream.read((char *) s.data(), size);
+ }
+
+ void operator & (PID &pid)
+ {
+ *this & ((int32_t &) pid.pipe);
+ *this & ((int32_t &) pid.ip);
+ *this & ((int32_t &) pid.port);
+ }
+};
+
+
+}} // namespace process { namespace tuples {
+
+
+#endif // __PROCESS_TUPLES_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/install-sh
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/install-sh b/3rdparty/libprocess/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/3rdparty/libprocess/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/m4/acx_pthread.m4
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/m4/acx_pthread.m4 b/3rdparty/libprocess/m4/acx_pthread.m4
new file mode 100644
index 0000000..2cf20de
--- /dev/null
+++ b/3rdparty/libprocess/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/src/config.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/config.hpp b/3rdparty/libprocess/src/config.hpp
new file mode 100644
index 0000000..1daa476
--- /dev/null
+++ b/3rdparty/libprocess/src/config.hpp
@@ -0,0 +1,47 @@
+#ifndef CONFIG_HPP
+#define CONFIG_HPP
+
+#ifdef __sun__
+#define gethostbyname2(name, _) gethostbyname(name)
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+#ifndef SOL_TCP
+#define SOL_TCP IPPROTO_TCP
+#endif
+#ifndef MAP_32BIT
+#define MAP_32BIT 0
+#endif
+#endif /* __sun__ */
+
+#ifdef __APPLE__
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+#ifndef SOL_TCP
+#define SOL_TCP IPPROTO_TCP
+#endif
+#ifndef MAP_32BIT
+#define MAP_32BIT 0
+#endif
+#define sendfile(s, fd, offset, size) \
+ ({ off_t length = size; \
+ sendfile(fd, s, offset, &length, NULL, 0) == 0 \
+ ? length \
+ : (errno == EAGAIN ? (length > 0 ? length : -1) : -1); })
+#endif /* __APPLE__ */
+
+#ifdef __linux__
+#ifndef MAP_32BIT
+#define MAP_32BIT 0
+#endif
+#include <sys/sendfile.h>
+#define sendfile(s, fd, offset, size) \
+ ({ off_t _offset = offset; \
+ sendfile(s, fd, &_offset, size) == -1 ? -1 : _offset - offset; })
+#endif /* __linux__ */
+
+#endif /* CONFIG_HPP */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/decoder.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/decoder.hpp b/3rdparty/libprocess/src/decoder.hpp
new file mode 100644
index 0000000..4c29229
--- /dev/null
+++ b/3rdparty/libprocess/src/decoder.hpp
@@ -0,0 +1,412 @@
+#ifndef __DECODER_HPP__
+#define __DECODER_HPP__
+
+#include <http_parser.h>
+
+#include <deque>
+#include <string>
+#include <vector>
+
+#include <process/http.hpp>
+#include <process/socket.hpp>
+
+#include <stout/foreach.hpp>
+#include <stout/gzip.hpp>
+#include <stout/try.hpp>
+
+
+// TODO(bmahler): Upgrade our http_parser to the latest version.
+namespace process {
+
+// TODO: Make DataDecoder abstract and make RequestDecoder a concrete subclass.
+class DataDecoder
+{
+public:
+ DataDecoder(const Socket& _s)
+ : s(_s), failure(false), request(NULL)
+ {
+ settings.on_message_begin = &DataDecoder::on_message_begin;
+ settings.on_header_field = &DataDecoder::on_header_field;
+ settings.on_header_value = &DataDecoder::on_header_value;
+ settings.on_path = &DataDecoder::on_path;
+ settings.on_url = &DataDecoder::on_url;
+ settings.on_fragment = &DataDecoder::on_fragment;
+ settings.on_query_string = &DataDecoder::on_query_string;
+ settings.on_body = &DataDecoder::on_body;
+ settings.on_headers_complete = &DataDecoder::on_headers_complete;
+ settings.on_message_complete = &DataDecoder::on_message_complete;
+
+ http_parser_init(&parser, HTTP_REQUEST);
+
+ parser.data = this;
+ }
+
+ std::deque<http::Request*> decode(const char* data, size_t length)
+ {
+ size_t parsed = http_parser_execute(&parser, &settings, data, length);
+
+ if (parsed != length) {
+ failure = true;
+ }
+
+ if (!requests.empty()) {
+ std::deque<http::Request*> result = requests;
+ requests.clear();
+ return result;
+ }
+
+ return std::deque<http::Request*>();
+ }
+
+ bool failed() const
+ {
+ return failure;
+ }
+
+ Socket socket() const
+ {
+ return s;
+ }
+
+private:
+ static int on_message_begin(http_parser* p)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+
+ assert(!decoder->failure);
+
+ decoder->header = HEADER_FIELD;
+ decoder->field.clear();
+ decoder->value.clear();
+ decoder->query.clear();
+
+ assert(decoder->request == NULL);
+ decoder->request = new http::Request();
+ decoder->request->headers.clear();
+ decoder->request->method.clear();
+ decoder->request->path.clear();
+ decoder->request->url.clear();
+ decoder->request->fragment.clear();
+ decoder->request->query.clear();
+ decoder->request->body.clear();
+
+ return 0;
+ }
+
+ static int on_headers_complete(http_parser* p)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+
+ // Add final header.
+ decoder->request->headers[decoder->field] = decoder->value;
+ decoder->field.clear();
+ decoder->value.clear();
+
+ decoder->request->method = http_method_str((http_method) decoder->parser.method);
+ decoder->request->keepAlive = http_should_keep_alive(&decoder->parser);
+ return 0;
+ }
+
+ static int on_message_complete(http_parser* p)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+// std::cout << "http::Request:" << std::endl;
+// std::cout << " method: " << decoder->request->method << std::endl;
+// std::cout << " path: " << decoder->request->path << std::endl;
+ // Parse the query key/values.
+ Try<std::string> decoded = http::decode(decoder->query);
+ if (decoded.isError()) {
+ return 1;
+ }
+ decoder->request->query = http::query::parse(decoded.get());
+
+ Option<std::string> encoding =
+ decoder->request->headers.get("Content-Encoding");
+ if (encoding.isSome() && encoding.get() == "gzip") {
+ Try<std::string> decompressed = gzip::decompress(decoder->request->body);
+ if (decompressed.isError()) {
+ return 1;
+ }
+ decoder->request->body = decompressed.get();
+ decoder->request->headers["Content-Length"] =
+ decoder->request->body.length();
+ }
+
+ decoder->requests.push_back(decoder->request);
+ decoder->request = NULL;
+ return 0;
+ }
+
+ static int on_header_field(http_parser* p, const char* data, size_t length)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+ assert(decoder->request != NULL);
+
+ if (decoder->header != HEADER_FIELD) {
+ decoder->request->headers[decoder->field] = decoder->value;
+ decoder->field.clear();
+ decoder->value.clear();
+ }
+
+ decoder->field.append(data, length);
+ decoder->header = HEADER_FIELD;
+
+ return 0;
+ }
+
+ static int on_header_value(http_parser* p, const char* data, size_t length)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+ assert(decoder->request != NULL);
+ decoder->value.append(data, length);
+ decoder->header = HEADER_VALUE;
+ return 0;
+ }
+
+ static int on_path(http_parser* p, const char* data, size_t length)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+ assert(decoder->request != NULL);
+ decoder->request->path.append(data, length);
+ return 0;
+ }
+
+ static int on_url(http_parser* p, const char* data, size_t length)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+ assert(decoder->request != NULL);
+ decoder->request->url.append(data, length);
+ return 0;
+ }
+
+ static int on_query_string(http_parser* p, const char* data, size_t length)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+ assert(decoder->request != NULL);
+ decoder->query.append(data, length);
+ return 0;
+ }
+
+ static int on_fragment(http_parser* p, const char* data, size_t length)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+ assert(decoder->request != NULL);
+ decoder->request->fragment.append(data, length);
+ return 0;
+ }
+
+ static int on_body(http_parser* p, const char* data, size_t length)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+ assert(decoder->request != NULL);
+ decoder->request->body.append(data, length);
+ return 0;
+ }
+
+ const Socket s; // The socket this decoder is associated with.
+
+ bool failure;
+
+ http_parser parser;
+ http_parser_settings settings;
+
+ enum {
+ HEADER_FIELD,
+ HEADER_VALUE
+ } header;
+
+ std::string field;
+ std::string value;
+ std::string query;
+
+ http::Request* request;
+
+ std::deque<http::Request*> requests;
+};
+
+
+class ResponseDecoder
+{
+public:
+ ResponseDecoder()
+ : failure(false), header(HEADER_FIELD), response(NULL)
+ {
+ settings.on_message_begin = &ResponseDecoder::on_message_begin;
+ settings.on_header_field = &ResponseDecoder::on_header_field;
+ settings.on_header_value = &ResponseDecoder::on_header_value;
+ settings.on_path = &ResponseDecoder::on_path;
+ settings.on_url = &ResponseDecoder::on_url;
+ settings.on_fragment = &ResponseDecoder::on_fragment;
+ settings.on_query_string = &ResponseDecoder::on_query_string;
+ settings.on_body = &ResponseDecoder::on_body;
+ settings.on_headers_complete = &ResponseDecoder::on_headers_complete;
+ settings.on_message_complete = &ResponseDecoder::on_message_complete;
+
+ http_parser_init(&parser, HTTP_RESPONSE);
+
+ parser.data = this;
+ }
+
+ std::deque<http::Response*> decode(const char* data, size_t length)
+ {
+ size_t parsed = http_parser_execute(&parser, &settings, data, length);
+
+ if (parsed != length) {
+ failure = true;
+ }
+
+ if (!responses.empty()) {
+ std::deque<http::Response*> result = responses;
+ responses.clear();
+ return result;
+ }
+
+ return std::deque<http::Response*>();
+ }
+
+ bool failed() const
+ {
+ return failure;
+ }
+
+private:
+ static int on_message_begin(http_parser* p)
+ {
+ ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+
+ assert(!decoder->failure);
+
+ decoder->header = HEADER_FIELD;
+ decoder->field.clear();
+ decoder->value.clear();
+
+ assert(decoder->response == NULL);
+ decoder->response = new http::Response();
+ decoder->response->status.clear();
+ decoder->response->headers.clear();
+ decoder->response->type = http::Response::BODY;
+ decoder->response->body.clear();
+ decoder->response->path.clear();
+
+ return 0;
+ }
+
+ static int on_headers_complete(http_parser* p)
+ {
+ ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+
+ // Add final header.
+ decoder->response->headers[decoder->field] = decoder->value;
+ decoder->field.clear();
+ decoder->value.clear();
+
+ return 0;
+ }
+
+ static int on_message_complete(http_parser* p)
+ {
+ ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+
+ // Get the response status string.
+ if (http::statuses.contains(decoder->parser.status_code)) {
+ decoder->response->status = http::statuses[decoder->parser.status_code];
+ } else {
+ decoder->failure = true;
+ return 1;
+ }
+
+ // We can only provide the gzip encoding.
+ Option<std::string> encoding =
+ decoder->response->headers.get("Content-Encoding");
+ if (encoding.isSome() && encoding.get() == "gzip") {
+ Try<std::string> decompressed = gzip::decompress(decoder->response->body);
+ if (decompressed.isError()) {
+ decoder->failure = true;
+ return 1;
+ }
+ decoder->response->body = decompressed.get();
+ decoder->response->headers["Content-Length"] =
+ decoder->response->body.length();
+ }
+
+ decoder->responses.push_back(decoder->response);
+ decoder->response = NULL;
+ return 0;
+ }
+
+ static int on_header_field(http_parser* p, const char* data, size_t length)
+ {
+ ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+ assert(decoder->response != NULL);
+
+ if (decoder->header != HEADER_FIELD) {
+ decoder->response->headers[decoder->field] = decoder->value;
+ decoder->field.clear();
+ decoder->value.clear();
+ }
+
+ decoder->field.append(data, length);
+ decoder->header = HEADER_FIELD;
+
+ return 0;
+ }
+
+ static int on_header_value(http_parser* p, const char* data, size_t length)
+ {
+ ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+ assert(decoder->response != NULL);
+ decoder->value.append(data, length);
+ decoder->header = HEADER_VALUE;
+ return 0;
+ }
+
+ static int on_path(http_parser* p, const char* data, size_t length)
+ {
+ return 0;
+ }
+
+ static int on_url(http_parser* p, const char* data, size_t length)
+ {
+ return 0;
+ }
+
+ static int on_query_string(http_parser* p, const char* data, size_t length)
+ {
+ return 0;
+ }
+
+ static int on_fragment(http_parser* p, const char* data, size_t length)
+ {
+ return 0;
+ }
+
+ static int on_body(http_parser* p, const char* data, size_t length)
+ {
+ ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+ assert(decoder->response != NULL);
+ decoder->response->body.append(data, length);
+ return 0;
+ }
+
+ bool failure;
+
+ http_parser parser;
+ http_parser_settings settings;
+
+ enum {
+ HEADER_FIELD,
+ HEADER_VALUE
+ } header;
+
+ std::string field;
+ std::string value;
+
+ http::Response* response;
+
+ std::deque<http::Response*> responses;
+};
+
+
+} // namespace process {
+
+#endif // __DECODER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/encoder.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/encoder.hpp b/3rdparty/libprocess/src/encoder.hpp
new file mode 100644
index 0000000..55aba22
--- /dev/null
+++ b/3rdparty/libprocess/src/encoder.hpp
@@ -0,0 +1,262 @@
+#ifndef __ENCODER_HPP__
+#define __ENCODER_HPP__
+
+#include <map>
+#include <sstream>
+
+#include <process/http.hpp>
+#include <process/process.hpp>
+
+#include <stout/foreach.hpp>
+#include <stout/gzip.hpp>
+#include <stout/hashmap.hpp>
+#include <stout/numify.hpp>
+#include <stout/os.hpp>
+
+// NOTE: We forward declare "ev_loop" and "ev_io" here because,
+// on OSX, including "ev.h" causes conflict with "EV_ERROR" declared
+// in "/usr/include/sys/event.h".
+struct ev_loop;
+struct ev_io;
+
+namespace process {
+
+const uint32_t GZIP_MINIMUM_BODY_LENGTH = 1024;
+
+typedef void (*Sender)(struct ev_loop*, ev_io*, int);
+
+extern void send_data(struct ev_loop*, ev_io*, int);
+extern void send_file(struct ev_loop*, ev_io*, int);
+
+
+class Encoder
+{
+public:
+ Encoder(const Socket& _s) : s(_s) {}
+ virtual ~Encoder() {}
+
+ virtual Sender sender() = 0;
+
+ Socket socket() const
+ {
+ return s;
+ }
+
+private:
+ const Socket s; // The socket this encoder is associated with.
+};
+
+
+class DataEncoder : public Encoder
+{
+public:
+ DataEncoder(const Socket& s, const std::string& _data)
+ : Encoder(s), data(_data), index(0) {}
+
+ virtual ~DataEncoder() {}
+
+ virtual Sender sender()
+ {
+ return send_data;
+ }
+
+ virtual const char* next(size_t* length)
+ {
+ size_t temp = index;
+ index = data.size();
+ *length = data.size() - temp;
+ return data.data() + temp;
+ }
+
+ virtual void backup(size_t length)
+ {
+ if (index >= length) {
+ index -= length;
+ }
+ }
+
+ virtual size_t remaining() const
+ {
+ return data.size() - index;
+ }
+
+private:
+ const std::string data;
+ size_t index;
+};
+
+
+class MessageEncoder : public DataEncoder
+{
+public:
+ MessageEncoder(const Socket& s, Message* _message)
+ : DataEncoder(s, encode(_message)), message(_message) {}
+
+ virtual ~MessageEncoder()
+ {
+ if (message != NULL) {
+ delete message;
+ }
+ }
+
+ static std::string encode(Message* message)
+ {
+ if (message != NULL) {
+ std::ostringstream out;
+
+ out << "POST /" << message->to.id << "/" << message->name
+ << " HTTP/1.0\r\n"
+ << "User-Agent: libprocess/" << message->from << "\r\n"
+ << "Connection: Keep-Alive\r\n";
+
+ if (message->body.size() > 0) {
+ out << "Transfer-Encoding: chunked\r\n\r\n"
+ << std::hex << message->body.size() << "\r\n";
+ out.write(message->body.data(), message->body.size());
+ out << "\r\n"
+ << "0\r\n"
+ << "\r\n";
+ } else {
+ out << "\r\n";
+ }
+
+ return out.str();
+ }
+ }
+
+private:
+ Message* message;
+};
+
+
+class HttpResponseEncoder : public DataEncoder
+{
+public:
+ HttpResponseEncoder(
+ const Socket& s,
+ const http::Response& response,
+ const http::Request& request)
+ : DataEncoder(s, encode(response, request)) {}
+
+ static std::string encode(
+ const http::Response& response,
+ const http::Request& request)
+ {
+ std::ostringstream out;
+
+ // TODO(benh): Check version?
+
+ out << "HTTP/1.1 " << response.status << "\r\n";
+
+ hashmap<std::string, std::string> headers = response.headers;
+
+ // HTTP 1.1 requires the "Date" header. In the future once we
+ // start checking the version (above) then we can conditionally
+ // add this header, but for now, we always do.
+ time_t rawtime;
+ time(&rawtime);
+
+ char date[256];
+
+ // TODO(benh): Check return code of strftime!
+ strftime(date, 256, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&rawtime));
+
+ headers["Date"] = date;
+
+ // Should we compress this response?
+ std::string body = response.body;
+
+ if (response.type == http::Response::BODY &&
+ response.body.length() >= GZIP_MINIMUM_BODY_LENGTH &&
+ !headers.contains("Content-Encoding") &&
+ request.accepts("gzip")) {
+ Try<std::string> compressed = gzip::compress(body);
+ if (compressed.isError()) {
+ LOG(WARNING) << "Failed to gzip response body: " << compressed.error();
+ } else {
+ body = compressed.get();
+ headers["Content-Length"] = stringify(body.length());
+ headers["Content-Encoding"] = "gzip";
+ }
+ }
+
+ foreachpair (const std::string& key, const std::string& value, headers) {
+ out << key << ": " << value << "\r\n";
+ }
+
+ // Add a Content-Length header if the response is of type "none"
+ // or "body" and no Content-Length header has been supplied.
+ if (response.type == http::Response::NONE &&
+ !headers.contains("Content-Length")) {
+ out << "Content-Length: 0\r\n";
+ } else if (response.type == http::Response::BODY &&
+ !headers.contains("Content-Length")) {
+ out << "Content-Length: " << body.size() << "\r\n";
+ }
+
+ // Use a CRLF to mark end of headers.
+ out << "\r\n";
+
+ // Add the body if necessary.
+ if (response.type == http::Response::BODY) {
+ // If the Content-Length header was supplied, only write as much data
+ // as the length specifies.
+ Result<uint32_t> length = numify<uint32_t>(headers.get("Content-Length"));
+ if (length.isSome() && length.get() <= body.length()) {
+ out.write(body.data(), length.get());
+ } else {
+ out.write(body.data(), body.size());
+ }
+ }
+
+ return out.str();
+ }
+};
+
+
+class FileEncoder : public Encoder
+{
+public:
+ FileEncoder(const Socket& s, int _fd, size_t _size)
+ : Encoder(s), fd(_fd), size(_size), index(0) {}
+
+ virtual ~FileEncoder()
+ {
+ os::close(fd);
+ }
+
+ virtual Sender sender()
+ {
+ return send_file;
+ }
+
+ virtual int next(off_t* offset, size_t* length)
+ {
+ off_t temp = index;
+ index = size;
+ *offset = temp;
+ *length = size - temp;
+ return fd;
+ }
+
+ virtual void backup(size_t length)
+ {
+ if (index >= length) {
+ index -= length;
+ }
+ }
+
+ virtual size_t remaining() const
+ {
+ return size - index;
+ }
+
+private:
+ int fd;
+ size_t size;
+ off_t index;
+};
+
+} // namespace process {
+
+#endif // __ENCODER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/fatal.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/fatal.cpp b/3rdparty/libprocess/src/fatal.cpp
new file mode 100644
index 0000000..b2934e0
--- /dev/null
+++ b/3rdparty/libprocess/src/fatal.cpp
@@ -0,0 +1,26 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void __fatal(const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, " (%s:%u)\n", file, line);
+ fflush(stderr);
+ va_end(args);
+ exit(1);
+}
+
+void __fatalerror(const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, " (%s:%u): ", file, line);
+ perror(NULL);
+ fflush(stderr);
+ va_end(args);
+ exit(1);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/fatal.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/fatal.hpp b/3rdparty/libprocess/src/fatal.hpp
new file mode 100644
index 0000000..38646f3
--- /dev/null
+++ b/3rdparty/libprocess/src/fatal.hpp
@@ -0,0 +1,28 @@
+/*
+ * Basic perror + exit routines.
+ *
+ * Contributed by Benjamin Hindman <be...@berkeley.edu>, 2008.
+ */
+
+#ifndef FATAL_HPP
+#define FATAL_HPP
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Like the non-debug version except includes the file name and line
+ * number in the output.
+ */
+#define fatal(fmt...) __fatal(__FILE__, __LINE__, fmt)
+void __fatal(const char *file, int line, const char *fmt, ...);
+
+/*
+ * Like the non-debug version except includes the file name and line
+ * number in the output.
+ */
+#define fatalerror(fmt...) __fatalerror(__FILE__, __LINE__, fmt)
+void __fatalerror(const char *file, int line, const char *fmt, ...);
+
+#endif /* FATAL_HPP */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/gate.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/gate.hpp b/3rdparty/libprocess/src/gate.hpp
new file mode 100644
index 0000000..954f620
--- /dev/null
+++ b/3rdparty/libprocess/src/gate.hpp
@@ -0,0 +1,103 @@
+#ifndef GATE_H
+#define GATE_H
+
+/* TODO(benh): Provide an implementation directly on-top-of futex's for Linux. */
+//#ifdef __linux__
+//#else
+
+class Gate
+{
+public:
+ typedef intptr_t state_t;
+
+private:
+ int waiters;
+ state_t state;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+
+public:
+ Gate() : waiters(0), state(0)
+ {
+ pthread_mutex_init(&mutex, NULL);
+ pthread_cond_init(&cond, NULL);
+ }
+
+ ~Gate()
+ {
+ pthread_cond_destroy(&cond);
+ pthread_mutex_destroy(&mutex);
+ }
+
+ void open(bool all = true)
+ {
+ pthread_mutex_lock(&mutex);
+ {
+ state++;
+ if (all) pthread_cond_broadcast(&cond);
+ else pthread_cond_signal(&cond);
+ }
+ pthread_mutex_unlock(&mutex);
+ }
+
+ void wait()
+ {
+ pthread_mutex_lock(&mutex);
+ {
+ waiters++;
+ state_t old = state;
+ while (old == state)
+ pthread_cond_wait(&cond, &mutex);
+ waiters--;
+ }
+ pthread_mutex_unlock(&mutex);
+ }
+
+ state_t approach()
+ {
+ state_t old;
+ pthread_mutex_lock(&mutex);
+ {
+ waiters++;
+ old = state;
+ }
+ pthread_mutex_unlock(&mutex);
+ return old;
+ }
+
+ void arrive(state_t old)
+ {
+ pthread_mutex_lock(&mutex);
+ {
+ while (old == state) {
+ pthread_cond_wait(&cond, &mutex);
+ }
+ waiters--;
+ }
+ pthread_mutex_unlock(&mutex);
+ }
+
+ void leave()
+ {
+ pthread_mutex_lock(&mutex);
+ {
+ waiters--;
+ }
+ pthread_mutex_unlock(&mutex);
+ }
+
+ bool empty()
+ {
+ bool occupied = true;
+ pthread_mutex_lock(&mutex);
+ {
+ occupied = waiters > 0 ? true : false;
+ }
+ pthread_mutex_unlock(&mutex);
+ return !occupied;
+ }
+};
+
+//#endif
+
+#endif /* GATE_H */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/httpd.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/httpd.cpp b/3rdparty/libprocess/src/httpd.cpp
new file mode 100644
index 0000000..793a5b0
--- /dev/null
+++ b/3rdparty/libprocess/src/httpd.cpp
@@ -0,0 +1,306 @@
+/* TODO(benh): TCP_CORK!!!!! */
+/* TODO(benh): Complete HttpParser & HttpMessage implementation. */
+/* TODO(benh): Turn off Nagle (on TCP_NODELAY) for pipelined requests. */
+
+#include <string.h>
+
+#include <process.hpp>
+#include <tuple.hpp>
+
+#include <iostream>
+#include <map>
+#include <sstream>
+#include <stdexcept>
+
+#include <arpa/inet.h>
+
+#include <stout/os.hpp>
+
+#include "net.hpp"
+
+#include "http-parser/http_parser.h"
+
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::runtime_error;
+using std::string;
+using std::map;
+
+using process::tuple::Tuple;
+
+#define malloc(bytes) \
+ ({ void *tmp; if ((tmp = malloc(bytes)) == NULL) abort(); tmp; })
+
+#define realloc(address, bytes) \
+ ({ void *tmp; if ((tmp = realloc(address, bytes)) == NULL) abort(); tmp; })
+
+#define HTTP_500 \
+ "HTTP/1.1 500 Internal Server Error\r\n\r\n"
+
+#define HTTP_501 \
+ "HTTP/1.1 501 Not Implemented\r\n\r\n"
+
+#define HTTP_404 \
+ "HTTP/1.1 404 Not Found\r\n\r\n"
+
+
+struct HttpMessage
+{
+ unsigned short method;
+ /* TODO(*): Use HTTP_MAX_URI_SIZE. */
+ string uri;
+};
+
+
+class HttpParser
+{
+protected:
+ static int on_uri(http_parser *parser, const char *p, size_t len)
+ {
+ HttpMessage *message = (HttpMessage *) parser->data;
+ message->uri += string(p, len);
+ return 0;
+ }
+
+ static int on_headers_complete(http_parser *parser)
+ {
+ HttpMessage *message = (HttpMessage *) parser->data;
+ message->method = parser->method;
+ return 0;
+ }
+
+public:
+ static HttpMessage * parse(const string &raw)
+ {
+ http_parser parser;
+ http_parser_init(&parser, HTTP_REQUEST);
+
+ HttpMessage *message = new HttpMessage;
+
+ parser.data = message;
+
+ parser.on_message_begin = NULL;
+ parser.on_header_field = NULL;
+ parser.on_header_value = NULL;
+ parser.on_path = NULL;
+ parser.on_uri = &HttpParser::on_uri;
+ parser.on_fragment = NULL;
+ parser.on_query_string = NULL;
+ parser.on_body = NULL;
+ parser.on_headers_complete = &HttpParser::on_headers_complete;
+ parser.on_message_complete = NULL;
+
+ http_parser_execute(&parser, raw.c_str(), raw.length());
+
+ if (http_parser_has_error(&parser)) {
+ //cerr << "parser error" << endl;
+ abort();
+ }
+
+ return message;
+ }
+};
+
+
+class HttpConnection : public SocketProcess<TCP>
+{
+protected:
+ void operator () ()
+ {
+ //cout << ht_id() << ": running " << this << " connection (1)" << endl;
+
+ string raw;
+
+ /* Read headers (until CRLF CRLF). */
+ do {
+ char buf[512];
+ ssize_t len = recv(buf, 512);
+ raw += string(buf, len);
+ } while (raw.find("\r\n\r\n") == string::npos);
+
+ //cout << ht_id() << ": running " << this << " connection (2)" << endl;
+
+ /* Parse headers. */
+ HttpMessage *message = HttpParser::parse(raw);
+
+ /* Handle request. */
+ switch (message->method) {
+ case HTTP_GET: {
+ message->uri =
+ message->uri != "/"
+ ? "." + message->uri
+ : "./index.html";
+
+ //cout << "URI: " << message->uri << endl;
+
+ /* Open file (if possible). */
+ int fd;
+
+ if ((fd = open(message->uri.c_str(), O_RDONLY, 0)) < 0) {
+ send(HTTP_404, strlen(HTTP_404));
+ return;
+ }
+
+ /* Lookup file size. */
+ struct stat fd_stat;
+
+ if (fstat(fd, &fd_stat) < 0) {
+ send(HTTP_500, strlen(HTTP_500));
+ os::close(fd);
+ return;
+ }
+
+ /* TODO(benh): Use TCP_CORK. */
+
+ /* Transmit reply header. */
+ std::stringstream out;
+
+ out << "HTTP/1.1 200 OK\r\n";
+
+ /* Determine the content type. */
+ if (message->uri.find(".jpg") != string::npos) {
+ out << "Content-Type: image/jpeg\r\n";
+ } else if (message->uri.find(".gif") != string::npos) {
+ out << "Content-Type: image/gif\r\n";
+ } else if (message->uri.find(".png") != string::npos) {
+ out << "Content-Type: image/png\r\n";
+ } else if (message->uri.find(".css") != string::npos) {
+ out << "Content-Type: text/css\r\n";
+ } else {
+ out << "Content-Type: text/html\r\n";
+ }
+
+ out <<
+ "Content-Length: " << fd_stat.st_size << "\r\n"
+ "\r\n";
+
+ //cout << out.str() << endl;
+
+ send(out.str().c_str(), out.str().size());
+
+ //cout << ht_id() << ": running " << this << " connection (3)" << endl;
+
+ /* Transmit file (TODO(benh): Use file cache.). */
+ sendfile(fd, fd_stat.st_size);
+
+ //cout << ht_id() << ": running " << this << " connection (4)" << endl;
+
+ os::close(fd);
+
+ break;
+ }
+
+ default:
+ /* Unimplemented. */
+ send(HTTP_501, strlen(HTTP_501));
+ break;
+ }
+ }
+
+public:
+ HttpConnection(int s) : SocketProcess<TCP>(s) {}
+ ~HttpConnection() {}
+};
+
+
+enum HTTP_MESSAGES { ACCEPT = PROCESS_MSGID };
+
+namespace process { namespace tuple { TUPLE(::ACCEPT, (int)); }}
+
+class HttpAcceptor : public Tuple< Acceptor<TCP> >
+{
+private:
+ PID server;
+
+protected:
+ void operator () ()
+ {
+ do {
+ struct sockaddr_in addr;
+ int c = accept(addr);
+ //cout << ht_id() << ": running acceptor" << endl;
+ send<ACCEPT>(server, c);
+ } while (true);
+ }
+
+public:
+ HttpAcceptor(const PID &_server, int s) : server(_server) { socket(s); }
+};
+
+
+
+class HttpServer : public Tuple< Server<TCP> >
+{
+private:
+ map<PID, HttpConnection *> connections;
+
+protected:
+ void operator () ()
+ {
+ int on = 1;
+ setsockopt(SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+ bind();
+ listen(100000);
+
+ HttpAcceptor *acceptor = new HttpAcceptor(self(), s);
+ link(spawn(acceptor));
+
+ do {
+ switch (receive()) {
+ case ACCEPT: {
+ //cout << ht_id() << ": running server (accept)" << endl;
+ int c;
+ unpack<ACCEPT>(c);
+ HttpConnection *connection = new HttpConnection(c);
+ connections[link(spawn(connection))] = connection;
+ //cout << "...started (" << connection << ")..." << endl;
+ break;
+ }
+ case PROCESS_EXIT: {
+ //cout << ht_id() << ": running server (exit)" << endl;
+ if (from() == acceptor->getPID()) {
+ throw runtime_error("unimplemented acceptor failure");
+ } else if (connections.find(from()) != connections.end()) {
+ HttpConnection *connection = connections[from()];
+ connections.erase(from());
+ delete connection;
+ //cout << "...finished (" << connection << ")..." << endl;
+ }
+ break;
+ }
+ default:
+ cout << "HttpServer received unexpected message" << endl;
+ break;
+ }
+ } while (true);
+ }
+
+public:
+ HttpServer(int port) { init(INADDR_ANY, port); }
+};
+
+
+
+int main(int argc, char **argv)
+{
+ /* TODO(benh): Blah, 'sendfile' doesn't let us use MSG_NOSIGNAL. :( */
+ signal(SIGPIPE, SIG_IGN);
+
+ if (argc != 2) {
+ cerr << "usage: " << argv[0] << " <port>" << endl;
+ return -1;
+ }
+
+#ifdef USE_LITHE
+ ProcessScheduler *scheduler = new ProcessScheduler();
+ Process::spawn(new HttpServer(atoi(argv[1])));
+ /* TODO(benh): Make Process::wait take and use the hart if using Lithe! */
+ for (;;)
+ sleep(10000);
+#else
+ Process::wait(Process::spawn(new HttpServer(atoi(argv[1]))));
+#endif /* USE_LITHE */
+
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/latch.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/latch.cpp b/3rdparty/libprocess/src/latch.cpp
new file mode 100644
index 0000000..a6f1256
--- /dev/null
+++ b/3rdparty/libprocess/src/latch.cpp
@@ -0,0 +1,62 @@
+#include <process/id.hpp>
+#include <process/latch.hpp>
+#include <process/process.hpp>
+
+#include <stout/duration.hpp>
+
+namespace process {
+
+// TODO(benh): Provide an "optimized" implementation of a latch that
+// is libprocess aware. That is, allow integrate "waiting" on a latch
+// within libprocess such that it doesn't cost a memory allocation, a
+// spawn, a message send, a wait, and two user-space context-switchs.
+
+Latch::Latch()
+{
+ triggered = false;
+
+ // Deadlock is possible if one thread is trying to delete a latch
+ // but the libprocess thread(s) is trying to acquire a resource the
+ // deleting thread is holding. Hence, we only save the PID for
+ // triggering the latch and let the GC actually do the deleting
+ // (thus no waiting is necessary, and deadlocks are avoided).
+ pid = spawn(new ProcessBase(ID::generate("__latch__")), true);
+}
+
+
+Latch::~Latch()
+{
+ terminate(pid);
+}
+
+
+void Latch::trigger()
+{
+ if (!triggered) {
+ terminate(pid);
+ triggered = true;
+ }
+}
+
+
+bool Latch::await(const Duration& duration)
+{
+ if (!triggered) {
+ process::wait(pid, duration); // Explict to disambiguate.
+ // It's possible that we failed to wait because:
+ // (1) Our process has already terminated.
+ // (2) We timed out (i.e., duration was not "infinite").
+
+ // In the event of (1) we might need to return 'true' since a
+ // terminated process might imply that the latch has been
+ // triggered. To capture this we simply return the value of
+ // 'triggered' (which will also capture cases where we actually
+ // timed out but have since triggered, which seems like an
+ // acceptable semantics given such a "tie").
+ return triggered;
+ }
+
+ return true;
+}
+
+} // namespace process {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/net.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/net.hpp b/3rdparty/libprocess/src/net.hpp
new file mode 100644
index 0000000..2fdc62a
--- /dev/null
+++ b/3rdparty/libprocess/src/net.hpp
@@ -0,0 +1,231 @@
+/* TODO(benh): Write a form of 'Client' process. */
+
+#ifndef NET_HPP
+#define NET_HPP
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <process.hpp>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+
+#include <sys/ioctl.h>
+#include <sys/sendfile.h>
+#include <sys/socket.h>
+
+#include <stdexcept>
+#include <iostream>
+
+#include <stout/os.hpp>
+
+typedef enum Protocol { TCP = SOCK_STREAM, UDP = SOCK_DGRAM } Protocol;
+
+using std::runtime_error;
+using std::string;
+
+
+template <Protocol protocol>
+class SocketProcess : public Process
+{
+protected:
+ int s;
+
+ void setsockopt(int level, int optname, const void *optval, socklen_t optlen)
+ {
+ if (::setsockopt(s, level, optname, optval, optlen) < 0)
+ throw std::runtime_error(string("setsockopt: ") += strerror(errno));
+ }
+
+ virtual void socket()
+ {
+ if ((s = ::socket(AF_INET, protocol, IPPROTO_IP)) < 0)
+ throw runtime_error(string("socket: ") += strerror(errno));
+
+ socket(s);
+ }
+
+ virtual void socket(int sd)
+ {
+ s = sd;
+
+ int flags = 1;
+ if (ioctl(s, FIONBIO, &flags) &&
+ ((flags = fcntl(s, F_GETFL, 0)) < 0 ||
+ fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0))
+ throw runtime_error(string("ioctl/fcntl: ") += strerror(errno));
+
+ if (fcntl(s, F_SETFD, FD_CLOEXEC) < 0) {
+ throw runtime_error(string("fcntl: ") += strerror(errno));
+ }
+ }
+
+ virtual void bind(in_addr_t ip, in_port_t port)
+ {
+ struct sockaddr_in addr;
+ addr.sin_family = PF_INET;
+ addr.sin_addr.s_addr = ip;
+ addr.sin_port = htons(port);
+
+ if (::bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+ throw runtime_error(string("bind: ") += strerror(errno));
+ }
+
+ virtual ssize_t recv(void *buf, size_t bytes)
+ {
+ ssize_t len = 0;
+ do {
+ len = ::recv(s, buf, bytes, 0);
+
+ if (len > 0)
+ return len;
+ else if (len < 0 && errno == EWOULDBLOCK)
+ while (!await(s, RDONLY));
+ else if (len == 0)
+ throw runtime_error(string("recv: connection terminated"));
+ else
+ throw runtime_error(string("recv: ") += strerror(errno));
+ } while (!(len > 0));
+
+ return len;
+ }
+
+ virtual ssize_t recvall(void *buf, size_t bytes)
+ {
+ ssize_t len, offset = 0;
+ do {
+ len = ::recv(s, (char *) buf + offset, bytes - offset, 0);
+
+ if (len > 0)
+ offset += len;
+ else if (len < 0 && errno == EWOULDBLOCK)
+ while (!await(s, RDONLY));
+ else if (len == 0)
+ throw runtime_error(string("recvall: connection terminated"));
+ else
+ throw runtime_error(string("recvall: ") += strerror(errno));
+ } while (offset != bytes);
+
+ return offset;
+ }
+
+ virtual void send(const void *buf, size_t bytes)
+ {
+ size_t offset = 0;
+ do {
+ size_t len =
+ ::send(s, (char *) buf + offset, bytes - offset, MSG_NOSIGNAL);
+
+ if (len > 0)
+ offset += len;
+ else if (len < 0 && errno == EWOULDBLOCK)
+ while (!await(s, WRONLY));
+ else if (len == 0)
+ throw runtime_error(string("send: connection terminated"));
+ else
+ throw runtime_error(string("send: ") += strerror(errno));
+ } while (offset != bytes);
+ }
+
+ virtual void sendfile(int fd, size_t bytes)
+ {
+ off_t offset = 0;
+ do {
+ size_t len = ::sendfile(s, fd, 0, bytes - offset);
+
+ if (len > 0)
+ offset += len;
+ else if (len < 0 && errno == EWOULDBLOCK)
+ while (!await(s, WRONLY));
+ else if (len == 0)
+ throw runtime_error(string("sendfile: connection terminated"));
+ else
+ throw runtime_error(string("sendfile: ") += strerror(errno));
+ } while (offset != bytes);
+ }
+
+public:
+ SocketProcess() : s(-1) {}
+ SocketProcess(int _s) : s(_s)
+ {
+ int flags = 1;
+ if (ioctl(s, FIONBIO, &flags) &&
+ ((flags = fcntl(s, F_GETFL, 0)) < 0 ||
+ fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0))
+ throw runtime_error(string("ioctl/fcntl: ") += strerror(errno));
+ }
+ ~SocketProcess() { os::close(s); }
+};
+
+
+template <Protocol protocol>
+class Acceptor : public SocketProcess<protocol>
+{
+protected:
+ virtual int accept(struct sockaddr_in &addr)
+ {
+ int c;
+
+ do {
+ while (!await(SocketProcess<protocol>::s, Process::RDONLY));
+
+ size_t size = sizeof(struct sockaddr_in);
+
+ c = ::accept(SocketProcess<protocol>::s,
+ (struct sockaddr *) &addr,
+ (socklen_t *) &size);
+
+ if (c == 0)
+ throw runtime_error(string("accept: ") += strerror(errno));
+ else if (c < 0 && (errno != EWOULDBLOCK))
+ throw runtime_error(string("accept: ") += strerror(errno));
+ } while (!(c > 0));
+
+ return c;
+ }
+
+public:
+ Acceptor() {}
+ Acceptor(int s) : SocketProcess<protocol>(s) {}
+};
+
+
+template <Protocol protocol>
+class Server : public Acceptor<protocol>
+{
+protected:
+ in_addr_t ip;
+ in_port_t port;
+
+ void init(in_addr_t _ip = INADDR_ANY, in_port_t _port = 0)
+ {
+ ip = _ip;
+ port = _port;
+ SocketProcess<protocol>::socket();
+ }
+
+ virtual void listen(int n)
+ {
+ int &s = SocketProcess<protocol>::s;
+ if (::listen(s, n) < 0)
+ throw runtime_error(string("listen: ") += strerror(errno));
+ }
+
+ virtual void bind()
+ {
+ SocketProcess<protocol>::bind(ip, port);
+ }
+
+public:
+ Server(in_addr_t _ip = INADDR_ANY, in_port_t _port = 0)
+ : ip(_ip), port(_port)
+ {
+ SocketProcess<protocol>::socket();
+ }
+};
+
+
+#endif /* NET_HH */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/pid.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/pid.cpp b/3rdparty/libprocess/src/pid.cpp
new file mode 100644
index 0000000..8f32b08
--- /dev/null
+++ b/3rdparty/libprocess/src/pid.cpp
@@ -0,0 +1,182 @@
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <arpa/inet.h>
+
+#include <glog/logging.h>
+
+#include <iostream>
+#include <string>
+
+#include <boost/unordered_map.hpp>
+
+#include <process/pid.hpp>
+#include <process/process.hpp>
+
+#include "config.hpp"
+
+#ifdef __APPLE__
+#define gethostbyname2_r(name, af, ret, buf, buflen, result, h_errnop) \
+ ({ *(result) = gethostbyname2(name, af); 0; })
+#endif // __APPLE__
+
+
+using std::istream;
+using std::ostream;
+using std::size_t;
+using std::string;
+
+
+namespace process {
+
+UPID::UPID(const char* s)
+{
+ std::istringstream in(s);
+ in >> *this;
+}
+
+
+UPID::UPID(const std::string& s)
+{
+ std::istringstream in(s);
+ in >> *this;
+}
+
+
+// TODO(benh): Make this inline-able (cyclic dependency issues).
+UPID::UPID(const ProcessBase& process)
+{
+ id = process.self().id;
+ ip = process.self().ip;
+ port = process.self().port;
+}
+
+
+UPID::operator std::string() const
+{
+ std::ostringstream out;
+ out << *this;
+ return out.str();
+}
+
+
+ostream& operator << (ostream& stream, const UPID& pid)
+{
+ // Call inet_ntop since inet_ntoa is not thread-safe!
+ char ip[INET_ADDRSTRLEN];
+ if (inet_ntop(AF_INET, (in_addr *) &pid.ip, ip, INET_ADDRSTRLEN) == NULL)
+ memset(ip, 0, INET_ADDRSTRLEN);
+
+ stream << pid.id << "@" << ip << ":" << pid.port;
+ return stream;
+}
+
+
+istream& operator >> (istream& stream, UPID& pid)
+{
+ pid.id = "";
+ pid.ip = 0;
+ pid.port = 0;
+
+ string str;
+ if (!(stream >> str)) {
+ stream.setstate(std::ios_base::badbit);
+ return stream;
+ }
+
+ VLOG(2) << "Attempting to parse '" << str << "' into a PID";
+
+ if (str.size() == 0) {
+ stream.setstate(std::ios_base::badbit);
+ return stream;
+ }
+
+ string id;
+ string host;
+ uint32_t ip;
+ uint16_t port;
+
+ size_t index = str.find('@');
+
+ if (index != string::npos) {
+ id = str.substr(0, index);
+ } else {
+ stream.setstate(std::ios_base::badbit);
+ return stream;
+ }
+
+ str = str.substr(index + 1);
+
+ index = str.find(':');
+
+ if (index != string::npos) {
+ host = str.substr(0, index);
+ } else {
+ stream.setstate(std::ios_base::badbit);
+ return stream;
+ }
+
+ hostent he, *hep;
+ char* temp;
+ size_t length;
+ int result;
+ int herrno;
+
+ // Allocate temporary buffer for gethostbyname2_r.
+ length = 1024;
+ temp = new char[length];
+
+ while ((result = gethostbyname2_r(host.c_str(), AF_INET, &he,
+ temp, length, &hep, &herrno)) == ERANGE) {
+ // Enlarge the buffer.
+ delete[] temp;
+ length *= 2;
+ temp = new char[length];
+ }
+
+ if (result != 0 || hep == NULL) {
+ VLOG(2) << "Failed to parse host '" << host
+ << "' because " << hstrerror(herrno);
+ delete[] temp;
+ stream.setstate(std::ios_base::badbit);
+ return stream;
+ }
+
+ if (hep->h_addr_list[0] == NULL) {
+ VLOG(2) << "Got no addresses for '" << host << "'";
+ delete[] temp;
+ stream.setstate(std::ios_base::badbit);
+ return stream;
+ }
+
+ ip = *((uint32_t*) hep->h_addr_list[0]);
+
+ delete[] temp;
+
+ str = str.substr(index + 1);
+
+ if (sscanf(str.c_str(), "%hu", &port) != 1) {
+ stream.setstate(std::ios_base::badbit);
+ return stream;
+ }
+
+ pid.id = id;
+ pid.ip = ip;
+ pid.port = port;
+
+ return stream;
+}
+
+
+size_t hash_value(const UPID& pid)
+{
+ size_t seed = 0;
+ boost::hash_combine(seed, pid.id);
+ boost::hash_combine(seed, pid.ip);
+ boost::hash_combine(seed, pid.port);
+ return seed;
+}
+
+} // namespace process {
[11/35] git commit: Moved flags to stout.
Posted by be...@apache.org.
Moved flags to stout.
Review: https://reviews.apache.org/r/11465
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/190a3bb8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/190a3bb8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/190a3bb8
Branch: refs/heads/master
Commit: 190a3bb80656ffdd435561d8e8f0f638bdcd7d6e
Parents: f122e61
Author: Benjamin Hindman <be...@twitter.com>
Authored: Tue May 21 10:55:30 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:18:39 2013 -0700
----------------------------------------------------------------------
third_party/libprocess/third_party/Makefile.am | 1 +
.../libprocess/third_party/stout/Makefile.am | 6 +
.../third_party/stout/include/stout/flags.hpp | 70 +++
.../third_party/stout/include/stout/flags/flag.hpp | 26 +
.../stout/include/stout/flags/flags.hpp | 481 +++++++++++++++
.../stout/include/stout/flags/loader.hpp | 109 ++++
.../stout/include/stout/flags/parse.hpp | 55 ++
.../third_party/stout/include/stout/os.hpp | 22 +
.../third_party/stout/tests/flags_tests.cpp | 349 +++++++++++
9 files changed, 1119 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/Makefile.am b/third_party/libprocess/third_party/Makefile.am
index 812b7c3..2f0567b 100644
--- a/third_party/libprocess/third_party/Makefile.am
+++ b/third_party/libprocess/third_party/Makefile.am
@@ -119,6 +119,7 @@ stout_tests_SOURCES = \
$(STOUT)/tests/bytes_tests.cpp \
$(STOUT)/tests/duration_tests.cpp \
$(STOUT)/tests/error_tests.cpp \
+ $(STOUT)/tests/flags_tests.cpp \
$(STOUT)/tests/gzip_tests.cpp \
$(STOUT)/tests/hashset_tests.cpp \
$(STOUT)/tests/json_tests.cpp \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/stout/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/Makefile.am b/third_party/libprocess/third_party/stout/Makefile.am
index 4af647e..fdd3482 100644
--- a/third_party/libprocess/third_party/stout/Makefile.am
+++ b/third_party/libprocess/third_party/stout/Makefile.am
@@ -11,6 +11,11 @@ EXTRA_DIST = \
include/stout/error.hpp \
include/stout/exit.hpp \
include/stout/fatal.hpp \
+ include/stout/flags.hpp \
+ include/stout/flags/flag.hpp \
+ include/stout/flags/flags.hpp \
+ include/stout/flags/loader.hpp \
+ include/stout/flags/parse.hpp \
include/stout/foreach.hpp \
include/stout/format.hpp \
include/stout/fs.hpp \
@@ -43,6 +48,7 @@ EXTRA_DIST = \
tests/bytes_tests.cpp \
tests/duration_tests.cpp \
tests/error_tests.cpp \
+ tests/flags_tests.cpp \
tests/gzip_tests.cpp \
tests/hashset_tests.cpp \
tests/json_tests.cpp \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/stout/include/stout/flags.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags.hpp b/third_party/libprocess/third_party/stout/include/stout/flags.hpp
new file mode 100644
index 0000000..0efd079
--- /dev/null
+++ b/third_party/libprocess/third_party/stout/include/stout/flags.hpp
@@ -0,0 +1,70 @@
+#ifndef __STOUT_FLAGS_HPP__
+#define __STOUT_FLAGS_HPP__
+
+#include <stout/flags/flags.hpp>
+
+// An abstraction for application/library "flags". An example is
+// probably best:
+// -------------------------------------------------------------
+// class MyFlags : public virtual FlagsBase // Use 'virtual' for composition!
+// {
+// public:
+// Flags()
+// {
+// add(&debug,
+// "debug",
+// "Help string for debug",
+// false);
+//
+// add(&name,
+// "name",
+// "Help string for name");
+// }
+
+// bool debug;
+// Option<string> name;
+// };
+//
+// ...
+//
+// map<string, Option<string> > values;
+// values["no-debug"] = None(); // --no-debug
+// values["debug"] = None(); // --debug
+// values["debug"] = Option<string>::some("true"); // --debug=true
+// values["debug"] = Option<string>::some("false"); // --debug=false
+// values["name"] = Option<string>::some("frank"); // --name=frank
+//
+// MyFlags flags;
+// flags.load(values);
+// flags.name.isSome() ...
+// flags.debug ...
+// -------------------------------------------------------------
+//
+// You can also compose flags provided that each has used "virtual
+// inheritance":
+// -------------------------------------------------------------
+// Flags<MyFlags1, MyFlags2> flags;
+// flags.add(...); // Any other flags you want to throw in there.
+// flags.load(values);
+// flags.flag_from_myflags1 ...
+// flags.flag_from_myflags2 ...
+// -------------------------------------------------------------
+//
+// "Fail early, fail often":
+//
+// You can not add duplicate flags, this is checked for you at compile
+// time for composite flags (e.g., Flag<MyFlags1, MyFlags2>) and also
+// checked at runtime for any other flags added via inheritance or
+// Flags::add(...).
+//
+// Flags that can not be loaded (e.g., attempting to use the 'no-'
+// prefix for a flag that is not boolean) will print a message to
+// standard error and abort the process.
+
+// TODO(benh): Provide a boolean which specifies whether or not to
+// abort on duplicates or load errors.
+
+// TODO(benh): Make prefix for environment variables configurable
+// (e.g., "MESOS_").
+
+#endif // __STOUT_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/stout/include/stout/flags/flag.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags/flag.hpp b/third_party/libprocess/third_party/stout/include/stout/flags/flag.hpp
new file mode 100644
index 0000000..d31c984
--- /dev/null
+++ b/third_party/libprocess/third_party/stout/include/stout/flags/flag.hpp
@@ -0,0 +1,26 @@
+#ifndef __STOUT_FLAGS_FLAG_HPP__
+#define __STOUT_FLAGS_FLAG_HPP__
+
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+namespace flags {
+
+// Forward declaration.
+class FlagsBase;
+
+struct Flag
+{
+ std::string name;
+ std::string help;
+ bool boolean;
+ std::tr1::function<Try<Nothing>(FlagsBase*, const std::string&)> loader;
+};
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_FLAG_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags/flags.hpp b/third_party/libprocess/third_party/stout/include/stout/flags/flags.hpp
new file mode 100644
index 0000000..77d36e6
--- /dev/null
+++ b/third_party/libprocess/third_party/stout/include/stout/flags/flags.hpp
@@ -0,0 +1,481 @@
+#ifndef __STOUT_FLAGS_FLAGS_HPP__
+#define __STOUT_FLAGS_FLAGS_HPP__
+
+#include <stdlib.h> // For abort.
+
+#include <map>
+#include <string>
+#include <typeinfo> // For typeid.
+
+#include <tr1/functional>
+
+#include <stout/error.hpp>
+#include <stout/exit.hpp>
+#include <stout/foreach.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/os.hpp>
+#include <stout/stringify.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+
+#include <stout/flags/flag.hpp>
+#include <stout/flags/loader.hpp>
+#include <stout/flags/parse.hpp>
+
+namespace flags {
+
+class FlagsBase
+{
+public:
+ virtual ~FlagsBase() {}
+
+ // Load any flags from the environment given the variable prefix,
+ // i.e., given prefix 'STOUT_' will load a flag named 'foo' via
+ // environment variables 'STOUT_foo' or 'STOUT_FOO'.
+ virtual Try<Nothing> load(
+ const std::string& prefix,
+ bool unknowns = false);
+
+ // Load any flags from the environment given the variable prefix
+ // (see above) followed by loading from the command line (via 'argc'
+ // and 'argv'). If 'unknowns' is true then we'll ignore unknown
+ // flags we see while loading. If 'duplicates' is true then we'll
+ // ignore any duplicates we see while loading.
+ virtual Try<Nothing> load(
+ const Option<std::string>& prefix,
+ int argc,
+ char** argv,
+ bool unknowns = false,
+ bool duplicates = false);
+
+ Try<Nothing> load(
+ const std::string& prefix,
+ int argc,
+ char** argv,
+ bool unknowns = false,
+ bool duplicates = false);
+
+ virtual Try<Nothing> load(
+ const std::map<std::string, Option<std::string> >& values,
+ bool unknowns = false);
+
+ virtual Try<Nothing> load(
+ const std::map<std::string, std::string>& values,
+ bool unknowns = false);
+
+ // Returns a string describing the flags.
+ std::string usage() const;
+
+ typedef std::map<std::string, Flag>::const_iterator const_iterator;
+
+ const_iterator begin() const { return flags.begin(); }
+ const_iterator end() const { return flags.end(); }
+
+ template <typename T1, typename T2>
+ void add(T1* t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2);
+
+ template <typename T>
+ void add(Option<T>* option,
+ const std::string& name,
+ const std::string& help);
+
+protected:
+ template <typename Flags, typename T1, typename T2>
+ void add(T1 Flags::*t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2);
+
+ template <typename Flags, typename T>
+ void add(Option<T> Flags::*option,
+ const std::string& name,
+ const std::string& help);
+
+ void add(const Flag& flag);
+
+private:
+ std::map<std::string, Flag> flags;
+};
+
+
+// Need to declare/define some explicit subclasses of FlagsBase so
+// that we can overload the 'Flags::operator FlagsN () const'
+// functions for each possible type.
+class _Flags1 : public virtual FlagsBase {};
+class _Flags2 : public virtual FlagsBase {};
+class _Flags3 : public virtual FlagsBase {};
+class _Flags4 : public virtual FlagsBase {};
+class _Flags5 : public virtual FlagsBase {};
+
+
+// TODO(benh): Add some "type constraints" for template paramters to
+// make sure they are all of type FlagsBase.
+template <typename Flags1 = _Flags1,
+ typename Flags2 = _Flags2,
+ typename Flags3 = _Flags3,
+ typename Flags4 = _Flags4,
+ typename Flags5 = _Flags5>
+class Flags : public virtual Flags1,
+ public virtual Flags2,
+ public virtual Flags3,
+ public virtual Flags4,
+ public virtual Flags5 {};
+
+
+template <typename T1, typename T2>
+void FlagsBase::add(
+ T1* t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2)
+{
+ *t1 = t2; // Set the default.
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T1) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &Loader<T1>::load,
+ t1,
+ std::tr1::function<Try<T1>(const std::string&)>(
+ std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
+
+ // Update the help string to include the default value.
+ flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
+ ? " (default: " // On same line, add space.
+ : "(default: "; // On newline.
+ flag.help += stringify(t2);
+ flag.help += ")";
+
+ FlagsBase::add(flag);
+}
+
+
+template <typename T>
+void FlagsBase::add(
+ Option<T>* option,
+ const std::string& name,
+ const std::string& help)
+{
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &OptionLoader<T>::load,
+ option,
+ std::tr1::function<Try<T>(const std::string&)>(
+ std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
+
+ FlagsBase::add(flag);
+}
+
+
+template <typename Flags, typename T1, typename T2>
+void FlagsBase::add(
+ T1 Flags::*t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2)
+{
+ Flags* flags = dynamic_cast<Flags*>(this);
+ if (flags == NULL) {
+ std::cerr << "Attempted to add flag '" << name
+ << "' with incompatible type" << std::endl;
+ abort();
+ } else {
+ flags->*t1 = t2; // Set the default.
+ }
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T1) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &MemberLoader<Flags, T1>::load,
+ std::tr1::placeholders::_1,
+ t1,
+ std::tr1::function<Try<T1>(const std::string&)>(
+ std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2);
+
+ // Update the help string to include the default value.
+ flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
+ ? " (default: " // On same line, add space.
+ : "(default: "; // On newline.
+ flag.help += stringify(t2);
+ flag.help += ")";
+
+ add(flag);
+}
+
+
+template <typename Flags, typename T>
+void FlagsBase::add(
+ Option<T> Flags::*option,
+ const std::string& name,
+ const std::string& help)
+{
+ Flags* flags = dynamic_cast<Flags*>(this);
+ if (flags == NULL) {
+ std::cerr << "Attempted to add flag '" << name
+ << "' with incompatible type" << std::endl;
+ abort();
+ }
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &OptionMemberLoader<Flags, T>::load,
+ std::tr1::placeholders::_1,
+ option,
+ std::tr1::function<Try<T>(const std::string&)>(
+ std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2);
+
+ add(flag);
+}
+
+
+inline void FlagsBase::add(const Flag& flag)
+{
+ if (flags.count(flag.name) > 0) {
+ EXIT(1) << "Attempted to add duplicate flag '" << flag.name << "'";
+ } else if (flag.name.find("no-") == 0) {
+ EXIT(1) << "Attempted to add flag '" << flag.name
+ << "' that starts with the reserved 'no-' prefix";
+ }
+
+ flags[flag.name] = flag;
+}
+
+
+// Extract environment variable "flags" with the specified prefix.
+inline std::map<std::string, Option<std::string> > extract(
+ const std::string& prefix)
+{
+ char** environ = os::environ();
+
+ std::map<std::string, Option<std::string> > values;
+
+ for (int i = 0; environ[i] != NULL; i++) {
+ std::string variable = environ[i];
+ if (variable.find(prefix) == 0) {
+ size_t eq = variable.find_first_of("=");
+ if (eq == std::string::npos) {
+ continue; // Not expecting a missing '=', but ignore anyway.
+ }
+ std::string name = variable.substr(prefix.size(), eq - prefix.size());
+ name = strings::lower(name); // Allow PREFIX_NAME or PREFIX_name.
+ std::string value = variable.substr(eq + 1);
+ values[name] = Option<std::string>::some(value);
+ }
+ }
+
+ return values;
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::string& prefix,
+ bool unknowns)
+{
+ return load(extract(prefix), unknowns);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const Option<std::string>& prefix,
+ int argc,
+ char** argv,
+ bool unknowns,
+ bool duplicates)
+{
+ std::map<std::string, Option<std::string> > values;
+
+ if (prefix.isSome()) {
+ values = extract(prefix.get());
+ }
+
+ // Read flags from the command line.
+ for (int i = 1; i < argc; i++) {
+ const std::string arg(argv[i]);
+
+ std::string name;
+ Option<std::string> value = None();
+ if (arg.find("--") == 0) {
+ size_t eq = arg.find_first_of("=");
+ if (eq == std::string::npos && arg.find("--no-") == 0) { // --no-name
+ name = arg.substr(2);
+ } else if (eq == std::string::npos) { // --name
+ name = arg.substr(2);
+ } else { // --name=value
+ name = arg.substr(2, eq - 2);
+ value = arg.substr(eq + 1);
+ }
+ }
+ name = strings::lower(name);
+
+ if (!duplicates) {
+ if (values.count(name) > 0 ||
+ (name.find("no-") == 0 && values.count(name.substr(3)) > 0)) {
+ return Error("Duplicate flag '" + name + "' on command line");
+ }
+ }
+
+ values[name] = value;
+ }
+
+ return load(values, unknowns);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::string& prefix,
+ int argc,
+ char** argv,
+ bool unknowns,
+ bool duplicates)
+{
+ return load(Option<std::string>::some(prefix),
+ argc,
+ argv,
+ unknowns,
+ duplicates);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::map<std::string, Option<std::string> >& values,
+ bool unknowns)
+{
+ std::map<std::string, Option<std::string> >::const_iterator iterator;
+
+ for (iterator = values.begin(); iterator != values.end(); ++iterator) {
+ const std::string& name = iterator->first;
+ const Option<std::string>& value = iterator->second;
+
+ if (flags.count(name) > 0) {
+ if (value.isSome()) { // --name=value
+ if (flags[name].boolean && value.get() == "") {
+ flags[name].loader(this, "true"); // Should never fail.
+ } else {
+ Try<Nothing> loader = flags[name].loader(this, value.get());
+ if (loader.isError()) {
+ return Error(
+ "Failed to load flag '" + name + "': " + loader.error());
+ }
+ }
+ } else { // --name
+ if (flags[name].boolean) {
+ flags[name].loader(this, "true"); // Should never fail.
+ } else {
+ return Error(
+ "Failed to load non-boolean flag '" + name + "': Missing value");
+ }
+ }
+ } else if (name.find("no-") == 0) {
+ if (flags.count(name.substr(3)) > 0) { // --no-name
+ if (flags[name.substr(3)].boolean) {
+ if (value.isNone() || value.get() == "") {
+ flags[name.substr(3)].loader(this, "false"); // Should never fail.
+ } else {
+ return Error(
+ "Failed to load boolean flag '" + name.substr(3) +
+ "' via '" + name + "' with value '" + value.get() + "'");
+ }
+ } else {
+ return Error(
+ "Failed to load non-boolean flag '" + name.substr(3) +
+ "' via '" + name + "'");
+ }
+ } else {
+ return Error(
+ "Failed to load unknown flag '" + name.substr(3) +
+ "' via '" + name + "'");
+ }
+ } else if (!unknowns) {
+ return Error("Failed to load unknown flag '" + name + "'");
+ }
+ }
+
+ return Nothing();
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::map<std::string, std::string>& _values,
+ bool unknowns)
+{
+ std::map<std::string, Option<std::string> > values;
+ std::map<std::string, std::string>::const_iterator iterator;
+ for (iterator = _values.begin(); iterator != _values.end(); ++iterator) {
+ const std::string& name = iterator->first;
+ const std::string& value = iterator->second;
+ values[name] = Option<std::string>::some(value);
+ }
+ return load(values, unknowns);
+}
+
+
+inline std::string FlagsBase::usage() const
+{
+ const int PAD = 5;
+
+ std::string usage;
+
+ std::map<std::string, std::string> col1; // key -> col 1 string
+
+ // Construct string for the first column and store width of column.
+ size_t width = 0;
+
+ foreachvalue (const flags::Flag& flag, *this) {
+ if (flag.boolean) {
+ col1[flag.name] = " --[no-]" + flag.name;
+ } else {
+ col1[flag.name] = " --" + flag.name + "=VALUE";
+ }
+ width = std::max(width, col1[flag.name].size());
+ }
+
+ foreachvalue (const flags::Flag& flag, *this) {
+ std::string line = col1[flag.name];
+
+ std::string pad(PAD + width - line.size(), ' ');
+ line += pad;
+
+ size_t pos1 = 0, pos2 = 0;
+ pos2 = flag.help.find_first_of("\n\r", pos1);
+ line += flag.help.substr(pos1, pos2 - pos1) + "\n";
+ usage += line;
+
+ while (pos2 != std::string::npos) { // Handle multi-line help strings.
+ line = "";
+ pos1 = pos2 + 1;
+ std::string pad2(PAD + width, ' ');
+ line += pad2;
+ pos2 = flag.help.find_first_of("\n\r", pos1);
+ line += flag.help.substr(pos1, pos2 - pos1) + "\n";
+ usage += line;
+ }
+ }
+ return usage;
+}
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/stout/include/stout/flags/loader.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags/loader.hpp b/third_party/libprocess/third_party/stout/include/stout/flags/loader.hpp
new file mode 100644
index 0000000..e5eaf24
--- /dev/null
+++ b/third_party/libprocess/third_party/stout/include/stout/flags/loader.hpp
@@ -0,0 +1,109 @@
+#ifndef __STOUT_FLAGS_LOADER_HPP__
+#define __STOUT_FLAGS_LOADER_HPP__
+
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+#include <stout/flags/parse.hpp>
+
+namespace flags {
+
+// Forward declaration.
+class FlagsBase;
+
+template <typename T>
+struct Loader
+{
+ static Try<Nothing> load(
+ T* flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ *flag = t.get();
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename T>
+struct OptionLoader
+{
+ static Try<Nothing> load(
+ Option<T>* flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ *flag = Option<T>::some(t.get());
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename F, typename T>
+struct MemberLoader
+{
+ static Try<Nothing> load(
+ FlagsBase* base,
+ T F::*flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ F* f = dynamic_cast<F*>(base);
+ if (f != NULL) {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ f->*flag = t.get();
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename F, typename T>
+struct OptionMemberLoader
+{
+ static Try<Nothing> load(
+ FlagsBase* base,
+ Option<T> F::*flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ F* f = dynamic_cast<F*>(base);
+ if (f != NULL) {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ f->*flag = Option<T>::some(t.get());
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ }
+ return Nothing();
+ }
+};
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_LOADER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/stout/include/stout/flags/parse.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags/parse.hpp b/third_party/libprocess/third_party/stout/include/stout/flags/parse.hpp
new file mode 100644
index 0000000..54eb35c
--- /dev/null
+++ b/third_party/libprocess/third_party/stout/include/stout/flags/parse.hpp
@@ -0,0 +1,55 @@
+#ifndef __STOUT_FLAGS_PARSE_HPP__
+#define __STOUT_FLAGS_PARSE_HPP__
+
+#include <sstream> // For istringstream.
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/duration.hpp>
+#include <stout/error.hpp>
+#include <stout/try.hpp>
+
+namespace flags {
+
+template <typename T>
+Try<T> parse(const std::string& value)
+{
+ T t;
+ std::istringstream in(value);
+ in >> t;
+ if (!in.good() && !in.eof()) {
+ return Error("Failed to convert into required type");
+ }
+ return t;
+}
+
+
+template <>
+inline Try<std::string> parse(const std::string& value)
+{
+ return value;
+}
+
+
+template <>
+inline Try<bool> parse(const std::string& value)
+{
+ if (value == "true" || value == "1") {
+ return true;
+ } else if (value == "false" || value == "0") {
+ return false;
+ }
+ return Error("Expecting a boolean (e.g., true or false)");
+}
+
+
+template <>
+inline Try<Duration> parse(const std::string& value)
+{
+ return Duration::parse(value);
+}
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_PARSE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/stout/include/stout/os.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/os.hpp b/third_party/libprocess/third_party/stout/include/stout/os.hpp
index 00b2313..28a08cc 100644
--- a/third_party/libprocess/third_party/stout/include/stout/os.hpp
+++ b/third_party/libprocess/third_party/stout/include/stout/os.hpp
@@ -1,6 +1,9 @@
#ifndef __STOUT_OS_HPP__
#define __STOUT_OS_HPP__
+#ifdef __APPLE__
+#include <crt_externs.h> // For _NSGetEnviron().
+#endif
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -55,8 +58,27 @@
({ (void)ret; *(result) = gethostbyname2(name, af); 0; })
#endif // __APPLE__
+// Need to declare 'environ' pointer for non OS X platforms.
+#ifndef __APPLE__
+extern char** environ;
+#endif
+
namespace os {
+inline char** environ()
+{
+ // Accessing the list of environment variables is platform-specific.
+ // On OS X, the 'environ' symbol isn't visible to shared libraries,
+ // so we must use the _NSGetEnviron() function (see 'man environ' on
+ // OS X). On other platforms, it's fine to access 'environ' from
+ // shared libraries.
+#ifdef __APPLE__
+ return *_NSGetEnviron();
+#endif
+ return ::environ;
+}
+
+
// Checks if the specified key is in the environment variables.
inline bool hasenv(const std::string& key)
{
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/190a3bb8/third_party/libprocess/third_party/stout/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/flags_tests.cpp b/third_party/libprocess/third_party/stout/tests/flags_tests.cpp
new file mode 100644
index 0000000..2809280
--- /dev/null
+++ b/third_party/libprocess/third_party/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());
+}
[05/35] Updated libprocess to use '3rdparty' instead of 'third_party'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/proc.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/proc.hpp b/third_party/libprocess/3rdparty/stout/include/stout/proc.hpp
new file mode 100644
index 0000000..b59735f
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/protobuf.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/protobuf.hpp b/third_party/libprocess/3rdparty/stout/include/stout/protobuf.hpp
new file mode 100644
index 0000000..eb79e7b
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/result.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/result.hpp b/third_party/libprocess/3rdparty/stout/include/stout/result.hpp
new file mode 100644
index 0000000..f918f86
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/stopwatch.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/stopwatch.hpp b/third_party/libprocess/3rdparty/stout/include/stout/stopwatch.hpp
new file mode 100644
index 0000000..bcff8c6
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/stringify.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/stringify.hpp b/third_party/libprocess/3rdparty/stout/include/stout/stringify.hpp
new file mode 100644
index 0000000..136316d
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/strings.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/strings.hpp b/third_party/libprocess/3rdparty/stout/include/stout/strings.hpp
new file mode 100644
index 0000000..ed14106
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/try.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/try.hpp b/third_party/libprocess/3rdparty/stout/include/stout/try.hpp
new file mode 100644
index 0000000..787bffd
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/utils.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/utils.hpp b/third_party/libprocess/3rdparty/stout/include/stout/utils.hpp
new file mode 100644
index 0000000..0f4bba2
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/uuid.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/uuid.hpp b/third_party/libprocess/3rdparty/stout/include/stout/uuid.hpp
new file mode 100644
index 0000000..c6c290d
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/install-sh
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/install-sh b/third_party/libprocess/3rdparty/stout/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/m4/acx_pthread.m4
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/m4/acx_pthread.m4 b/third_party/libprocess/3rdparty/stout/m4/acx_pthread.m4
new file mode 100644
index 0000000..2cf20de
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/bytes_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/bytes_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/bytes_tests.cpp
new file mode 100644
index 0000000..18b2474
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/duration_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/duration_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/duration_tests.cpp
new file mode 100644
index 0000000..e0910d4
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/error_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/error_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/error_tests.cpp
new file mode 100644
index 0000000..75e365e
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/flags_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/flags_tests.cpp
new file mode 100644
index 0000000..2809280
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/gzip_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/gzip_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/gzip_tests.cpp
new file mode 100644
index 0000000..13296d8
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/hashset_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/hashset_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/hashset_tests.cpp
new file mode 100644
index 0000000..72f65c4
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/json_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/json_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/json_tests.cpp
new file mode 100644
index 0000000..c582d70
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/main.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/main.cpp b/third_party/libprocess/3rdparty/stout/tests/main.cpp
new file mode 100644
index 0000000..0f1e9cb
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/multimap_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/multimap_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/multimap_tests.cpp
new file mode 100644
index 0000000..79e7200
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/none_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/none_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/none_tests.cpp
new file mode 100644
index 0000000..38d25bb
--- /dev/null
+++ b/third_party/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());
+}
[09/35] Replaced flags and configurator in Mesos with flags in stout.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/tests/configurator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/configurator_tests.cpp b/src/tests/configurator_tests.cpp
deleted file mode 100644
index b82f5c2..0000000
--- a/src/tests/configurator_tests.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/**
- * 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 <gtest/gtest.h>
-
-#include <stout/gtest.hpp>
-#include <stout/os.hpp>
-
-#include "configurator/configurator.hpp"
-
-#include "tests/utils.hpp"
-
-using std::string;
-
-using namespace mesos;
-using namespace mesos::internal;
-using namespace mesos::internal::tests;
-
-
-class ConfiguratorTest : public TemporaryDirectoryTest {};
-
-
-TEST_F(ConfiguratorTest, Environment)
-{
- setenv("MESOS_TEST", "working", true);
- Configurator conf;
- conf.load();
- unsetenv("MESOS_TEST");
-
- EXPECT_EQ("working", conf.getConfiguration()["test"]);
-}
-
-
-TEST_F(ConfiguratorTest, DefaultOptions)
-{
- const int ARGC = 5;
- char* argv[ARGC];
- argv[0] = (char*) "bin/filename";
- argv[1] = (char*) "--test1=501";
- argv[2] = (char*) "--test2";
- argv[3] = (char*) "--excp=txt";
- argv[4] = (char*) "--test8=foo";
-
- Configurator conf;
-
- EXPECT_NO_THROW(conf.addOption<int>("test1", "Testing option", 500));
- EXPECT_NO_THROW(conf.addOption<bool>("test2", "Another tester", 0));
- EXPECT_NO_THROW(conf.addOption<long>("test3", "Tests the default", 2010));
- EXPECT_NO_THROW(conf.addOption<string>("test4", "Option without default"));
- EXPECT_NO_THROW(conf.addOption<string>("test5", "Option with a default",
- "default"));
- EXPECT_NO_THROW(conf.addOption<bool>("test6", "Toggler...", false));
- EXPECT_NO_THROW(conf.addOption<bool>("test7", "Toggler...", true));
- EXPECT_NO_THROW(conf.addOption<string>("test8", "Overridden default",
- "default"));
- EXPECT_NO_THROW(conf.load(ARGC, argv));
-
- EXPECT_NO_THROW(conf.addOption<int>("excp", "Exception tester.", 50));
- EXPECT_THROW(conf.validate(), ConfigurationException);
- conf.getConfiguration()["excp"] = "27";
- EXPECT_NO_THROW(conf.validate());
-
- EXPECT_EQ("501", conf.getConfiguration()["test1"]);
- EXPECT_EQ("1", conf.getConfiguration()["test2"]);
- EXPECT_EQ("2010", conf.getConfiguration()["test3"]);
- EXPECT_EQ("", conf.getConfiguration()["test4"]);
- EXPECT_EQ("default", conf.getConfiguration()["test5"]);
- EXPECT_EQ("27", conf.getConfiguration()["excp"]);
- EXPECT_EQ("0", conf.getConfiguration()["test6"]);
- EXPECT_EQ("1", conf.getConfiguration()["test7"]);
- EXPECT_EQ("foo", conf.getConfiguration()["test8"]);
-}
-
-
-TEST_F(ConfiguratorTest, CommandLine)
-{
- const int ARGC = 12;
- char* argv[ARGC];
- argv[0] = (char*) "bin/filename";
- argv[1] = (char*) "--test1=text1";
- argv[2] = (char*) "--test2";
- argv[3] = (char*) "text2";
- argv[4] = (char*) "-N";
- argv[5] = (char*) "-25";
- argv[6] = (char*) "--cAsE=4";
- argv[7] = (char*) "--space=Long String";
- argv[8] = (char*) "--bool1";
- argv[9] = (char*) "--no-bool2";
- argv[10] = (char*) "-a";
- argv[11] = (char*) "-no-b";
-
- Configurator conf;
- EXPECT_NO_THROW(conf.addOption<int>("negative", 'N', "some val", -30));
- EXPECT_NO_THROW(conf.addOption<string>("test1", "textual value", "text2"));
- EXPECT_NO_THROW(conf.addOption<bool>("bool1", "toggler", false));
- EXPECT_NO_THROW(conf.addOption<bool>("bool2", 'z', "toggler", true));
- EXPECT_NO_THROW(conf.addOption<bool>("bool3", 'a', "toggler", false));
- EXPECT_NO_THROW(conf.addOption<bool>("bool4", 'b', "toggler", true));
-
- EXPECT_NO_THROW( conf.load(ARGC, argv) );
-
- EXPECT_EQ("text1", conf.getConfiguration()["test1"]);
- EXPECT_EQ("1", conf.getConfiguration()["test2"]);
- EXPECT_EQ("-25", conf.getConfiguration()["negative"]);
- EXPECT_EQ("4", conf.getConfiguration()["case"]);
- EXPECT_EQ("Long String", conf.getConfiguration()["space"]);
- EXPECT_EQ("1", conf.getConfiguration()["bool1"]);
- EXPECT_EQ("0", conf.getConfiguration()["bool2"]);
- EXPECT_EQ("1", conf.getConfiguration()["bool3"]);
- EXPECT_EQ("0", conf.getConfiguration()["bool4"]);
-}
-
-
-// Check whether specifying just MESOS_CONF allows a config file to be loaded
-TEST_F(ConfiguratorTest, ConfigFileWithConfDir)
-{
- ASSERT_SOME(os::mkdir("conf2"));
- ASSERT_SOME(os::write("conf2/mesos.conf",
- "test3=shake # sugar bomb\n"
- "# just a comment\n"
- "test4=milk\n"));
-
- setenv("MESOS_CONF", "conf2", 1);
- Configurator conf;
- EXPECT_NO_THROW( conf.load() );
- unsetenv("MESOS_CONF");
-
- EXPECT_EQ("shake", conf.getConfiguration()["test3"]);
- EXPECT_EQ("milk", conf.getConfiguration()["test4"]);
-}
-
-
-// Check that when we specify a conf directory on the command line,
-// we load values from the config file first and then the command line
-TEST_F(ConfiguratorTest, CommandLineConfFlag)
-{
- ASSERT_SOME(os::mkdir("bin"));
- ASSERT_SOME(os::mkdir("conf2"));
- ASSERT_SOME(os::write("conf2/mesos.conf",
- "a=1\n"
- "b=2\n"
- "c=3"));
-
- const int ARGC = 4;
- char* argv[ARGC];
- argv[0] = (char*) "bin/filename";
- argv[1] = (char*) "--conf=conf2";
- argv[2] = (char*) "--b=overridden";
- argv[3] = (char*) "--d=fromCmdLine";
-
- Configurator conf;
- EXPECT_NO_THROW( conf.load(ARGC, argv) );
-
- EXPECT_EQ("1", conf.getConfiguration()["a"]);
- EXPECT_EQ("overridden", conf.getConfiguration()["b"]);
- EXPECT_EQ("3", conf.getConfiguration()["c"]);
- EXPECT_EQ("fromCmdLine", conf.getConfiguration()["d"]);
-}
-
-
-// Check that variables are loaded with the correct priority when an
-// environment variable, a config file element , and a config flag
-// are all present. Command line flags should have the highest priority,
-// second should be environment variables, and last should be the file.
-TEST_F(ConfiguratorTest, LoadingPriorities)
-{
- ASSERT_SOME(os::mkdir("bin"));
- ASSERT_SOME(os::mkdir("conf"));
- ASSERT_SOME(os::write("conf/mesos.conf",
- "a=fromFile\n"
- "b=fromFile\n"
- "c=fromFile\n"
- "d=fromFile\n"));
-
- // Set environment to contain parameters a and b
- setenv("MESOS_A", "fromEnv", 1);
- setenv("MESOS_B", "fromEnv", 1);
- setenv("MESOS_CONF", "conf", 1);
-
- // Pass parameters a and c from the command line
- const int ARGC = 3;
- char* argv[ARGC];
- argv[0] = (char*) "bin/filename";
- argv[1] = (char*) "--a=fromCmdLine";
- argv[2] = (char*) "--c=fromCmdLine";
-
- Configurator conf;
- EXPECT_NO_THROW(conf.load(ARGC, argv));
-
- // Clear the environment vars set above
- unsetenv("MESOS_A");
- unsetenv("MESOS_B");
- unsetenv("MESOS_CONF");
-
- // Check that every variable is obtained from the highest-priority location
- // (command line > env > file)
- EXPECT_EQ("fromCmdLine", conf.getConfiguration()["a"]);
- EXPECT_EQ("fromEnv", conf.getConfiguration()["b"]);
- EXPECT_EQ("fromCmdLine", conf.getConfiguration()["c"]);
- EXPECT_EQ("fromFile", conf.getConfiguration()["d"]);
-}
-
-
-// Check that spaces before and after the = signs in config files are ignored
-TEST_F(ConfiguratorTest, ConfigFileSpacesIgnored)
-{
- ASSERT_SOME(os::mkdir("conf"));
- ASSERT_SOME(os::write("conf/mesos.conf",
- "test1=coffee # beans are tasty\n"
- "# just a comment\n"
- " \t # comment with spaces in front\n"
- "\n"
- "test2 =tea\n"
- "test3= water\n"
- " test4 = milk\n"
- " test5 = hot chocolate\t\n"
- "\ttest6 = juice# #\n"));
-
- Configurator conf;
- setenv("MESOS_CONF", "conf", 1);
- EXPECT_NO_THROW(conf.load());
- unsetenv("MESOS_CONF");
-
- EXPECT_EQ("coffee", conf.getConfiguration()["test1"]);
- EXPECT_EQ("tea", conf.getConfiguration()["test2"]);
- EXPECT_EQ("water", conf.getConfiguration()["test3"]);
- EXPECT_EQ("milk", conf.getConfiguration()["test4"]);
- EXPECT_EQ("hot chocolate", conf.getConfiguration()["test5"]);
- EXPECT_EQ("juice", conf.getConfiguration()["test6"]);
-}
-
-
-// Check that exceptions are thrown on invalid config file
-TEST_F(ConfiguratorTest, MalformedConfigFile)
-{
- ASSERT_SOME(os::mkdir("conf"));
- ASSERT_SOME(os::write("conf/mesos.conf",
- "test1=coffee\n"
- "JUNK\n"
- "test2=tea\n"));
-
- setenv("MESOS_CONF", "conf", 1);
- Configurator conf;
- EXPECT_THROW(conf.load(), ConfigurationException);
- unsetenv("MESOS_CONF");
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/tests/environment.cpp
----------------------------------------------------------------------
diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp
index d8bb5fd..125c306 100644
--- a/src/tests/environment.cpp
+++ b/src/tests/environment.cpp
@@ -29,8 +29,6 @@
#include <stout/os.hpp>
#include <stout/strings.hpp>
-#include "configurator/configurator.hpp"
-
#ifdef __linux__
#include "linux/cgroups.hpp"
#endif
@@ -191,7 +189,18 @@ Environment::~Environment()
void Environment::SetUp()
{
// Clear any MESOS_ environment variables so they don't affect our tests.
- Configurator::clearMesosEnvironmentVars();
+ char** environ = os::environ();
+ for (int i = 0; environ[i] != NULL; i++) {
+ std::string variable = environ[i];
+ if (variable.find("MESOS_") == 0) {
+ string key;
+ size_t eq = variable.find_first_of("=");
+ if (eq == string::npos) {
+ continue; // Not expecting a missing '=', but ignore anyway.
+ }
+ os::unsetenv(variable.substr(strlen("MESOS_"), eq - strlen("MESOS_")));
+ }
+ }
if (!GTEST_IS_THREADSAFE) {
EXIT(1) << "Testing environment is not thread safe, bailing!";
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/tests/flags.hpp
----------------------------------------------------------------------
diff --git a/src/tests/flags.hpp b/src/tests/flags.hpp
index 6ba5eca..b229e1f 100644
--- a/src/tests/flags.hpp
+++ b/src/tests/flags.hpp
@@ -21,10 +21,9 @@
#include <string>
+#include <stout/flags.hpp>
#include <stout/os.hpp>
-#include "flags/flags.hpp"
-
#include "logging/logging.hpp"
namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/29183c1b/src/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/flags_tests.cpp b/src/tests/flags_tests.cpp
deleted file mode 100644
index d52d4db..0000000
--- a/src/tests/flags_tests.cpp
+++ /dev/null
@@ -1,223 +0,0 @@
-/**
- * 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 <gmock/gmock.h>
-
-#include <map>
-#include <string>
-
-#include <stout/duration.hpp>
-#include <stout/gtest.hpp>
-#include <stout/none.hpp>
-#include <stout/option.hpp>
-
-#include "configurator/configuration.hpp"
-#include "configurator/configurator.hpp"
-
-#include "flags/flags.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)
-{
- 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, Configurator)
-{
- Flags<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";
-
- mesos::internal::Configurator configurator(flags);
- mesos::internal::Configuration configuration;
- try {
- configuration = configurator.load(argc, argv);
- } catch (mesos::internal::ConfigurationException& e) {
- FAIL() << "Configuration error: " << e.what();
- }
-
- flags.load(configuration.getMap());
-
- 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, 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/29183c1b/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/src/tests/main.cpp b/src/tests/main.cpp
index 868bdd5..ba9bf64 100644
--- a/src/tests/main.cpp
+++ b/src/tests/main.cpp
@@ -22,10 +22,10 @@
#include <process/process.hpp>
+#include <stout/flags.hpp>
+#include <stout/nothing.hpp>
#include <stout/os.hpp>
-
-#include "configurator/configuration.hpp"
-#include "configurator/configurator.hpp"
+#include <stout/try.hpp>
#include "logging/logging.hpp"
@@ -42,12 +42,12 @@ using std::endl;
using std::string;
-void usage(const char* argv0, const Configurator& configurator)
+void usage(const char* argv0, const flags::FlagsBase& flags)
{
cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
<< endl
<< "Supported options:" << endl
- << configurator.getUsage();
+ << flags.usage();
}
@@ -63,20 +63,18 @@ int main(int argc, char** argv)
"Prints this help message",
false);
- Configurator configurator(flags);
- Configuration configuration;
- try {
- configuration = configurator.load(argc, argv);
- } catch (ConfigurationException& e) {
- cerr << "Configuration error: " << e.what() << endl;
- usage(argv[0], configurator);
+ // Load flags from environment and command line but allow unknown
+ // flags (since we might have gtest/gmock flags as well).
+ Try<Nothing> load = flags.load("MESOS_", argc, argv, true);
+
+ if (load.isError()) {
+ cerr << load.error() << endl;
+ usage(argv[0], flags);
exit(1);
}
- flags.load(configuration.getMap());
-
if (help) {
- usage(argv[0], configurator);
+ usage(argv[0], flags);
cerr << endl;
testing::InitGoogleTest(&argc, argv); // Get usage from gtest too.
exit(1);
[21/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/format.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/format.hpp b/third_party/libprocess/3rdparty/stout/include/stout/format.hpp
deleted file mode 100644
index 71b5986..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/format.hpp
+++ /dev/null
@@ -1,343 +0,0 @@
-#ifndef __STOUT_FORMAT_HPP__
-#define __STOUT_FORMAT_HPP__
-
-#include <stdarg.h> // For 'va_list', 'va_start', 'va_end'.
-#include <stdio.h> // For 'vasprintf'.
-
-#include <string>
-
-#include <tr1/type_traits> // For 'is_pod'.
-
-#include "error.hpp"
-#include "try.hpp"
-#include "stringify.hpp"
-
-
-// The 'strings::format' functions produces strings based on the
-// printf family of functions. Except, unlike the printf family of
-// functions, the 'strings::format' routines attempt to "stringify"
-// any arguments that are not POD types (i.e., "plain old data":
-// primitives, pointers, certain structs/classes and unions,
-// etc). This enables passing structs/classes to 'strings::format'
-// provided there is a definition/specialization of 'ostream::operator
-// <<' available for that type. Note that the '%s' format specifier is
-// expected for each argument that gets stringified. A specialization
-// for std::string is also provided so that std::string::c_str is not
-// necessary (but again, '%s' is expected as the format specifier).
-
-namespace strings {
-namespace internal {
-
-Try<std::string> format(const std::string& fmt, va_list args);
-Try<std::string> format(const std::string& fmt, ...);
-
-template <typename T, bool b>
-struct stringify;
-
-} // namespace internal {
-
-
-#if __cplusplus >= 201103L
-template <typename ...T>
-Try<std::string> format(const std::string& s, const T& ...t)
-{
- return internal::format(
- s,
- internal::stringify<T, !std::is_pod<T>::value>(t).get()...);
-}
-#else
-template <typename T1>
-Try<std::string> format(const std::string& s,
- const T1& t1)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get());
-}
-
-
-template <typename T1,
- typename T2>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T1>::value>(t2).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6,
- typename T7>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6,
- const T7& t7)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
- internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6,
- typename T7,
- typename T8>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6,
- const T7& t7,
- const T8& t8)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
- internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
- internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6,
- typename T7,
- typename T8,
- typename T9>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6,
- const T7& t7,
- const T8& t8,
- const T9& t9)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
- internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
- internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get(),
- internal::stringify<T9, !std::tr1::is_pod<T9>::value>(t9).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6,
- typename T7,
- typename T8,
- typename T9,
- typename T10>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6,
- const T7& t7,
- const T8& t8,
- const T9& t9,
- const T10& t10)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
- internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
- internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get(),
- internal::stringify<T9, !std::tr1::is_pod<T9>::value>(t9).get(),
- internal::stringify<T10, !std::tr1::is_pod<T10>::value>(t10).get());
-}
-#endif // __cplusplus >= 201103L
-
-
-namespace internal {
-
-inline Try<std::string> format(const std::string& fmt, va_list args)
-{
- char* temp;
- if (vasprintf(&temp, fmt.c_str(), args) == -1) {
- // Note that temp is undefined, so we do not need to call free.
- return Error("Failed to format '" + fmt + "' (possibly out of memory)");
- }
- std::string result(temp);
- free(temp);
- return result;
-}
-
-
-inline Try<std::string> format(const std::string& fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- const Try<std::string>& result = format(fmt, args);
- va_end(args);
- return result;
-}
-
-
-template <typename T>
-struct stringify<T, false>
-{
- stringify(const T& _t) : t(_t) {}
- const T& get() { return t; }
- const T& t;
-};
-
-
-template <typename T>
-struct stringify<T, true>
-{
- stringify(const T& _t) : s(::stringify(_t)) {}
- const char* get() { return s.c_str(); }
-
- // NOTE: We need to do the copy here, because the temporary returned by
- // ::stringify() doesn't outlive the get() call inside strings::format().
- // TODO(vinod): Figure out a fix for using const ref here.
- const std::string s;
-};
-
-
-template <>
-struct stringify<std::string, true>
-{
- stringify(const std::string& _s) : s(_s) {}
- const char* get() { return s.c_str(); }
- const std::string& s;
-};
-
-} // namespace internal {
-} // namespace strings {
-
-#endif // __STOUT_FORMAT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/fs.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/fs.hpp b/third_party/libprocess/3rdparty/stout/include/stout/fs.hpp
deleted file mode 100644
index c1a05b5..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/fs.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef __STOUT_FS_HPP__
-#define __STOUT_FS_HPP__
-
-#include <unistd.h> // For symlink.
-
-#include <sys/statvfs.h>
-
-#include <string>
-
-#include "bytes.hpp"
-#include "error.hpp"
-#include "nothing.hpp"
-#include "try.hpp"
-
-// TODO(bmahler): Migrate the appropriate 'os' namespace funtions here.
-namespace fs {
-
-// Returns the total available disk size in bytes.
-inline Try<Bytes> available(const std::string& path = "/")
-{
- struct statvfs buf;
- if (::statvfs(path.c_str(), &buf) < 0) {
- return ErrnoError();
- }
- return Bytes(buf.f_bavail * buf.f_frsize);
-}
-
-
-// Returns relative disk usage of the file system that the given path
-// is mounted at.
-inline Try<double> usage(const std::string& path = "/")
-{
- struct statvfs buf;
- if (statvfs(path.c_str(), &buf) < 0) {
- return ErrnoError("Error invoking statvfs on '" + path + "'");
- }
- return (double) (buf.f_blocks - buf.f_bfree) / buf.f_blocks;
-}
-
-
-inline Try<Nothing> symlink(
- const std::string& original,
- const std::string& link)
-{
- if (::symlink(original.c_str(), link.c_str()) < 0) {
- return ErrnoError();
- }
- return Nothing();
-}
-
-} // namespace fs {
-
-#endif // __STOUT_FS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/gtest.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/gtest.hpp b/third_party/libprocess/3rdparty/stout/include/stout/gtest.hpp
deleted file mode 100644
index 3c34124..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/gtest.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef __STOUT_GTEST_HPP__
-#define __STOUT_GTEST_HPP__
-
-#include <gtest/gtest.h>
-
-#include <string>
-
-#include <stout/option.hpp>
-#include <stout/result.hpp>
-#include <stout/try.hpp>
-
-
-template <typename T>
-::testing::AssertionResult AssertSome(
- const char* expr,
- const Option<T>& actual)
-{
- if (actual.isNone()) {
- return ::testing::AssertionFailure()
- << expr << " is NONE";
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T>
-::testing::AssertionResult AssertSome(
- const char* expr,
- const Try<T>& actual)
-{
- if (actual.isError()) {
- return ::testing::AssertionFailure()
- << expr << ": " << actual.error();
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T>
-::testing::AssertionResult AssertSome(
- const char* expr,
- const Result<T>& actual)
-{
- if (actual.isNone()) {
- return ::testing::AssertionFailure()
- << expr << " is NONE";
- } else if (actual.isError()) {
- return ::testing::AssertionFailure()
- << expr << ": " << actual.error();
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T1, typename T2>
-::testing::AssertionResult AssertSomeEq(
- const char* expectedExpr,
- const char* actualExpr,
- const T1& expected,
- const T2& actual) // Duck typing!
-{
- const ::testing::AssertionResult result = AssertSome(actualExpr, actual);
-
- if (result) {
- if (expected == actual.get()) {
- return ::testing::AssertionSuccess();
- } else {
- return ::testing::AssertionFailure()
- << "Value of: (" << actualExpr << ").get()\n"
- << " Actual: " << ::testing::PrintToString(actual.get()) << "\n"
- << "Expected: " << expectedExpr << "\n"
- << "Which is: " << ::testing::PrintToString(expected);
- }
- }
-
- return result;
-}
-
-
-#define ASSERT_SOME(actual) \
- ASSERT_PRED_FORMAT1(AssertSome, actual)
-
-
-#define EXPECT_SOME(actual) \
- EXPECT_PRED_FORMAT1(AssertSome, actual)
-
-
-#define ASSERT_SOME_EQ(expected, actual) \
- ASSERT_PRED_FORMAT2(AssertSomeEq, expected, actual)
-
-
-#define EXPECT_SOME_EQ(expected, actual) \
- EXPECT_PRED_FORMAT2(AssertSomeEq, expected, actual)
-
-
-#define ASSERT_SOME_TRUE(actual) \
- ASSERT_PRED_FORMAT2(AssertSomeEq, true, actual)
-
-
-#define EXPECT_SOME_TRUE(actual) \
- EXPECT_PRED_FORMAT2(AssertSomeEq, true, actual)
-
-
-#define ASSERT_SOME_FALSE(actual) \
- ASSERT_PRED_FORMAT2(AssertSomeEq, false, actual)
-
-
-#define EXPECT_SOME_FALSE(actual) \
- EXPECT_PRED_FORMAT2(AssertSomeEq, false, actual)
-
-
-#define ASSERT_ERROR(actual) \
- ASSERT_TRUE(actual.isError())
-
-
-#define EXPECT_ERROR(actual) \
- EXPECT_TRUE(actual.isError())
-
-#endif // __STOUT_GTEST_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/gzip.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/gzip.hpp b/third_party/libprocess/3rdparty/stout/include/stout/gzip.hpp
deleted file mode 100644
index ef36f1b..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/gzip.hpp
+++ /dev/null
@@ -1,149 +0,0 @@
-#ifndef __STOUT_GZIP_HPP__
-#define __STOUT_GZIP_HPP__
-
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-#include <string>
-
-#include "error.hpp"
-#include "try.hpp"
-
-// Compression utilities.
-// TODO(bmahler): Provide streaming compression / decompression as well.
-namespace gzip {
-
-// We use a 16KB buffer with zlib compression / decompression.
-#define GZIP_BUFFER_SIZE 16384
-
-// Returns a gzip compressed version of the provided string.
-// The compression level should be within the range [-1, 9].
-// See zlib.h:
-// #define Z_NO_COMPRESSION 0
-// #define Z_BEST_SPEED 1
-// #define Z_BEST_COMPRESSION 9
-// #define Z_DEFAULT_COMPRESSION (-1)
-inline Try<std::string> compress(
- const std::string& decompressed,
-#ifdef HAVE_LIBZ
- int level = Z_DEFAULT_COMPRESSION)
-#else
- int level = -1)
-#endif
-{
-#ifndef HAVE_LIBZ
- return Error("libz is not available");
-#else
- // Verify the level is within range.
- if (!(level == Z_DEFAULT_COMPRESSION ||
- (level >= Z_NO_COMPRESSION && level <= Z_BEST_COMPRESSION))) {
- return Error("Invalid compression level: " + level);
- }
-
- z_stream_s stream;
- stream.next_in =
- const_cast<Bytef*>(reinterpret_cast<const Bytef*>(decompressed.data()));
- stream.avail_in = decompressed.length();
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = Z_NULL;
-
- int code = deflateInit2(
- &stream,
- level, // Compression level.
- Z_DEFLATED, // Compression method.
- MAX_WBITS + 16, // Zlib magic for gzip compression / decompression.
- 8, // Default memLevel value.
- Z_DEFAULT_STRATEGY);
-
- if (code != Z_OK) {
- return Error("Failed to initialize zlib: " + std::string(stream.msg));
- }
-
- // Build up the compressed result.
- Bytef buffer[GZIP_BUFFER_SIZE];
- std::string result = "";
- do {
- stream.next_out = buffer;
- stream.avail_out = GZIP_BUFFER_SIZE;
- code = deflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
-
- if (code != Z_OK && code != Z_STREAM_END) {
- Error error(std::string(stream.msg));
- deflateEnd(&stream);
- return error;
- }
-
- // Consume output and reset the buffer.
- result.append(
- reinterpret_cast<char*>(buffer),
- GZIP_BUFFER_SIZE - stream.avail_out);
- stream.next_out = buffer;
- stream.avail_out = GZIP_BUFFER_SIZE;
- } while (code != Z_STREAM_END);
-
- code = deflateEnd(&stream);
- if (code != Z_OK) {
- return Error("Failed to clean up zlib: " + std::string(stream.msg));
- }
- return result;
-#endif // HAVE_LIBZ
-}
-
-
-// Returns a gzip decompressed version of the provided string.
-inline Try<std::string> decompress(const std::string& compressed)
-{
-#ifndef HAVE_LIBZ
- return Error("libz is not available");
-#else
- z_stream_s stream;
- stream.next_in =
- const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
- stream.avail_in = compressed.length();
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = Z_NULL;
-
- int code = inflateInit2(
- &stream,
- MAX_WBITS + 16); // Zlib magic for gzip compression / decompression.
-
- if (code != Z_OK) {
- return Error("Failed to initialize zlib: " + std::string(stream.msg));
- }
-
- // Build up the decompressed result.
- Bytef buffer[GZIP_BUFFER_SIZE];
- std::string result = "";
- do {
- stream.next_out = buffer;
- stream.avail_out = GZIP_BUFFER_SIZE;
- code = inflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
-
- if (code != Z_OK && code != Z_STREAM_END) {
- Error error(std::string(stream.msg));
- inflateEnd(&stream);
- return error;
- }
-
- // Consume output and reset the buffer.
- result.append(
- reinterpret_cast<char*>(buffer),
- GZIP_BUFFER_SIZE - stream.avail_out);
- stream.next_out = buffer;
- stream.avail_out = GZIP_BUFFER_SIZE;
- } while (code != Z_STREAM_END);
-
- code = inflateEnd(&stream);
- if (code != Z_OK) {
- return Error("Failed to clean up zlib: " + std::string(stream.msg));
- }
- return result;
-#endif // HAVE_LIBZ
-}
-
-} // namespace gzip {
-
-#endif // __STOUT_GZIP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/hashmap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/hashmap.hpp b/third_party/libprocess/3rdparty/stout/include/stout/hashmap.hpp
deleted file mode 100644
index 796cb50..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/hashmap.hpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef __STOUT_HASHMAP_HPP__
-#define __STOUT_HASHMAP_HPP__
-
-#include <boost/get_pointer.hpp>
-#include <boost/unordered_map.hpp>
-
-#include "hashset.hpp"
-#include "foreach.hpp"
-#include "none.hpp"
-#include "option.hpp"
-
-
-// Provides a hash map via Boost's 'unordered_map'. For most intensive
-// purposes this could be accomplished with a templated typedef, but
-// those don't exist (until C++-11). Also, doing it this way allows us
-// to add functionality, or better naming of existing functionality,
-// etc.
-
-template <typename Key, typename Value>
-class hashmap : public boost::unordered_map<Key, Value>
-{
-public:
- // An explicit default constructor is needed so
- // 'const hashmap<T> map;' is not an error.
- hashmap() {}
-
- // Checks whether this map contains a binding for a key.
- bool contains(const Key& key) const
- {
- return boost::unordered_map<Key, Value>::count(key) > 0;
- }
-
- // Checks whether there exists a bound value in this map.
- bool containsValue(const Value& v) const
- {
- foreachvalue (const Value& value, *this) {
- if (value == v) {
- return true;
- }
- }
- }
-
- // Returns an Option for the binding to the key.
- Option<Value> get(const Key& key) const
- {
- typedef typename boost::unordered_map<Key, Value>::const_iterator
- const_iterator;
- const_iterator it = boost::unordered_map<Key, Value>::find(key);
- if (it == boost::unordered_map<Key, Value>::end()) {
- return None();
- }
- return it->second;
- }
-
- // Returns the set of keys in this map.
- hashset<Key> keys() const
- {
- hashset<Key> result;
- foreachkey (const Key& key, *this) {
- result.insert(key);
- }
- return result;
- }
-
- // Returns the set of values in this map.
- hashset<Value> values() const
- {
- hashset<Value> result;
- foreachvalue (const Value& value, *this) {
- result.insert(value);
- }
- return result;
- }
-
- // Checks whether there exists a value in this map that returns the
- // a result equal to 'r' when the specified method is invoked.
- template <typename R, typename T>
- bool existsValue(R (T::*method)(), R r) const
- {
- foreachvalue (const Value& value, *this) {
- const T* t = boost::get_pointer(value);
- if (t->*method() == r) {
- return true;
- }
- }
- }
-
- // Checks whether there exists a value in this map whose specified
- // member is equal to 'r'.
- template <typename R, typename T>
- bool existsValue(R (T::*member), R r) const
- {
- foreachvalue (const Value& value, *this) {
- const T* t = boost::get_pointer(value);
- if (t->*member == r) {
- return true;
- }
- }
- }
-};
-
-#endif // __STOUT_HASHMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/hashset.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/hashset.hpp b/third_party/libprocess/3rdparty/stout/include/stout/hashset.hpp
deleted file mode 100644
index f584545..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/hashset.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef __STOUT_HASHSET_HPP__
-#define __STOUT_HASHSET_HPP__
-
-#include <boost/get_pointer.hpp>
-#include <boost/unordered_set.hpp>
-
-#include "foreach.hpp"
-
-
-// Provides a hash set via Boost's 'unordered_set'. For most intensive
-// purposes this could be accomplished with a templated typedef, but
-// those don't exist (until C++-11). Also, doing it this way allows us
-// to add functionality, or better naming of existing functionality,
-// etc.
-
-template <typename Elem>
-class hashset : public boost::unordered_set<Elem>
-{
-public:
- // An explicit default constructor is needed so
- // 'const hashset<T> map;' is not an error.
- hashset() {}
-
- // Checks whether this map contains a binding for a key.
- bool contains(const Elem& elem) const
- {
- return boost::unordered_set<Elem>::count(elem) > 0;
- }
-
- // Checks whether there exists a value in this set that returns the
- // a result equal to 'r' when the specified method is invoked.
- template <typename R, typename T>
- bool exists(R (T::*method)(), R r) const
- {
- foreach (const Elem& elem, *this) {
- const T* t = boost::get_pointer(elem);
- if (t->*method() == r) {
- return true;
- }
- }
- }
-
- // Checks whether there exists an element in this set whose
- // specified member is equal to 'r'.
- template <typename R, typename T>
- bool exists(R (T::*member), R r) const
- {
- foreach (const Elem& elem, *this) {
- const T* t = boost::get_pointer(elem);
- if (t->*member == r) {
- return true;
- }
- }
- }
-};
-
-#endif // __STOUT_HASHSET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/json.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/json.hpp b/third_party/libprocess/3rdparty/stout/include/stout/json.hpp
deleted file mode 100644
index e2cd4f2..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/json.hpp
+++ /dev/null
@@ -1,202 +0,0 @@
-#ifndef __STOUT_JSON__
-#define __STOUT_JSON__
-
-#include <iomanip>
-#include <iostream>
-#include <list>
-#include <map>
-#include <string>
-
-#include <boost/variant.hpp>
-
-#include <stout/foreach.hpp>
-
-// TODO(jsirois): Implement parsing that constructs JSON objects.
-
-
-namespace JSON {
-
-// Implementation of the JavaScript Object Notation (JSON) grammar
-// using boost::variant. We explicitly define each "type" of the
-// grammar, including 'true' (json::True), 'false' (json::False), and
-// 'null' (json::Null), for clarity and also because boost::variant
-// "picks" the wrong type when we try and use std::string, long (or
-// int), double (or float), and bool all in the same variant (while it
-// does work with explicit casts, it seemed bad style to force people
-// to put those casts in place). We could have avoided using
-// json::String or json::Number and just used std::string and double
-// respectively, but we choose to include them for completeness
-// (although, this does pay a 2x cost when compiling thanks to all the
-// extra template instantiations).
-
-struct String;
-struct Number;
-struct Object;
-struct Array;
-struct True;
-struct False;
-struct Null;
-
-
-typedef boost::variant<boost::recursive_wrapper<String>,
- boost::recursive_wrapper<Number>,
- boost::recursive_wrapper<Object>,
- boost::recursive_wrapper<Array>,
- boost::recursive_wrapper<True>,
- boost::recursive_wrapper<False>,
- boost::recursive_wrapper<Null> > Value;
-
-
-struct String
-{
- String() {}
- String(const char* _value) : value(_value) {}
- String(const std::string& _value) : value(_value) {}
- std::string value;
-};
-
-
-struct Number
-{
- Number() {}
- Number(double _value) : value(_value) {}
- double value;
-};
-
-
-struct Object
-{
- std::map<std::string, Value> values;
-};
-
-
-struct Array
-{
- std::list<Value> values;
-};
-
-
-struct True {};
-
-
-struct False {};
-
-
-struct Null {};
-
-
-// Implementation of rendering JSON objects built above using standard
-// C++ output streams. The visitor pattern is used thanks to to build
-// a "renderer" with boost::static_visitor and two top-level render
-// routines are provided for rendering JSON objects and arrays.
-
-struct Renderer : boost::static_visitor<>
-{
- Renderer(std::ostream& _out) : out(_out) {}
-
- void operator () (const String& string) const
- {
- // TODO(benh): This escaping DOES NOT handle unicode, it encodes as ASCII.
- // See RFC4627 for the JSON string specificiation.
- out << "\"";
- foreach (unsigned char c, string.value) {
- switch (c) {
- case '"': out << "\\\""; break;
- case '\\': out << "\\\\"; break;
- case '/': out << "\\/"; break;
- case '\b': out << "\\b"; break;
- case '\f': out << "\\f"; break;
- case '\n': out << "\\n"; break;
- case '\r': out << "\\r"; break;
- case '\t': out << "\\t"; break;
- default:
- // See RFC4627 for these ranges.
- if ((c >= 0x20 && c <= 0x21) ||
- (c >= 0x23 && c <= 0x5B) ||
- (c >= 0x5D && c < 0x7F)) {
- out << c;
- } else {
- // NOTE: We also escape all bytes > 0x7F since they imply more than
- // 1 byte in UTF-8. This is why we don't escape UTF-8 properly.
- // See RFC4627 for the escaping format: \uXXXX (X is a hex digit).
- // Each byte here will be of the form: \u00XX (this is why we need
- // setw and the cast to unsigned int).
- out << "\\u" << std::setfill('0') << std::setw(4)
- << std::hex << std::uppercase << (unsigned int) c;
- }
- break;
- }
- }
- out << "\"";
- }
-
- void operator () (const Number& number) const
- {
- out.precision(10);
- out << number.value;
- }
-
- void operator () (const Object& object) const
- {
- out << "{";
- std::map<std::string, Value>::const_iterator iterator;
- iterator = object.values.begin();
- while (iterator != object.values.end()) {
- out << "\"" << (*iterator).first << "\":";
- boost::apply_visitor(Renderer(out), (*iterator).second);
- if (++iterator != object.values.end()) {
- out << ",";
- }
- }
- out << "}";
- }
-
- void operator () (const Array& array) const
- {
- out << "[";
- std::list<Value>::const_iterator iterator;
- iterator = array.values.begin();
- while (iterator != array.values.end()) {
- boost::apply_visitor(Renderer(out), *iterator);
- if (++iterator != array.values.end()) {
- out << ",";
- }
- }
- out << "]";
- }
-
- void operator () (const True&) const
- {
- out << "true";
- }
-
- void operator () (const False&) const
- {
- out << "false";
- }
-
- void operator () (const Null&) const
- {
- out << "null";
- }
-
-private:
- std::ostream& out;
-};
-
-
-inline void render(std::ostream& out, const Value& value)
-{
- boost::apply_visitor(Renderer(out), value);
-}
-
-
-inline std::ostream& operator<<(std::ostream& out, const JSON::Value& value)
-{
- JSON::render(out, value);
- return out;
-}
-
-} // namespace JSON {
-
-#endif // __STOUT_JSON__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/lambda.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/lambda.hpp b/third_party/libprocess/3rdparty/stout/include/stout/lambda.hpp
deleted file mode 100644
index d493353..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/lambda.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __STOUT_LAMBDA_HPP__
-#define __STOUT_LAMBDA_HPP__
-
-#include <tr1/functional>
-
-namespace lambda {
-
-using std::tr1::bind;
-using std::tr1::function;
-using namespace std::tr1::placeholders;
-
-} // namespace lambda {
-
-#endif // __STOUT_LAMBDA_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/multihashmap.hpp b/third_party/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
deleted file mode 100644
index 10e49dc..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef __STOUT_MULTIHASHMAP_HPP__
-#define __STOUT_MULTIHASHMAP_HPP__
-
-#include <algorithm> // For find.
-#include <list>
-#include <set>
-#include <utility>
-
-#include <boost/unordered_map.hpp>
-
-
-// Implementation of a hash multimap via Boost's 'unordered_multimap'
-// but with a better interface. The rationale for creating this is
-// that the std::multimap interface is painful to use (requires lots
-// of iterator garbage, as well as the use of 'equal_range' which
-// makes for cluttered code).
-template <typename K, typename V>
-class multihashmap : public boost::unordered_multimap<K, V>
-{
-public:
- void put(const K& key, const V& value);
- std::list<V> get(const K& key) const;
- std::set<K> keys() const;
- bool remove(const K& key);
- bool remove(const K& key, const V& value);
- bool contains(const K& key) const;
- bool contains(const K& key, const V& value) const;
-};
-
-
-template <typename K, typename V>
-void multihashmap<K, V>::put(const K& key, const V& value)
-{
- boost::unordered_multimap<K, V>::insert(std::pair<K, V>(key, value));
-}
-
-
-template <typename K, typename V>
-std::list<V> multihashmap<K, V>::get(const K& key) const
-{
- std::list<V> values; // Values to return.
-
- std::pair<typename boost::unordered_multimap<K, V>::const_iterator,
- typename boost::unordered_multimap<K, V>::const_iterator> range;
-
- range = boost::unordered_multimap<K, V>::equal_range(key);
-
- typename boost::unordered_multimap<K, V>::const_iterator i;
- for (i = range.first; i != range.second; ++i) {
- values.push_back(i->second);
- }
-
- return values;
-}
-
-
-template <typename K, typename V>
-std::set<K> multihashmap<K, V>::keys() const
-{
- std::set<K> keys;
- foreachkey (const K& key, *this) {
- keys.insert(key);
- }
- return keys;
-}
-
-
-template <typename K, typename V>
-bool multihashmap<K, V>::remove(const K& key)
-{
- return boost::unordered_multimap<K, V>::erase(key) > 0;
-}
-
-
-template <typename K, typename V>
-bool multihashmap<K, V>::remove(const K& key, const V& value)
-{
- std::pair<typename boost::unordered_multimap<K, V>::iterator,
- typename boost::unordered_multimap<K, V>::iterator> range;
-
- range = boost::unordered_multimap<K, V>::equal_range(key);
-
- typename boost::unordered_multimap<K, V>::iterator i;
- for (i = range.first; i != range.second; ++i) {
- if (i->second == value) {
- boost::unordered_multimap<K, V>::erase(i);
- return true;
- }
- }
-
- return false;
-}
-
-
-template <typename K, typename V>
-bool multihashmap<K, V>::contains(const K& key) const
-{
- return multihashmap<K, V>::count(key) > 0;
-}
-
-
-template <typename K, typename V>
-bool multihashmap<K, V>::contains(const K& key, const V& value) const
-{
- const std::list<V>& values = get(key);
- return std::find(values.begin(), values.end(), value) != values.end();
-}
-
-#endif // __STOUT_MULTIHASHMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/multimap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/multimap.hpp b/third_party/libprocess/3rdparty/stout/include/stout/multimap.hpp
deleted file mode 100644
index 187ad79..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/multimap.hpp
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef __STOUT_MULTIMAP_HPP__
-#define __STOUT_MULTIMAP_HPP__
-
-#include <algorithm>
-#include <list>
-#include <map>
-#include <set>
-#include <utility>
-
-// Implementation of a multimap via std::multimap but with a better
-// interface. The rationale for creating this is that the
-// std::multimap interface is painful to use (requires lots of
-// iterator garbage, as well as the use of 'equal_range' which makes
-// for cluttered code).
-template <typename K, typename V>
-class Multimap : public std::multimap<K, V>
-{
-public:
- void put(const K& key, const V& value);
- std::list<V> get(const K& key) const;
- std::set<K> keys() const;
- bool remove(const K& key);
- bool remove(const K& key, const V& value);
- bool contains(const K& key) const;
- bool contains(const K& key, const V& value) const;
-};
-
-
-template <typename K, typename V>
-void Multimap<K, V>::put(const K& key, const V& value)
-{
- std::multimap<K, V>::insert(std::pair<K, V>(key, value));
-}
-
-
-template <typename K, typename V>
-std::list<V> Multimap<K, V>::get(const K& key) const
-{
- std::list<V> values; // Values to return.
-
- std::pair<typename std::multimap<K, V>::const_iterator,
- typename std::multimap<K, V>::const_iterator> range;
-
- range = std::multimap<K, V>::equal_range(key);
-
- typename std::multimap<K, V>::const_iterator i;
- for (i = range.first; i != range.second; ++i) {
- values.push_back(i->second);
- }
-
- return values;
-}
-
-
-template <typename K, typename V>
-std::set<K> Multimap<K, V>::keys() const
-{
- std::set<K> keys;
- foreachkey (const K& key, *this) {
- keys.insert(key);
- }
- return keys;
-}
-
-
-template <typename K, typename V>
-bool Multimap<K, V>::remove(const K& key)
-{
- return std::multimap<K, V>::erase(key) > 0;
-}
-
-
-template <typename K, typename V>
-bool Multimap<K, V>::remove(const K& key, const V& value)
-{
- std::pair<typename std::multimap<K, V>::iterator,
- typename std::multimap<K, V>::iterator> range;
-
- range = std::multimap<K, V>::equal_range(key);
-
- typename std::multimap<K, V>::iterator i;
- for (i = range.first; i != range.second; ++i) {
- if (i->second == value) {
- std::multimap<K, V>::erase(i);
- return true;
- }
- }
-
- return false;
-}
-
-
-template <typename K, typename V>
-bool Multimap<K, V>::contains(const K& key) const
-{
- return std::multimap<K, V>::count(key) > 0;
-}
-
-
-template <typename K, typename V>
-bool Multimap<K, V>::contains(const K& key, const V& value) const
-{
- const std::list<V>& values = get(key);
- return std::find(values.begin(), values.end(), value) != values.end();
-}
-
-#endif // __STOUT_MULTIMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/net.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/net.hpp b/third_party/libprocess/3rdparty/stout/include/stout/net.hpp
deleted file mode 100644
index 1c5f88a..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/net.hpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef __STOUT_NET_HPP__
-#define __STOUT_NET_HPP__
-
-#include <netdb.h>
-#include <stdio.h>
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#ifdef HAVE_LIBCURL
-#include <curl/curl.h>
-#endif
-
-#include <string>
-
-#include "error.hpp"
-#include "os.hpp"
-#include "try.hpp"
-
-
-// Network utilities.
-namespace net {
-
-// Returns the HTTP response code resulting from attempting to download the
-// specified HTTP or FTP URL into a file at the specified path.
-inline Try<int> download(const std::string& url, const std::string& path)
-{
-#ifndef HAVE_LIBCURL
- return Error("libcurl is not available");
-#else
- Try<int> fd = os::open(
- path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
-
- if (fd.isError()) {
- return Error(fd.error());
- }
-
- curl_global_init(CURL_GLOBAL_ALL);
- CURL* curl = curl_easy_init();
-
- if (curl == NULL) {
- curl_easy_cleanup(curl);
- os::close(fd.get());
- return Error("Failed to initialize libcurl");
- }
-
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
-
- FILE* file = fdopen(fd.get(), "w");
- if (file == NULL) {
- return ErrnoError("Failed to open file handle of '" + path + "'");
- }
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
-
- CURLcode curlErrorCode = curl_easy_perform(curl);
- if (curlErrorCode != 0) {
- curl_easy_cleanup(curl);
- fclose(file);
- return Error(curl_easy_strerror(curlErrorCode));
- }
-
- long code;
- curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
- curl_easy_cleanup(curl);
-
- if (fclose(file) != 0) {
- return ErrnoError("Failed to close file handle of '" + path + "'");
- }
-
- return Try<int>::some(code);
-#endif // HAVE_LIBCURL
-}
-
-// Returns a Try of the hostname for the provided IP. If the hostname cannot
-// be resolved, then a string version of the IP address is returned.
-inline Try<std::string> getHostname(uint32_t ip)
-{
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = ip;
-
- char hostname[MAXHOSTNAMELEN];
- if (getnameinfo(
- (sockaddr*)&addr,
- sizeof(addr),
- hostname,
- MAXHOSTNAMELEN,
- NULL,
- 0,
- 0) != 0) {
- return ErrnoError();
- }
-
- return std::string(hostname);
-}
-
-} // namespace net {
-
-#endif // __STOUT_NET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/none.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/none.hpp b/third_party/libprocess/3rdparty/stout/include/stout/none.hpp
deleted file mode 100644
index ea8e0f5..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/none.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __STOUT_NONE_HPP__
-#define __STOUT_NONE_HPP__
-
-#include "option.hpp"
-#include "result.hpp"
-
-// A "none" type that is implicitly convertible to an Option<T> and
-// Result<T> for any T (effectively "syntactic sugar" to make code
-// more readable). The implementation uses cast operators to perform
-// the conversions instead of adding constructors to Option/Result
-// directly. Performance shouldn't be an issue given that an instance
-// of None has no virtual functions and no fields.
-
-class None
-{
-public:
- template <typename T>
- operator Option<T> () const
- {
- return Option<T>::none();
- }
-
- // Give the compiler some help for nested Option<T>. For example,
- // enable converting None to a Try<Option<T>>. Note that this will
- // bind to the innermost Option<T>.
- template <template <typename> class S, typename T>
- operator S<Option<T> > () const
- {
- return S<Option<T> >(Option<T>::none());
- }
-
- template <typename T>
- operator Result<T> () const
- {
- return Result<T>::none();
- }
-
- // Give the compiler some help for nested Result<T>. For example,
- // enable converting None to a Try<Result<T>>. Note that this will
- // bind to the innermost Result<T>.
- template <template <typename> class S, typename T>
- operator S<Result<T> > () const
- {
- return S<Result<T> >(Result<T>::none());
- }
-
- // Give the compiler some more help to disambiguate the above cast
- // operators from Result<Option<T>>.
- template <typename T>
- operator Result<Option<T> > () const
- {
- return Result<Option<T> >::none();
- }
-};
-
-#endif // __STOUT_NONE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/nothing.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/nothing.hpp b/third_party/libprocess/3rdparty/stout/include/stout/nothing.hpp
deleted file mode 100644
index c11a010..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/nothing.hpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __NOTHING_HPP__
-#define __NOTHING_HPP__
-
-struct Nothing {};
-
-#endif // __NOTHING_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/numify.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/numify.hpp b/third_party/libprocess/3rdparty/stout/include/stout/numify.hpp
deleted file mode 100644
index d23e238..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/numify.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __STOUT_NUMIFY_HPP__
-#define __STOUT_NUMIFY_HPP__
-
-#include <string>
-
-#include <boost/lexical_cast.hpp>
-
-#include "error.hpp"
-#include "none.hpp"
-#include "option.hpp"
-#include "result.hpp"
-#include "try.hpp"
-
-template <typename T>
-Try<T> numify(const std::string& s)
-{
- try {
- return boost::lexical_cast<T>(s);
- } catch (const boost::bad_lexical_cast&) {
- return Error("Failed to convert '" + s + "' to number");
- }
-}
-
-
-template <typename T>
-Result<T> numify(const Option<std::string>& s)
-{
- if (s.isSome()) {
- Try<T> t = numify<T>(s.get());
- if (t.isSome()) {
- return t.get();
- } else if (t.isError()) {
- return Error(t.error());
- }
- }
-
- return None();
-}
-
-#endif // __STOUT_NUMIFY_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/option.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/option.hpp b/third_party/libprocess/3rdparty/stout/include/stout/option.hpp
deleted file mode 100644
index f991ae8..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/option.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __STOUT_OPTION_HPP__
-#define __STOUT_OPTION_HPP__
-
-#include <assert.h>
-
-template <typename T>
-class Option
-{
-public:
- static Option<T> none()
- {
- return Option<T>(NONE);
- }
-
- static Option<T> some(const T& t)
- {
- return Option<T>(SOME, new T(t));
- }
-
- Option() : state(NONE), t(NULL) {}
-
- Option(const T& _t) : state(SOME), t(new T(_t)) {}
-
- Option(const Option<T>& that)
- {
- state = that.state;
- if (that.t != NULL) {
- t = new T(*that.t);
- } else {
- t = NULL;
- }
- }
-
- ~Option()
- {
- delete t;
- }
-
- Option<T>& operator = (const Option<T>& that)
- {
- if (this != &that) {
- delete t;
- state = that.state;
- if (that.t != NULL) {
- t = new T(*that.t);
- } else {
- t = NULL;
- }
- }
-
- return *this;
- }
-
- bool operator == (const Option<T>& that) const
- {
- return (state == NONE && that.state == NONE) ||
- (state == SOME && that.state == SOME && *t == *that.t);
- }
-
- bool operator != (const Option<T>& that) const
- {
- return !operator == (that);
- }
-
- bool isSome() const { return state == SOME; }
- bool isNone() const { return state == NONE; }
-
- T get() const { assert(state == SOME); return *t; }
-
- T get(const T& _t) const { return state == NONE ? _t : *t; }
-
-private:
- enum State {
- SOME,
- NONE,
- };
-
- Option(State _state, T* _t = NULL)
- : state(_state), t(_t) {}
-
- State state;
- T* t;
-};
-
-#endif // __STOUT_OPTION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/os.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/os.hpp b/third_party/libprocess/3rdparty/stout/include/stout/os.hpp
deleted file mode 100644
index 28a08cc..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/os.hpp
+++ /dev/null
@@ -1,1081 +0,0 @@
-#ifndef __STOUT_OS_HPP__
-#define __STOUT_OS_HPP__
-
-#ifdef __APPLE__
-#include <crt_externs.h> // For _NSGetEnviron().
-#endif
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fts.h>
-#include <glob.h>
-#include <libgen.h>
-#include <limits.h>
-#include <netdb.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <glog/logging.h>
-
-#ifdef __linux__
-#include <linux/version.h>
-#endif
-
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#ifdef __APPLE__
-#include <sys/sysctl.h>
-#endif
-#ifdef __linux__
-#include <sys/sysinfo.h>
-#endif
-#include <sys/types.h>
-#include <sys/utsname.h>
-
-#include <list>
-#include <set>
-#include <sstream>
-#include <string>
-
-#include "bytes.hpp"
-#include "duration.hpp"
-#include "error.hpp"
-#include "foreach.hpp"
-#include "none.hpp"
-#include "nothing.hpp"
-#include "path.hpp"
-#include "result.hpp"
-#include "strings.hpp"
-#include "try.hpp"
-
-#ifdef __APPLE__
-// Assigning the result pointer to ret silences an unused var warning.
-#define gethostbyname2_r(name, af, ret, buf, buflen, result, h_errnop) \
- ({ (void)ret; *(result) = gethostbyname2(name, af); 0; })
-#endif // __APPLE__
-
-// Need to declare 'environ' pointer for non OS X platforms.
-#ifndef __APPLE__
-extern char** environ;
-#endif
-
-namespace os {
-
-inline char** environ()
-{
- // Accessing the list of environment variables is platform-specific.
- // On OS X, the 'environ' symbol isn't visible to shared libraries,
- // so we must use the _NSGetEnviron() function (see 'man environ' on
- // OS X). On other platforms, it's fine to access 'environ' from
- // shared libraries.
-#ifdef __APPLE__
- return *_NSGetEnviron();
-#endif
- return ::environ;
-}
-
-
-// Checks if the specified key is in the environment variables.
-inline bool hasenv(const std::string& key)
-{
- char* value = ::getenv(key.c_str());
-
- return value != NULL;
-}
-
-// Looks in the environment variables for the specified key and
-// returns a string representation of it's value. If 'expected' is
-// true (default) and no environment variable matching key is found,
-// this function will exit the process.
-inline std::string getenv(const std::string& key, bool expected = true)
-{
- char* value = ::getenv(key.c_str());
-
- if (expected && value == NULL) {
- LOG(FATAL) << "Expecting '" << key << "' in environment variables";
- }
-
- if (value != NULL) {
- return std::string(value);
- }
-
- return std::string();
-}
-
-
-// Sets the value associated with the specified key in the set of
-// environment variables.
-inline void setenv(const std::string& key,
- const std::string& value,
- bool overwrite = true)
-{
- ::setenv(key.c_str(), value.c_str(), overwrite ? 1 : 0);
-}
-
-
-// Unsets the value associated with the specified key in the set of
-// environment variables.
-inline void unsetenv(const std::string& key)
-{
- ::unsetenv(key.c_str());
-}
-
-
-inline Try<bool> access(const std::string& path, int how)
-{
- if (::access(path.c_str(), how) < 0) {
- if (errno == EACCES) {
- return false;
- } else {
- return ErrnoError();
- }
- }
- return true;
-}
-
-
-inline Try<int> open(const std::string& path, int oflag, mode_t mode = 0)
-{
- int fd = ::open(path.c_str(), oflag, mode);
-
- if (fd < 0) {
- return ErrnoError();
- }
-
- return fd;
-}
-
-
-inline Try<Nothing> close(int fd)
-{
- if (::close(fd) != 0) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-
-inline Try<Nothing> cloexec(int fd)
-{
- int flags = ::fcntl(fd, F_GETFD);
-
- if (flags == -1) {
- return ErrnoError();
- }
-
- if (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-
-inline Try<Nothing> nonblock(int fd)
-{
- int flags = ::fcntl(fd, F_GETFL);
-
- if (flags == -1) {
- return ErrnoError();
- }
-
- if (::fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-
-inline Try<bool> isNonblock(int fd)
-{
- int flags = ::fcntl(fd, F_GETFL);
-
- if (flags == -1) {
- return ErrnoError();
- }
-
- return (flags & O_NONBLOCK) != 0;
-}
-
-
-inline Try<Nothing> touch(const std::string& path)
-{
- Try<int> fd =
- open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
-
- if (fd.isError()) {
- return Error("Failed to open file '" + path + "'");
- }
-
- // TODO(benh): Is opening/closing sufficient to have the same
- // semantics as the touch utility (i.e., doesn't the utility change
- // the modified date)?
- return close(fd.get());
-}
-
-
-// Creates a temporary file using the specified path template. The
-// template may be any path with _6_ `Xs' appended to it, for example
-// /tmp/temp.XXXXXX. The trailing `Xs' are replaced with a unique
-// alphanumeric combination.
-inline Try<std::string> mktemp(const std::string& path = "/tmp/XXXXXX")
-{
- char* temp = new char[path.size() + 1];
- int fd = ::mkstemp(::strcpy(temp, path.c_str()));
-
- if (fd < 0) {
- delete temp;
- return ErrnoError();
- }
-
- // We ignore the return value of close(). This is because users
- // calling this function are interested in the return value of
- // mkstemp(). Also an unsuccessful close() doesn't affect the file.
- os::close(fd);
-
- std::string result(temp);
- delete temp;
- return result;
-}
-
-
-// Write out the string to the file at the current fd position.
-inline Try<Nothing> write(int fd, const std::string& message)
-{
- size_t offset = 0;
-
- while (offset < message.length()) {
- ssize_t length =
- ::write(fd, message.data() + offset, message.length() - offset);
-
- if (length < 0) {
- // TODO(benh): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
- if (errno == EINTR) {
- continue;
- }
- return ErrnoError();
- }
-
- offset += length;
- }
-
- 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 std::string& 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 ErrnoError("Failed to open file '" + path + "'");
- }
-
- Try<Nothing> result = write(fd.get(), message);
-
- // 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;
-}
-
-
-// Reads 'size' bytes from a file from its current offset.
-// If EOF is encountered before reading size bytes, then the offset
-// is restored and none is returned.
-inline Result<std::string> read(int fd, size_t size)
-{
- // Save the current offset.
- off_t current = lseek(fd, 0, SEEK_CUR);
- if (current == -1) {
- return ErrnoError("Failed to lseek to SEEK_CUR");
- }
-
- char* buffer = new char[size];
- size_t offset = 0;
-
- while (offset < size) {
- ssize_t length = ::read(fd, buffer + offset, size - offset);
-
- if (length < 0) {
- // TODO(bmahler): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
- if (errno == EINTR) {
- continue;
- }
- // Attempt to restore the original offset.
- lseek(fd, current, SEEK_SET);
- return ErrnoError();
- } else if (length == 0) {
- // Reached EOF before expected! Restore the offset.
- lseek(fd, current, SEEK_SET);
- return None();
- }
-
- offset += length;
- }
-
- return std::string(buffer, size);
-}
-
-
-// Returns the contents of the file starting from its current offset.
-// If an error occurs, this will attempt to recover the file offset.
-inline Try<std::string> read(int fd)
-{
- // Save the current offset.
- off_t current = lseek(fd, 0, SEEK_CUR);
- if (current == -1) {
- return ErrnoError("Failed to lseek to SEEK_CUR");
- }
-
- // Get the size of the file from the offset.
- off_t size = lseek(fd, current, SEEK_END);
- if (size == -1) {
- return ErrnoError("Failed to lseek to SEEK_END");
- }
-
- // Restore the offset.
- if (lseek(fd, current, SEEK_SET) == -1) {
- return ErrnoError("Failed to lseek with SEEK_SET");
- }
-
- Result<std::string> result = read(fd, size);
- if (result.isNone()) {
- // Hit EOF before reading size bytes.
- return Error("The file size was modified while reading");
- } else if (result.isError()) {
- return Error(result.error());
- }
-
- return result.get();
-}
-
-
-// A wrapper function that wraps the above read() with
-// open and closing the file.
-inline Try<std::string> 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 + "'");
- }
-
- Try<std::string> result = read(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;
-}
-
-
-inline Try<Nothing> rm(const std::string& path)
-{
- if (::remove(path.c_str()) != 0) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-
-inline Try<std::string> basename(const std::string& path)
-{
- char* temp = new char[path.size() + 1];
- char* result = ::basename(::strcpy(temp, path.c_str()));
- if (result == NULL) {
- delete temp;
- return ErrnoError();
- }
-
- std::string s(result);
- delete temp;
- return s;
-}
-
-
-inline Try<std::string> dirname(const std::string& path)
-{
- char* temp = new char[path.size() + 1];
- char* result = ::dirname(::strcpy(temp, path.c_str()));
- if (result == NULL) {
- delete temp;
- return ErrnoError();
- }
-
- std::string s(result);
- delete temp;
- return s;
-}
-
-
-inline Try<std::string> realpath(const std::string& path)
-{
- char temp[PATH_MAX];
- if (::realpath(path.c_str(), temp) == NULL) {
- return ErrnoError();
- }
- return std::string(temp);
-}
-
-
-inline bool isdir(const std::string& path)
-{
- struct stat s;
-
- if (::stat(path.c_str(), &s) < 0) {
- return false;
- }
- return S_ISDIR(s.st_mode);
-}
-
-
-inline bool isfile(const std::string& path)
-{
- struct stat s;
-
- if (::stat(path.c_str(), &s) < 0) {
- return false;
- }
- return S_ISREG(s.st_mode);
-}
-
-
-inline bool islink(const std::string& path)
-{
- struct stat s;
-
- if (::lstat(path.c_str(), &s) < 0) {
- return false;
- }
- return S_ISLNK(s.st_mode);
-}
-
-
-inline bool exists(const std::string& path)
-{
- struct stat s;
-
- if (::lstat(path.c_str(), &s) < 0) {
- return false;
- }
- return true;
-}
-
-
-// TODO(benh): Put this in the 'paths' or 'files' or 'fs' namespace.
-inline Try<long> mtime(const std::string& path)
-{
- struct stat s;
-
- if (::lstat(path.c_str(), &s) < 0) {
- return ErrnoError("Error invoking stat for '" + path + "'");
- }
-
- return s.st_mtime;
-}
-
-
-inline Try<Nothing> mkdir(const std::string& directory, bool recursive = true)
-{
- if (!recursive) {
- if (::mkdir(directory.c_str(), 0755) < 0) {
- return ErrnoError();
- }
- } else {
- std::vector<std::string> tokens = strings::tokenize(directory, "/");
- std::string path = "";
-
- // We got an absolute path, so keep the leading slash.
- if (directory.find_first_of("/") == 0) {
- path = "/";
- }
-
- foreach (const std::string& token, tokens) {
- path += token;
- if (::mkdir(path.c_str(), 0755) < 0 && errno != EEXIST) {
- return ErrnoError();
- }
- path += "/";
- }
- }
-
- return Nothing();
-}
-
-// Creates a temporary directory using the specified path
-// template. The template may be any path with _6_ `Xs' appended to
-// it, for example /tmp/temp.XXXXXX. The trailing `Xs' are replaced
-// with a unique alphanumeric combination.
-inline Try<std::string> mkdtemp(const std::string& path = "/tmp/XXXXXX")
-{
- char* temp = new char[path.size() + 1];
- if (::mkdtemp(::strcpy(temp, path.c_str())) != NULL) {
- std::string result(temp);
- delete temp;
- return result;
- } else {
- delete temp;
- return ErrnoError();
- }
-}
-
-// By default, recursively deletes a directory akin to: 'rm -r'. If the
-// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
-// Note that this function expects an absolute path.
-inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
-{
- if (!recursive) {
- if (::rmdir(directory.c_str()) < 0) {
- return ErrnoError();
- }
- } else {
- char* paths[] = {const_cast<char*>(directory.c_str()), NULL};
-
- FTS* tree = fts_open(paths, FTS_NOCHDIR, NULL);
- if (tree == NULL) {
- return ErrnoError();
- }
-
- FTSENT* node;
- while ((node = fts_read(tree)) != NULL) {
- switch (node->fts_info) {
- case FTS_DP:
- if (::rmdir(node->fts_path) < 0 && errno != ENOENT) {
- return ErrnoError();
- }
- break;
- case FTS_F:
- case FTS_SL:
- if (::unlink(node->fts_path) < 0 && errno != ENOENT) {
- return ErrnoError();
- }
- break;
- default:
- break;
- }
- }
-
- if (errno != 0) {
- return ErrnoError();
- }
-
- if (fts_close(tree) < 0) {
- return ErrnoError();
- }
- }
-
- return Nothing();
-}
-
-
-inline int system(const std::string& command)
-{
- return ::system(command.c_str());
-}
-
-
-// TODO(bmahler): Clean these bool functions to return Try<Nothing>.
-// Changes the specified path's user and group ownership to that of
-// the specified user..
-inline Try<Nothing> chown(
- const std::string& user,
- const std::string& path,
- bool recursive = true)
-{
- passwd* passwd;
- if ((passwd = ::getpwnam(user.c_str())) == NULL) {
- return ErrnoError("Failed to get user information for '" + user + "'");
- }
-
- if (recursive) {
- // TODO(bmahler): Consider walking the file tree instead. We would need
- // to be careful to not miss dotfiles.
- std::string command = "chown -R " + stringify(passwd->pw_uid) + ':' +
- stringify(passwd->pw_gid) + " '" + path + "'";
-
- int status = os::system(command);
- if (status != 0) {
- return ErrnoError(
- "Failed to execute '" + command +
- "' (exit status: " + stringify(status) + ")");
- }
- } else {
- if (::chown(path.c_str(), passwd->pw_uid, passwd->pw_gid) < 0) {
- return ErrnoError();
- }
- }
-
- return Nothing();
-}
-
-
-inline bool chmod(const std::string& path, int mode)
-{
- if (::chmod(path.c_str(), mode) < 0) {
- PLOG(ERROR) << "Failed to changed the mode of the path '" << path << "'";
- return false;
- }
-
- return true;
-}
-
-
-inline bool chdir(const std::string& directory)
-{
- if (::chdir(directory.c_str()) < 0) {
- PLOG(ERROR) << "Failed to change directory";
- return false;
- }
-
- return true;
-}
-
-
-inline bool su(const std::string& user)
-{
- passwd* passwd;
- if ((passwd = ::getpwnam(user.c_str())) == NULL) {
- PLOG(ERROR) << "Failed to get user information for '"
- << user << "', getpwnam";
- return false;
- }
-
- if (::setgid(passwd->pw_gid) < 0) {
- PLOG(ERROR) << "Failed to set group id, setgid";
- return false;
- }
-
- if (::setuid(passwd->pw_uid) < 0) {
- PLOG(ERROR) << "Failed to set user id, setuid";
- return false;
- }
-
- return true;
-}
-
-
-inline std::string getcwd()
-{
- size_t size = 100;
-
- while (true) {
- char* temp = new char[size];
- if (::getcwd(temp, size) == temp) {
- std::string result(temp);
- delete[] temp;
- return result;
- } else {
- if (errno != ERANGE) {
- delete[] temp;
- return std::string();
- }
- size *= 2;
- delete[] temp;
- }
- }
-
- return std::string();
-}
-
-
-// TODO(bmahler): Wrap with a Try.
-inline std::list<std::string> ls(const std::string& directory)
-{
- std::list<std::string> result;
-
- DIR* dir = opendir(directory.c_str());
-
- if (dir == NULL) {
- return std::list<std::string>();
- }
-
- // Calculate the size for a "directory entry".
- long name_max = fpathconf(dirfd(dir), _PC_NAME_MAX);
-
- // If we don't get a valid size, check NAME_MAX, but fall back on
- // 255 in the worst case ... Danger, Will Robinson!
- if (name_max == -1) {
- name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
- }
-
- size_t name_end =
- (size_t) offsetof(dirent, d_name) + name_max + 1;
-
- size_t size = (name_end > sizeof(dirent)
- ? name_end
- : sizeof(dirent));
-
- dirent* temp = (dirent*) malloc(size);
-
- if (temp == NULL) {
- free(temp);
- closedir(dir);
- return std::list<std::string>();
- }
-
- struct dirent* entry;
-
- int error;
-
- while ((error = readdir_r(dir, temp, &entry)) == 0 && entry != NULL) {
- if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
- continue;
- }
- result.push_back(entry->d_name);
- }
-
- free(temp);
- closedir(dir);
-
- if (error != 0) {
- return std::list<std::string>();
- }
-
- return result;
-}
-
-
-// Return the list of file paths that match the given pattern by recursively
-// searching the given directory. A match is successful if the pattern is a
-// substring of the file name.
-// NOTE: Directory path should not end with '/'.
-// NOTE: Symbolic links are not followed.
-// TODO(vinod): Support regular expressions for pattern.
-// TODO(vinod): Consider using ftw or a non-recursive approach.
-inline Try<std::list<std::string> > find(
- const std::string& directory,
- const std::string& pattern)
-{
- std::list<std::string> results;
-
- if (!isdir(directory)) {
- return Error("'" + directory + "' is not a directory");
- }
-
- foreach (const std::string& entry, ls(directory)) {
- std::string path = path::join(directory, entry);
- // If it's a directory, recurse.
- if (isdir(path) && !islink(path)) {
- Try<std::list<std::string> > matches = find(path, pattern);
- if (matches.isError()) {
- return matches;
- }
- foreach (const std::string& match, matches.get()) {
- results.push_back(match);
- }
- } else {
- if (entry.find(pattern) != std::string::npos) {
- results.push_back(path); // Matched the file pattern!
- }
- }
- }
-
- return results;
-}
-
-
-inline std::string user()
-{
- passwd* passwd;
- if ((passwd = getpwuid(getuid())) == NULL) {
- LOG(FATAL) << "Failed to get username information";
- }
-
- return passwd->pw_name;
-}
-
-
-inline Try<std::string> hostname()
-{
- char host[512];
-
- if (gethostname(host, sizeof(host)) < 0) {
- return ErrnoError();
- }
-
- // Allocate temporary buffer for gethostbyname2_r.
- size_t length = 1024;
- char* temp = new char[length];
-
- struct hostent he, *hep = NULL;
- int result = 0;
- int herrno = 0;
-
- while ((result = gethostbyname2_r(host, AF_INET, &he, temp,
- length, &hep, &herrno)) == ERANGE) {
- // Enlarge the buffer.
- delete[] temp;
- length *= 2;
- temp = new char[length];
- }
-
- if (result != 0 || hep == NULL) {
- delete[] temp;
- return Error(hstrerror(herrno));
- }
-
- std::string hostname = hep->h_name;
- delete[] temp;
- return Try<std::string>::some(hostname);
-}
-
-
-// Runs a shell command formatted with varargs and return the return value
-// of the command. Optionally, the output is returned via an argument.
-// TODO(vinod): Pass an istream object that can provide input to the command.
-inline Try<int> shell(std::ostream* os, const std::string& fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
-
- const Try<std::string>& cmdline = strings::internal::format(fmt, args);
-
- va_end(args);
-
- if (cmdline.isError()) {
- return Error(cmdline.error());
- }
-
- FILE* file;
-
- if ((file = popen(cmdline.get().c_str(), "r")) == NULL) {
- return Error("Failed to run '" + cmdline.get() + "'");
- }
-
- char line[1024];
- // NOTE(vinod): Ideally the if and while loops should be interchanged. But
- // we get a broken pipe error if we don't read the output and simply close.
- while (fgets(line, sizeof(line), file) != NULL) {
- if (os != NULL) {
- *os << line ;
- }
- }
-
- if (ferror(file) != 0) {
- ErrnoError error("Error reading output of '" + cmdline.get() + "'");
- pclose(file); // Ignoring result since we already have an error.
- return error;
- }
-
- int status;
- if ((status = pclose(file)) == -1) {
- return Error("Failed to get status of '" + cmdline.get() + "'");
- }
-
- return status;
-}
-
-
-// Suspends execution for the given duration.
-inline Try<Nothing> sleep(const Duration& duration)
-{
- timespec remaining;
- remaining.tv_sec = static_cast<long>(duration.secs());
- remaining.tv_nsec =
- static_cast<long>((duration - Seconds(remaining.tv_sec)).ns());
-
- while (nanosleep(&remaining, &remaining) == -1) {
- if (errno == EINTR) {
- continue;
- } else {
- return ErrnoError();
- }
- }
-
- return Nothing();
-}
-
-
-// Creates a tar 'archive' with gzip compression, of the given 'path'.
-inline Try<Nothing> tar(const std::string& path, const std::string& archive)
-{
- Try<int> status =
- shell(NULL, "tar -czf %s %s", archive.c_str(), path.c_str());
-
- if (status.isError()) {
- return Error("Failed to archive " + path + ": " + status.error());
- } else if (status.get() != 0) {
- return Error("Non-zero exit status when archiving " + path +
- ": " + stringify(status.get()));
- }
-
- return Nothing();
-}
-
-
-// Returns the list of files that match the given (shell) pattern.
-inline Try<std::list<std::string> > glob(const std::string& pattern)
-{
- glob_t g;
- int status = ::glob(pattern.c_str(), GLOB_NOSORT, NULL, &g);
-
- std::list<std::string> result;
-
- if (status != 0) {
- if (status == GLOB_NOMATCH) {
- return result; // Empty list.
- } else {
- return ErrnoError();
- }
- }
-
- for (size_t i = 0; i < g.gl_pathc; ++i) {
- result.push_back(g.gl_pathv[i]);
- }
-
- globfree(&g); // Best-effort free of dynamically allocated memory.
-
- return result;
-}
-
-
-// Returns the total number of cpus (cores).
-inline Try<long> cpus()
-{
- long cpus = sysconf(_SC_NPROCESSORS_ONLN);
-
- if (cpus < 0) {
- return ErrnoError();
- }
- return cpus;
-}
-
-
-// Returns the total size of main memory.
-inline Try<Bytes> memory()
-{
-#ifdef __linux__
- struct sysinfo info;
- if (sysinfo(&info) != 0) {
- return ErrnoError();
- }
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23)
- return Bytes(info.totalram * info.mem_unit);
-# else
- return Bytes(info.totalram);
-# endif
-#elif defined __APPLE__
- const size_t NAME_SIZE = 2;
- int name[NAME_SIZE];
- name[0] = CTL_HW;
- name[1] = HW_MEMSIZE;
-
- int64_t memory;
- size_t length = sizeof(memory);
-
- if (sysctl(name, NAME_SIZE, &memory, &length, NULL, 0) < 0) {
- return ErrnoError("Failed to get sysctl of HW_MEMSIZE");
- }
- return Bytes(memory);
-#else
- return Error("Cannot determine the size of main memory");
-#endif
-}
-
-
-// The structure returned by uname describing the currently running system.
-struct UTSInfo
-{
- std::string sysname; // Operating system name (e.g. Linux).
- std::string nodename; // Network name of this machine.
- std::string release; // Release level of the operating system.
- std::string version; // Version level of the operating system.
- std::string machine; // Machine hardware platform.
-};
-
-
-// Return the system information.
-inline Try<UTSInfo> uname()
-{
- struct utsname name;
-
- if (::uname(&name) < 0) {
- return ErrnoError();
- }
-
- UTSInfo info;
- info.sysname = name.sysname;
- info.nodename = name.nodename;
- info.release = name.release;
- info.version = name.version;
- info.machine = name.machine;
- return info;
-}
-
-
-// Return the operating system name (e.g. Linux).
-inline Try<std::string> sysname()
-{
- Try<UTSInfo> info = uname();
- if (info.isError()) {
- return Error(info.error());
- }
-
- return info.get().sysname;
-}
-
-
-// The OS release level.
-struct Release
-{
- int version;
- int major;
- int minor;
-};
-
-
-// Return the OS release numbers.
-inline Try<Release> release()
-{
- Try<UTSInfo> info = uname();
- if (info.isError()) {
- return Error(info.error());
- }
-
- Release r;
- if (::sscanf(
- info.get().release.c_str(),
- "%d.%d.%d",
- &r.version,
- &r.major,
- &r.minor) != 3) {
- return Error("Failed to parse: " + info.get().release);
- }
-
- return r;
-}
-
-
-inline Try<bool> alive(pid_t pid)
-{
- CHECK(pid > 0);
-
- if (::kill(pid, 0) == 0) {
- return true;
- }
-
- if (errno == ESRCH) {
- return false;
- }
-
- return Try<bool>::error(strerror(errno));
-}
-
-} // namespace os {
-
-#endif // __STOUT_OS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/owned.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/owned.hpp b/third_party/libprocess/3rdparty/stout/include/stout/owned.hpp
deleted file mode 100644
index 3433f50..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/owned.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __STOUT_OWNED_HPP__
-#define __STOUT_OWNED_HPP__
-
-#include <boost/shared_ptr.hpp>
-
-// Represents a uniquely owned pointer.
-//
-// TODO(bmahler): For now, Owned only provides shared_ptr semantics.
-// When we make the switch to C++11, we will change to provide
-// unique_ptr semantics. Consequently, each usage of Owned that
-// invoked a copy will have to be adjusted to use move semantics.
-template <typename T>
-class Owned : public boost::shared_ptr<T>
-{
-public:
- Owned(T* t) : boost::shared_ptr<T>(t) {}
-};
-
-
-#endif // __STOUT_OWNED_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/path.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/path.hpp b/third_party/libprocess/3rdparty/stout/include/stout/path.hpp
deleted file mode 100644
index fda4e04..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/path.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef __STOUT_PATH_HPP__
-#define __STOUT_PATH_HPP__
-
-#include <string>
-#include <vector>
-
-#include "strings.hpp"
-
-namespace path {
-
-inline std::string join(const std::string& path1, const std::string& path2)
-{
- return
- strings::remove(path1, "/", strings::SUFFIX) + "/" +
- strings::remove(path2, "/", strings::PREFIX);
-}
-
-
-inline std::string join(
- const std::string& path1,
- const std::string& path2,
- const std::string& path3)
-{
- return join(path1, join(path2, path3));
-}
-
-
-inline std::string join(
- const std::string& path1,
- const std::string& path2,
- const std::string& path3,
- const std::string& path4)
-{
- return join(path1, join(path2, path3, path4));
-}
-
-
-inline std::string join(
- const std::string& path1,
- const std::string& path2,
- const std::string& path3,
- const std::string& path4,
- const std::string& path5)
-{
- return join(path1, join(path2, join(path3, join(path4, path5))));
-}
-
-
-inline std::string join(
- const std::string& path1,
- const std::string& path2,
- const std::string& path3,
- const std::string& path4,
- const std::string& path5,
- const std::string& path6)
-{
- return join(path1, join(path2, path3, path4, path5, path6));
-}
-
-
-inline std::string join(const std::vector<std::string>& paths)
-{
- if (paths.empty()) {
- return "";
- }
-
- std::string result = paths[0];
- for (size_t i = 1; i < paths.size(); ++i) {
- result = join(result, paths[i]);
- }
- return result;
-}
-
-} // namespace path {
-
-#endif // __STOUT_PATH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/preprocessor.hpp b/third_party/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
deleted file mode 100644
index 466e16f..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __PROCESS_PREPROCESSOR_HPP__
-#define __PROCESS_PREPROCESSOR_HPP__
-
-#include <boost/preprocessor/cat.hpp>
-
-#include <boost/preprocessor/arithmetic/inc.hpp>
-
-#include <boost/preprocessor/facilities/intercept.hpp>
-
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-
-// Provides aliases to a bunch of preprocessor macros useful for
-// creating template definitions that have varying number of
-// parameters (should be removable with C++-11 variadic templates).
-
-#define CAT BOOST_PP_CAT
-#define INC BOOST_PP_INC
-#define INTERCEPT BOOST_PP_INTERCEPT
-#define ENUM_PARAMS BOOST_PP_ENUM_PARAMS
-#define ENUM_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS
-#define ENUM_TRAILING_PARAMS BOOST_PP_ENUM_TRAILING_PARAMS
-#define REPEAT BOOST_PP_REPEAT
-#define REPEAT_FROM_TO BOOST_PP_REPEAT_FROM_TO
-
-#endif // __PROCESS_PREPROCESSOR_HPP__
[24/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/process.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/process.cpp b/3rdparty/libprocess/src/process.cpp
new file mode 100644
index 0000000..86414e5
--- /dev/null
+++ b/3rdparty/libprocess/src/process.cpp
@@ -0,0 +1,3446 @@
+#include <errno.h>
+#include <ev.h>
+#include <limits.h>
+#include <libgen.h>
+#include <netdb.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+
+#include <glog/logging.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <algorithm>
+#include <deque>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <list>
+#include <map>
+#include <queue>
+#include <set>
+#include <sstream>
+#include <stack>
+#include <stdexcept>
+#include <vector>
+
+#include <tr1/functional>
+#include <tr1/memory> // TODO(benh): Replace all shared_ptr with unique_ptr.
+
+#include <boost/shared_array.hpp>
+
+#include <process/clock.hpp>
+#include <process/defer.hpp>
+#include <process/delay.hpp>
+#include <process/dispatch.hpp>
+#include <process/executor.hpp>
+#include <process/filter.hpp>
+#include <process/future.hpp>
+#include <process/gc.hpp>
+#include <process/id.hpp>
+#include <process/io.hpp>
+#include <process/logging.hpp>
+#include <process/mime.hpp>
+#include <process/process.hpp>
+#include <process/profiler.hpp>
+#include <process/socket.hpp>
+#include <process/statistics.hpp>
+#include <process/thread.hpp>
+#include <process/time.hpp>
+#include <process/timer.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/foreach.hpp>
+#include <stout/lambda.hpp>
+#include <stout/net.hpp>
+#include <stout/os.hpp>
+#include <stout/strings.hpp>
+
+#include "config.hpp"
+#include "decoder.hpp"
+#include "encoder.hpp"
+#include "gate.hpp"
+#include "synchronized.hpp"
+
+using process::wait; // Necessary on some OS's to disambiguate.
+
+using process::http::BadRequest;
+using process::http::InternalServerError;
+using process::http::NotFound;
+using process::http::OK;
+using process::http::Request;
+using process::http::Response;
+using process::http::ServiceUnavailable;
+
+using std::deque;
+using std::find;
+using std::list;
+using std::map;
+using std::ostream;
+using std::pair;
+using std::queue;
+using std::set;
+using std::stack;
+using std::string;
+using std::stringstream;
+using std::vector;
+
+// Represents a remote "node" (encapsulates IP address and port).
+class Node
+{
+public:
+ Node(uint32_t _ip = 0, uint16_t _port = 0)
+ : ip(_ip), port(_port) {}
+
+ bool operator < (const Node& that) const
+ {
+ if (ip == that.ip) {
+ return port < that.port;
+ } else {
+ return ip < that.ip;
+ }
+ }
+
+ ostream& operator << (ostream& stream) const
+ {
+ stream << ip << ":" << port;
+ return stream;
+ }
+
+ uint32_t ip;
+ uint16_t port;
+};
+
+
+namespace process {
+
+namespace ID {
+
+string generate(const string& prefix)
+{
+ static map<string, int> prefixes;
+ stringstream out;
+ out << __sync_add_and_fetch(&prefixes[prefix], 1);
+ return prefix + "(" + out.str() + ")";
+}
+
+} // namespace ID {
+
+
+namespace http {
+
+hashmap<uint16_t, string> statuses;
+
+} // namespace http {
+
+
+namespace mime {
+
+map<string, string> types;
+
+} // namespace mime {
+
+
+// Provides reference counting semantics for a process pointer.
+class ProcessReference
+{
+public:
+ ProcessReference() : process(NULL) {}
+
+ ~ProcessReference()
+ {
+ cleanup();
+ }
+
+ ProcessReference(const ProcessReference& that)
+ {
+ copy(that);
+ }
+
+ ProcessReference& operator = (const ProcessReference& that)
+ {
+ if (this != &that) {
+ cleanup();
+ copy(that);
+ }
+ return *this;
+ }
+
+ ProcessBase* operator -> ()
+ {
+ return process;
+ }
+
+ operator ProcessBase* ()
+ {
+ return process;
+ }
+
+ operator bool () const
+ {
+ return process != NULL;
+ }
+
+private:
+ friend class ProcessManager; // For ProcessManager::use.
+
+ ProcessReference(ProcessBase* _process)
+ : process(_process)
+ {
+ if (process != NULL) {
+ __sync_fetch_and_add(&(process->refs), 1);
+ }
+ }
+
+ void copy(const ProcessReference& that)
+ {
+ process = that.process;
+
+ if (process != NULL) {
+ // There should be at least one reference to the process, so
+ // we don't need to worry about checking if it's exiting or
+ // not, since we know we can always create another reference.
+ CHECK(process->refs > 0);
+ __sync_fetch_and_add(&(process->refs), 1);
+ }
+ }
+
+ void cleanup()
+ {
+ if (process != NULL) {
+ __sync_fetch_and_sub(&(process->refs), 1);
+ }
+ }
+
+ ProcessBase* process;
+};
+
+
+// Provides a process that manages sending HTTP responses so as to
+// satisfy HTTP/1.1 pipelining. Each request should either enqueue a
+// response, or ask the proxy to handle a future response. The process
+// is responsible for making sure the responses are sent in the same
+// order as the requests. Note that we use a 'Socket' in order to keep
+// the underyling file descriptor from getting closed while there
+// might still be outstanding responses even though the client might
+// have closed the connection (see more discussion in
+// SocketManger::close and SocketManager::proxy).
+class HttpProxy : public Process<HttpProxy>
+{
+public:
+ HttpProxy(const Socket& _socket);
+ virtual ~HttpProxy();
+
+ // Enqueues the response to be sent once all previously enqueued
+ // responses have been processed (e.g., waited for and sent).
+ void enqueue(const Response& response, const Request& request);
+
+ // Enqueues a future to a response that will get waited on (up to
+ // some timeout) and then sent once all previously enqueued
+ // responses have been processed (e.g., waited for and sent).
+ void handle(Future<Response>* future, const Request& request);
+
+private:
+ // Starts "waiting" on the next available future response.
+ void next();
+
+ // Invoked once a future response has been satisfied.
+ void waited(const Future<Response>& future);
+
+ // Demuxes and handles a response.
+ bool process(const Future<Response>& future, const Request& request);
+
+ // Handles stream (i.e., pipe) based responses.
+ void stream(const Future<short>& poll, const Request& request);
+
+ Socket socket; // Wrap the socket to keep it from getting closed.
+
+ // Describes a queue "item" that wraps the future to the response
+ // and the original request.
+ // The original request contains needed information such as what encodings
+ // are acceptable and whether to persist the connection.
+ struct Item
+ {
+ Item(const Request& _request, Future<Response>* _future)
+ : request(_request), future(_future) {}
+
+ ~Item()
+ {
+ delete future;
+ }
+
+ const Request request; // Make a copy.
+ Future<Response>* future;
+ };
+
+ queue<Item*> items;
+
+ Option<int> pipe; // Current pipe, if streaming.
+};
+
+
+class SocketManager
+{
+public:
+ SocketManager();
+ ~SocketManager();
+
+ Socket accepted(int s);
+
+ void link(ProcessBase* process, const UPID& to);
+
+ PID<HttpProxy> proxy(const Socket& socket);
+
+ void send(Encoder* encoder, bool persist);
+ void send(const Response& response,
+ const Request& request,
+ const Socket& socket);
+ void send(Message* message);
+
+ Encoder* next(int s);
+
+ void close(int s);
+
+ void exited(const Node& node);
+ void exited(ProcessBase* process);
+
+private:
+ // Map from UPID (local/remote) to process.
+ map<UPID, set<ProcessBase*> > links;
+
+ // Collection of all actice sockets.
+ map<int, Socket> sockets;
+
+ // Collection of sockets that should be disposed when they are
+ // finished being used (e.g., when there is no more data to send on
+ // them).
+ set<int> dispose;
+
+ // Map from socket to node (ip, port).
+ map<int, Node> nodes;
+
+ // Maps from node (ip, port) to temporary sockets (i.e., they will
+ // get closed once there is no more data to send on them).
+ map<Node, int> temps;
+
+ // Maps from node (ip, port) to persistent sockets (i.e., they will
+ // remain open even if there is no more data to send on them). We
+ // distinguish these from the 'temps' collection so we can tell when
+ // a persistant socket has been lost (and thus generate
+ // ExitedEvents).
+ map<Node, int> persists;
+
+ // Map from socket to outgoing queue.
+ map<int, queue<Encoder*> > outgoing;
+
+ // HTTP proxies.
+ map<int, HttpProxy*> proxies;
+
+ // Protects instance variables.
+ synchronizable(this);
+};
+
+
+class ProcessManager
+{
+public:
+ ProcessManager(const string& delegate);
+ ~ProcessManager();
+
+ ProcessReference use(const UPID& pid);
+
+ bool handle(
+ const Socket& socket,
+ Request* request);
+
+ bool deliver(
+ ProcessBase* receiver,
+ Event* event,
+ ProcessBase* sender = NULL);
+
+ bool deliver(
+ const UPID& to,
+ Event* event,
+ ProcessBase* sender = NULL);
+
+ UPID spawn(ProcessBase* process, bool manage);
+ void resume(ProcessBase* process);
+ void cleanup(ProcessBase* process);
+ void link(ProcessBase* process, const UPID& to);
+ void terminate(const UPID& pid, bool inject, ProcessBase* sender = NULL);
+ bool wait(const UPID& pid);
+
+ void enqueue(ProcessBase* process);
+ ProcessBase* dequeue();
+
+ void settle();
+
+private:
+ // Delegate process name to receive root HTTP requests.
+ const string delegate;
+
+ // Map of all local spawned and running processes.
+ map<string, ProcessBase*> processes;
+ synchronizable(processes);
+
+ // Gates for waiting threads (protected by synchronizable(processes)).
+ map<ProcessBase*, Gate*> gates;
+
+ // Queue of runnable processes (implemented using list).
+ list<ProcessBase*> runq;
+ synchronizable(runq);
+
+ // Number of running processes, to support Clock::settle operation.
+ int running;
+};
+
+
+// Unique id that can be assigned to each process.
+static uint32_t __id__ = 0;
+
+// Local server socket.
+static int __s__ = -1;
+
+// Local IP address.
+static uint32_t __ip__ = 0;
+
+// Local port.
+static uint16_t __port__ = 0;
+
+// Active SocketManager (eventually will probably be thread-local).
+static SocketManager* socket_manager = NULL;
+
+// Active ProcessManager (eventually will probably be thread-local).
+static ProcessManager* process_manager = NULL;
+
+// Event loop.
+static struct ev_loop* loop = NULL;
+
+// Asynchronous watcher for interrupting loop.
+static ev_async async_watcher;
+
+// Watcher for timeouts.
+static ev_timer timeouts_watcher;
+
+// Server watcher for accepting connections.
+static ev_io server_watcher;
+
+// Queue of I/O watchers.
+static queue<ev_io*>* watchers = new queue<ev_io*>();
+static synchronizable(watchers) = SYNCHRONIZED_INITIALIZER;
+
+// We store the timers in a map of lists indexed by the timeout of the
+// timer so that we can have two timers that have the same timeout. We
+// exploit that the map is SORTED!
+static map<Time, list<Timer> >* timeouts =
+ new map<Time, list<Timer> >();
+static synchronizable(timeouts) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
+
+// For supporting Clock::settle(), true if timers have been removed
+// from 'timeouts' but may not have been executed yet. Protected by
+// the timeouts lock. This is only used when the clock is paused.
+static bool pending_timers = false;
+
+// Flag to indicate whether or to update the timer on async interrupt.
+static bool update_timer = false;
+
+// Scheduling gate that threads wait at when there is nothing to run.
+static Gate* gate = new Gate();
+
+// Filter. Synchronized support for using the filterer needs to be
+// recursive incase a filterer wants to do anything fancy (which is
+// possible and likely given that filters will get used for testing).
+static Filter* filterer = NULL;
+static synchronizable(filterer) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
+
+// Global garbage collector.
+PID<GarbageCollector> gc;
+
+// Per thread process pointer.
+ThreadLocal<ProcessBase>* _process_ = new ThreadLocal<ProcessBase>();
+
+// Per thread executor pointer.
+ThreadLocal<Executor>* _executor_ = new ThreadLocal<Executor>();
+
+
+// We namespace the clock related variables to keep them well
+// named. In the future we'll probably want to associate a clock with
+// a specific ProcessManager/SocketManager instance pair, so this will
+// likely change.
+namespace clock {
+
+map<ProcessBase*, Time>* currents = new map<ProcessBase*, Time>();
+
+Time initial = Time::EPOCH;
+Time current = Time::EPOCH;
+
+bool paused = false;
+
+} // namespace clock {
+
+
+Time Time::EPOCH = Time(Duration::zero());
+
+
+Time Time::MAX = Time(Duration::max());
+
+
+Time Clock::now()
+{
+ return now(__process__);
+}
+
+
+Time Clock::now(ProcessBase* process)
+{
+ synchronized (timeouts) {
+ if (Clock::paused()) {
+ if (process != NULL) {
+ if (clock::currents->count(process) != 0) {
+ return (*clock::currents)[process];
+ } else {
+ return (*clock::currents)[process] = clock::initial;
+ }
+ } else {
+ return clock::current;
+ }
+ }
+ }
+
+ // TODO(benh): Versus ev_now()?
+ double d = ev_time();
+ Try<Time> time = Time::create(d);
+
+ // TODO(xujyan): Move CHECK_SOME to libprocess and add CHECK_SOME
+ // here.
+ if (time.isError()) {
+ LOG(FATAL) << "Failed to create a Time from " << d << ": "
+ << time.error();
+ }
+ return time.get();
+}
+
+
+void Clock::pause()
+{
+ process::initialize(); // To make sure the libev watchers are ready.
+
+ synchronized (timeouts) {
+ if (!clock::paused) {
+ clock::initial = clock::current = now();
+ clock::paused = true;
+ VLOG(2) << "Clock paused at " << clock::initial;
+ }
+ }
+
+ // Note that after pausing the clock an existing libev timer might
+ // still fire (invoking handle_timeout), but since paused == true no
+ // "time" will actually have passed, so no timer will actually fire.
+}
+
+
+bool Clock::paused()
+{
+ return clock::paused;
+}
+
+
+void Clock::resume()
+{
+ process::initialize(); // To make sure the libev watchers are ready.
+
+ synchronized (timeouts) {
+ if (clock::paused) {
+ VLOG(2) << "Clock resumed at " << clock::current;
+ clock::paused = false;
+ clock::currents->clear();
+ update_timer = true;
+ ev_async_send(loop, &async_watcher);
+ }
+ }
+}
+
+
+void Clock::advance(const Duration& duration)
+{
+ synchronized (timeouts) {
+ if (clock::paused) {
+ clock::current += duration;
+ VLOG(2) << "Clock advanced (" << duration << ") to " << clock::current;
+ if (!update_timer) {
+ update_timer = true;
+ ev_async_send(loop, &async_watcher);
+ }
+ }
+ }
+}
+
+
+void Clock::advance(ProcessBase* process, const Duration& duration)
+{
+ synchronized (timeouts) {
+ if (clock::paused) {
+ Time current = now(process);
+ current += duration;
+ (*clock::currents)[process] = current;
+ VLOG(2) << "Clock of " << process->self() << " advanced (" << duration
+ << ") to " << current;
+ }
+ }
+}
+
+
+void Clock::update(const Time& time)
+{
+ synchronized (timeouts) {
+ if (clock::paused) {
+ if (clock::current < time) {
+ clock::current = Time(time);
+ VLOG(2) << "Clock updated to " << clock::current;
+ if (!update_timer) {
+ update_timer = true;
+ ev_async_send(loop, &async_watcher);
+ }
+ }
+ }
+ }
+}
+
+
+void Clock::update(ProcessBase* process, const Time& time)
+{
+ synchronized (timeouts) {
+ if (clock::paused) {
+ if (now(process) < time) {
+ VLOG(2) << "Clock of " << process->self() << " updated to " << time;
+ (*clock::currents)[process] = Time(time);
+ }
+ }
+ }
+}
+
+
+void Clock::order(ProcessBase* from, ProcessBase* to)
+{
+ update(to, now(from));
+}
+
+
+void Clock::settle()
+{
+ CHECK(clock::paused); // TODO(benh): Consider returning a bool instead.
+ process_manager->settle();
+}
+
+
+static Message* encode(const UPID& from,
+ const UPID& to,
+ const string& name,
+ const string& data = "")
+{
+ Message* message = new Message();
+ message->from = from;
+ message->to = to;
+ message->name = name;
+ message->body = data;
+ return message;
+}
+
+
+static void transport(Message* message, ProcessBase* sender = NULL)
+{
+ if (message->to.ip == __ip__ && message->to.port == __port__) {
+ // Local message.
+ process_manager->deliver(message->to, new MessageEvent(message), sender);
+ } else {
+ // Remote message.
+ socket_manager->send(message);
+ }
+}
+
+
+static bool libprocess(Request* request)
+{
+ return request->method == "POST" &&
+ request->headers.count("User-Agent") > 0 &&
+ request->headers["User-Agent"].find("libprocess/") == 0;
+}
+
+
+static Message* parse(Request* request)
+{
+ // TODO(benh): Do better error handling (to deal with a malformed
+ // libprocess message, malicious or otherwise).
+ const string& agent = request->headers["User-Agent"];
+ const string& identifier = "libprocess/";
+ size_t index = agent.find(identifier);
+ if (index != string::npos) {
+ // Okay, now determine 'from'.
+ const UPID from(agent.substr(index + identifier.size(), agent.size()));
+
+ // Now determine 'to'.
+ index = request->path.find('/', 1);
+ index = index != string::npos ? index - 1 : string::npos;
+ const UPID to(request->path.substr(1, index), __ip__, __port__);
+
+ // And now determine 'name'.
+ index = index != string::npos ? index + 2: request->path.size();
+ const string& name = request->path.substr(index);
+
+ VLOG(2) << "Parsed message name '" << name
+ << "' for " << to << " from " << from;
+
+ Message* message = new Message();
+ message->name = name;
+ message->from = from;
+ message->to = to;
+ message->body = request->body;
+
+ return message;
+ }
+
+ return NULL;
+}
+
+
+void handle_async(struct ev_loop* loop, ev_async* _, int revents)
+{
+ synchronized (watchers) {
+ // Start all the new I/O watchers.
+ while (!watchers->empty()) {
+ ev_io* watcher = watchers->front();
+ watchers->pop();
+ ev_io_start(loop, watcher);
+ }
+ }
+
+ synchronized (timeouts) {
+ if (update_timer) {
+ if (!timeouts->empty()) {
+ // Determine when the next timer should fire.
+ timeouts_watcher.repeat = (timeouts->begin()->first - Clock::now()).secs();
+
+ if (timeouts_watcher.repeat <= 0) {
+ // Feed the event now!
+ timeouts_watcher.repeat = 0;
+ ev_timer_again(loop, &timeouts_watcher);
+ ev_feed_event(loop, &timeouts_watcher, EV_TIMEOUT);
+ } else {
+ // Don't fire the timer if the clock is paused since we
+ // don't want time to advance (instead a call to
+ // clock::advance() will handle the timer).
+ if (Clock::paused() && timeouts_watcher.repeat > 0) {
+ timeouts_watcher.repeat = 0;
+ }
+
+ ev_timer_again(loop, &timeouts_watcher);
+ }
+ }
+
+ update_timer = false;
+ }
+ }
+}
+
+
+void handle_timeouts(struct ev_loop* loop, ev_timer* _, int revents)
+{
+ list<Timer> timedout;
+
+ synchronized (timeouts) {
+ Time now = Clock::now();
+
+ VLOG(3) << "Handling timeouts up to " << now;
+
+ foreachkey (const Time& timeout, *timeouts) {
+ if (timeout > now) {
+ break;
+ }
+
+ VLOG(3) << "Have timeout(s) at " << timeout;
+
+ // Record that we have pending timers to execute so the
+ // Clock::settle() operation can wait until we're done.
+ pending_timers = true;
+
+ foreach (const Timer& timer, (*timeouts)[timeout]) {
+ timedout.push_back(timer);
+ }
+ }
+
+ // Now erase the range of timeouts that timed out.
+ timeouts->erase(timeouts->begin(), timeouts->upper_bound(now));
+
+ // Okay, so the timeout for the next timer should not have fired.
+ CHECK(timeouts->empty() || (timeouts->begin()->first > now));
+
+ // Update the timer as necessary.
+ if (!timeouts->empty()) {
+ // Determine when the next timer should fire.
+ timeouts_watcher.repeat =
+ (timeouts->begin()->first - Clock::now()).secs();
+
+ if (timeouts_watcher.repeat <= 0) {
+ // Feed the event now!
+ timeouts_watcher.repeat = 0;
+ ev_timer_again(loop, &timeouts_watcher);
+ ev_feed_event(loop, &timeouts_watcher, EV_TIMEOUT);
+ } else {
+ // Don't fire the timer if the clock is paused since we don't
+ // want time to advance (instead a call to Clock::advance()
+ // will handle the timer).
+ if (Clock::paused() && timeouts_watcher.repeat > 0) {
+ timeouts_watcher.repeat = 0;
+ }
+
+ ev_timer_again(loop, &timeouts_watcher);
+ }
+ }
+
+ update_timer = false; // Since we might have a queued update_timer.
+ }
+
+ // Update current time of process (if it's present/valid). It might
+ // be necessary to actually add some more synchronization around
+ // this so that, for example, pausing and resuming the clock doesn't
+ // cause some processes to get thier current times updated and
+ // others not. Since ProcessManager::use acquires the 'processes'
+ // lock we had to move this out of the synchronized (timeouts) above
+ // since there was a deadlock with acquring 'processes' then
+ // 'timeouts' (reverse order) in ProcessManager::cleanup. Note that
+ // current time may be greater than the timeout if a local message
+ // was received (and happens-before kicks in).
+ if (Clock::paused()) {
+ foreach (const Timer& timer, timedout) {
+ if (ProcessReference process = process_manager->use(timer.creator())) {
+ Clock::update(process, timer.timeout().time());
+ }
+ }
+ }
+
+ // Invoke the timers that timed out (TODO(benh): Do this
+ // asynchronously so that we don't tie up the event thread!).
+ foreach (const Timer& timer, timedout) {
+ timer();
+ }
+
+ // Mark ourselves as done executing the timers since it's now safe
+ // for a call to Clock::settle() to check if there will be any
+ // future timeouts reached.
+ synchronized (timeouts) {
+ pending_timers = false;
+ }
+}
+
+
+void recv_data(struct ev_loop* loop, ev_io* watcher, int revents)
+{
+ DataDecoder* decoder = (DataDecoder*) watcher->data;
+
+ int s = watcher->fd;
+
+ while (true) {
+ const ssize_t size = 80 * 1024;
+ ssize_t length = 0;
+
+ char data[size];
+
+ length = recv(s, data, size, 0);
+
+ if (length < 0 && (errno == EINTR)) {
+ // Interrupted, try again now.
+ continue;
+ } else if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ // Might block, try again later.
+ break;
+ } else if (length <= 0) {
+ // Socket error or closed.
+ if (length < 0) {
+ const char* error = strerror(errno);
+ VLOG(1) << "Socket error while receiving: " << error;
+ } else {
+ VLOG(1) << "Socket closed while receiving";
+ }
+ socket_manager->close(s);
+ delete decoder;
+ ev_io_stop(loop, watcher);
+ delete watcher;
+ break;
+ } else {
+ CHECK(length > 0);
+
+ // Decode as much of the data as possible into HTTP requests.
+ const deque<Request*>& requests = decoder->decode(data, length);
+
+ if (!requests.empty()) {
+ foreach (Request* request, requests) {
+ process_manager->handle(decoder->socket(), request);
+ }
+ } else if (requests.empty() && decoder->failed()) {
+ VLOG(1) << "Decoder error while receiving";
+ socket_manager->close(s);
+ delete decoder;
+ ev_io_stop(loop, watcher);
+ delete watcher;
+ break;
+ }
+ }
+ }
+}
+
+
+void send_data(struct ev_loop* loop, ev_io* watcher, int revents)
+{
+ DataEncoder* encoder = (DataEncoder*) watcher->data;
+
+ int s = watcher->fd;
+
+ while (true) {
+ const void* data;
+ size_t size;
+
+ data = encoder->next(&size);
+ CHECK(size > 0);
+
+ ssize_t length = send(s, data, size, MSG_NOSIGNAL);
+
+ if (length < 0 && (errno == EINTR)) {
+ // Interrupted, try again now.
+ encoder->backup(size);
+ continue;
+ } else if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ // Might block, try again later.
+ encoder->backup(size);
+ break;
+ } else if (length <= 0) {
+ // Socket error or closed.
+ if (length < 0) {
+ const char* error = strerror(errno);
+ VLOG(1) << "Socket error while sending: " << error;
+ } else {
+ VLOG(1) << "Socket closed while sending";
+ }
+ socket_manager->close(s);
+ delete encoder;
+ ev_io_stop(loop, watcher);
+ delete watcher;
+ break;
+ } else {
+ CHECK(length > 0);
+
+ // Update the encoder with the amount sent.
+ encoder->backup(size - length);
+
+ // See if there is any more of the message to send.
+ if (encoder->remaining() == 0) {
+ delete encoder;
+
+ // Stop this watcher for now.
+ ev_io_stop(loop, watcher);
+
+ // Check for more stuff to send on socket.
+ Encoder* next = socket_manager->next(s);
+ if (next != NULL) {
+ watcher->data = next;
+ ev_io_init(watcher, next->sender(), s, EV_WRITE);
+ ev_io_start(loop, watcher);
+ } else {
+ // Nothing more to send right now, clean up.
+ delete watcher;
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+void send_file(struct ev_loop* loop, ev_io* watcher, int revents)
+{
+ FileEncoder* encoder = (FileEncoder*) watcher->data;
+
+ int s = watcher->fd;
+
+ while (true) {
+ int fd;
+ off_t offset;
+ size_t size;
+
+ fd = encoder->next(&offset, &size);
+ CHECK(size > 0);
+
+ ssize_t length = sendfile(s, fd, offset, size);
+
+ if (length < 0 && (errno == EINTR)) {
+ // Interrupted, try again now.
+ encoder->backup(size);
+ continue;
+ } else if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ // Might block, try again later.
+ encoder->backup(size);
+ break;
+ } else if (length <= 0) {
+ // Socket error or closed.
+ if (length < 0) {
+ const char* error = strerror(errno);
+ VLOG(1) << "Socket error while sending: " << error;
+ } else {
+ VLOG(1) << "Socket closed while sending";
+ }
+ socket_manager->close(s);
+ delete encoder;
+ ev_io_stop(loop, watcher);
+ delete watcher;
+ break;
+ } else {
+ CHECK(length > 0);
+
+ // Update the encoder with the amount sent.
+ encoder->backup(size - length);
+
+ // See if there is any more of the message to send.
+ if (encoder->remaining() == 0) {
+ delete encoder;
+
+ // Stop this watcher for now.
+ ev_io_stop(loop, watcher);
+
+ // Check for more stuff to send on socket.
+ Encoder* next = socket_manager->next(s);
+ if (next != NULL) {
+ watcher->data = next;
+ ev_io_init(watcher, next->sender(), s, EV_WRITE);
+ ev_io_start(loop, watcher);
+ } else {
+ // Nothing more to send right now, clean up.
+ delete watcher;
+ }
+ break;
+ }
+ }
+ }
+}
+
+
+void sending_connect(struct ev_loop* loop, ev_io* watcher, int revents)
+{
+ int s = watcher->fd;
+
+ // Now check that a successful connection was made.
+ int opt;
+ socklen_t optlen = sizeof(opt);
+
+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0 || opt != 0) {
+ // Connect failure.
+ VLOG(1) << "Socket error while connecting";
+ socket_manager->close(s);
+ MessageEncoder* encoder = (MessageEncoder*) watcher->data;
+ delete encoder;
+ ev_io_stop(loop, watcher);
+ delete watcher;
+ } else {
+ // We're connected! Now let's do some sending.
+ ev_io_stop(loop, watcher);
+ ev_io_init(watcher, send_data, s, EV_WRITE);
+ ev_io_start(loop, watcher);
+ }
+}
+
+
+void receiving_connect(struct ev_loop* loop, ev_io* watcher, int revents)
+{
+ int s = watcher->fd;
+
+ // Now check that a successful connection was made.
+ int opt;
+ socklen_t optlen = sizeof(opt);
+
+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0 || opt != 0) {
+ // Connect failure.
+ VLOG(1) << "Socket error while connecting";
+ socket_manager->close(s);
+ DataDecoder* decoder = (DataDecoder*) watcher->data;
+ delete decoder;
+ ev_io_stop(loop, watcher);
+ delete watcher;
+ } else {
+ // We're connected! Now let's do some receiving.
+ ev_io_stop(loop, watcher);
+ ev_io_init(watcher, recv_data, s, EV_READ);
+ ev_io_start(loop, watcher);
+ }
+}
+
+
+void accept(struct ev_loop* loop, ev_io* watcher, int revents)
+{
+ CHECK_EQ(__s__, watcher->fd);
+
+ sockaddr_in addr;
+ socklen_t addrlen = sizeof(addr);
+
+ int s = ::accept(__s__, (sockaddr*) &addr, &addrlen);
+
+ if (s < 0) {
+ return;
+ }
+
+ Try<Nothing> nonblock = os::nonblock(s);
+ if (nonblock.isError()) {
+ LOG_IF(INFO, VLOG_IS_ON(1)) << "Failed to accept, nonblock: "
+ << nonblock.error();
+ os::close(s);
+ return;
+ }
+
+ Try<Nothing> cloexec = os::cloexec(s);
+ if (cloexec.isError()) {
+ LOG_IF(INFO, VLOG_IS_ON(1)) << "Failed to accept, cloexec: "
+ << cloexec.error();
+ os::close(s);
+ return;
+ }
+
+ // Turn off Nagle (TCP_NODELAY) so pipelined requests don't wait.
+ int on = 1;
+ if (setsockopt(s, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) {
+ const char* error = strerror(errno);
+ VLOG(1) << "Failed to turn off the Nagle algorithm: " << error;
+ os::close(s);
+ } else {
+ // Inform the socket manager for proper bookkeeping.
+ const Socket& socket = socket_manager->accepted(s);
+
+ // Allocate and initialize the decoder and watcher.
+ DataDecoder* decoder = new DataDecoder(socket);
+
+ ev_io* watcher = new ev_io();
+ watcher->data = decoder;
+
+ ev_io_init(watcher, recv_data, s, EV_READ);
+ ev_io_start(loop, watcher);
+ }
+}
+
+
+void polled(struct ev_loop* loop, ev_io* watcher, int revents)
+{
+ Promise<short>* promise = (Promise<short>*) watcher->data;
+ promise->set(revents);
+ delete promise;
+
+ ev_io_stop(loop, watcher);
+ delete watcher;
+}
+
+
+void* serve(void* arg)
+{
+ ev_loop(((struct ev_loop*) arg), 0);
+
+ return NULL;
+}
+
+
+void* schedule(void* arg)
+{
+ do {
+ ProcessBase* process = process_manager->dequeue();
+ if (process == NULL) {
+ Gate::state_t old = gate->approach();
+ process = process_manager->dequeue();
+ if (process == NULL) {
+ gate->arrive(old); // Wait at gate if idle.
+ continue;
+ } else {
+ gate->leave();
+ }
+ }
+ process_manager->resume(process);
+ } while (true);
+}
+
+
+// We might find value in catching terminating signals at some point.
+// However, for now, adding signal handlers freely is not allowed
+// because they will clash with Java and Python virtual machines and
+// causes hard to debug crashes/segfaults.
+
+// void sigbad(int signal, struct sigcontext *ctx)
+// {
+// // Pass on the signal (so that a core file is produced).
+// struct sigaction sa;
+// sa.sa_handler = SIG_DFL;
+// sigemptyset(&sa.sa_mask);
+// sa.sa_flags = 0;
+// sigaction(signal, &sa, NULL);
+// raise(signal);
+// }
+
+
+void initialize(const string& delegate)
+{
+ // TODO(benh): Return an error if attempting to initialize again
+ // with a different delegate then originally specified.
+
+ // static pthread_once_t init = PTHREAD_ONCE_INIT;
+ // pthread_once(&init, ...);
+
+ static volatile bool initialized = false;
+ static volatile bool initializing = true;
+
+ // Try and do the initialization or wait for it to complete.
+ if (initialized && !initializing) {
+ return;
+ } else if (initialized && initializing) {
+ while (initializing);
+ return;
+ } else {
+ if (!__sync_bool_compare_and_swap(&initialized, false, true)) {
+ while (initializing);
+ return;
+ }
+ }
+
+// // Install signal handler.
+// struct sigaction sa;
+
+// sa.sa_handler = (void (*) (int)) sigbad;
+// sigemptyset (&sa.sa_mask);
+// sa.sa_flags = SA_RESTART;
+
+// sigaction (SIGTERM, &sa, NULL);
+// sigaction (SIGINT, &sa, NULL);
+// sigaction (SIGQUIT, &sa, NULL);
+// sigaction (SIGSEGV, &sa, NULL);
+// sigaction (SIGILL, &sa, NULL);
+// #ifdef SIGBUS
+// sigaction (SIGBUS, &sa, NULL);
+// #endif
+// #ifdef SIGSTKFLT
+// sigaction (SIGSTKFLT, &sa, NULL);
+// #endif
+// sigaction (SIGABRT, &sa, NULL);
+
+// sigaction (SIGFPE, &sa, NULL);
+
+#ifdef __sun__
+ /* Need to ignore this since we can't do MSG_NOSIGNAL on Solaris. */
+ signal(SIGPIPE, SIG_IGN);
+#endif // __sun__
+
+ // Create a new ProcessManager and SocketManager.
+ process_manager = new ProcessManager(delegate);
+ socket_manager = new SocketManager();
+
+ // Setup processing threads.
+ long cpus = std::max(4L, sysconf(_SC_NPROCESSORS_ONLN));
+
+ for (int i = 0; i < cpus; i++) {
+ pthread_t thread; // For now, not saving handles on our threads.
+ if (pthread_create(&thread, NULL, schedule, NULL) != 0) {
+ LOG(FATAL) << "Failed to initialize, pthread_create";
+ }
+ }
+
+ __ip__ = 0;
+ __port__ = 0;
+
+ char* value;
+
+ // Check environment for ip.
+ value = getenv("LIBPROCESS_IP");
+ if (value != NULL) {
+ int result = inet_pton(AF_INET, value, &__ip__);
+ if (result == 0) {
+ LOG(FATAL) << "LIBPROCESS_IP=" << value << " was unparseable";
+ } else if (result < 0) {
+ PLOG(FATAL) << "Failed to initialize, inet_pton";
+ }
+ }
+
+ // Check environment for port.
+ value = getenv("LIBPROCESS_PORT");
+ if (value != NULL) {
+ int result = atoi(value);
+ if (result < 0 || result > USHRT_MAX) {
+ LOG(FATAL) << "LIBPROCESS_PORT=" << value << " is not a valid port";
+ }
+ __port__ = result;
+ }
+
+ // Create a "server" socket for communicating with other nodes.
+ if ((__s__ = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ PLOG(FATAL) << "Failed to initialize, socket";
+ }
+
+ // Make socket non-blocking.
+ Try<Nothing> nonblock = os::nonblock(__s__);
+ if (nonblock.isError()) {
+ LOG(FATAL) << "Failed to initialize, nonblock: " << nonblock.error();
+ }
+
+ // Set FD_CLOEXEC flag.
+ Try<Nothing> cloexec = os::cloexec(__s__);
+ if (cloexec.isError()) {
+ LOG(FATAL) << "Failed to initialize, cloexec: " << cloexec.error();
+ }
+
+ // Allow address reuse.
+ int on = 1;
+ if (setsockopt(__s__, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
+ PLOG(FATAL) << "Failed to initialize, setsockopt(SO_REUSEADDR)";
+ }
+
+ // Set up socket.
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = PF_INET;
+ addr.sin_addr.s_addr = __ip__;
+ addr.sin_port = htons(__port__);
+
+ if (bind(__s__, (sockaddr*) &addr, sizeof(addr)) < 0) {
+ PLOG(FATAL) << "Failed to initialize, bind";
+ }
+
+ // Lookup and store assigned ip and assigned port.
+ socklen_t addrlen = sizeof(addr);
+ if (getsockname(__s__, (sockaddr*) &addr, &addrlen) < 0) {
+ PLOG(FATAL) << "Failed to initialize, getsockname";
+ }
+
+ __ip__ = addr.sin_addr.s_addr;
+ __port__ = ntohs(addr.sin_port);
+
+ // Lookup hostname if missing ip or if ip is 127.0.0.1 in case we
+ // actually have a valid external ip address. Note that we need only
+ // one ip address, so that other processes can send and receive and
+ // don't get confused as to whom they are sending to.
+ if (__ip__ == 0 || __ip__ == 2130706433) {
+ char hostname[512];
+
+ if (gethostname(hostname, sizeof(hostname)) < 0) {
+ PLOG(FATAL) << "Ffailed to initialize, gethostname";
+ }
+
+ // Lookup IP address of local hostname.
+ hostent* he;
+
+ if ((he = gethostbyname2(hostname, AF_INET)) == NULL) {
+ PLOG(FATAL) << "Failed to initialize, gethostbyname2";
+ }
+
+ __ip__ = *((uint32_t *) he->h_addr_list[0]);
+ }
+
+ if (listen(__s__, 500000) < 0) {
+ PLOG(FATAL) << "Failed to initialize, listen";
+ }
+
+ // Setup event loop.
+#ifdef __sun__
+ loop = ev_default_loop(EVBACKEND_POLL | EVBACKEND_SELECT);
+#else
+ loop = ev_default_loop(EVFLAG_AUTO);
+#endif // __sun__
+
+ ev_async_init(&async_watcher, handle_async);
+ ev_async_start(loop, &async_watcher);
+
+ ev_timer_init(&timeouts_watcher, handle_timeouts, 0., 2100000.0);
+ ev_timer_again(loop, &timeouts_watcher);
+
+ ev_io_init(&server_watcher, accept, __s__, EV_READ);
+ ev_io_start(loop, &server_watcher);
+
+// ev_child_init(&child_watcher, child_exited, pid, 0);
+// ev_child_start(loop, &cw);
+
+// /* Install signal handler. */
+// struct sigaction sa;
+
+// sa.sa_handler = ev_sighandler;
+// sigfillset (&sa.sa_mask);
+// sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
+// sigaction (w->signum, &sa, 0);
+
+// sigemptyset (&sa.sa_mask);
+// sigaddset (&sa.sa_mask, w->signum);
+// sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
+
+ pthread_t thread; // For now, not saving handles on our threads.
+ if (pthread_create(&thread, NULL, serve, loop) != 0) {
+ LOG(FATAL) << "Failed to initialize, pthread_create";
+ }
+
+ // Need to set initialzing here so that we can actually invoke
+ // 'spawn' below for the garbage collector.
+ initializing = false;
+
+ // TODO(benh): Make sure creating the garbage collector, logging
+ // process, and profiler always succeeds and use supervisors to make
+ // sure that none terminate.
+
+ // Create global garbage collector process.
+ gc = spawn(new GarbageCollector());
+
+ // Create the global logging process.
+ spawn(new Logging(), true);
+
+ // Create the global profiler process.
+ spawn(new Profiler(), true);
+
+ // Create the global statistics.
+ // TODO(bmahler): Investigate memory implications of this window
+ // size. We may also want to provide a maximum memory size rather than
+ // time window. Or, offload older data to disk, etc.
+ process::statistics = new Statistics(Weeks(2));
+
+ // Initialize the mime types.
+ mime::initialize();
+
+ // Initialize the response statuses.
+ http::initialize();
+
+ char temp[INET_ADDRSTRLEN];
+ if (inet_ntop(AF_INET, (in_addr*) &__ip__, temp, INET_ADDRSTRLEN) == NULL) {
+ PLOG(FATAL) << "Failed to initialize, inet_ntop";
+ }
+
+ VLOG(1) << "libprocess is initialized on " << temp << ":" << __port__
+ << " for " << cpus << " cpus";
+}
+
+
+uint32_t ip()
+{
+ process::initialize();
+ return __ip__;
+}
+
+
+uint16_t port()
+{
+ process::initialize();
+ return __port__;
+}
+
+
+HttpProxy::HttpProxy(const Socket& _socket)
+ : ProcessBase(ID::generate("__http__")),
+ socket(_socket) {}
+
+
+HttpProxy::~HttpProxy()
+{
+ // Need to make sure response producers know not to continue to
+ // create a response (streaming or otherwise).
+ if (pipe.isSome()) {
+ os::close(pipe.get());
+ }
+ pipe = None();
+
+ while (!items.empty()) {
+ Item* item = items.front();
+
+ // Attempt to discard the future.
+ item->future->discard();
+
+ // But it might have already been ready ...
+ if (item->future->isReady()) {
+ const Response& response = item->future->get();
+ if (response.type == Response::PIPE) {
+ os::close(response.pipe);
+ }
+ }
+
+ items.pop();
+ delete item;
+ }
+}
+
+
+void HttpProxy::enqueue(const Response& response, const Request& request)
+{
+ handle(new Future<Response>(response), request);
+}
+
+
+void HttpProxy::handle(Future<Response>* future, const Request& request)
+{
+ items.push(new Item(request, future));
+
+ if (items.size() == 1) {
+ next();
+ }
+}
+
+
+void HttpProxy::next()
+{
+ if (items.size() > 0) {
+ // Wait for any transition of the future.
+ items.front()->future->onAny(
+ defer(self(), &HttpProxy::waited, lambda::_1));
+ }
+}
+
+
+void HttpProxy::waited(const Future<Response>& future)
+{
+ CHECK(items.size() > 0);
+ Item* item = items.front();
+
+ CHECK(future == *item->future);
+
+ // Process the item and determine if we're done or not (so we know
+ // whether to start waiting on the next responses).
+ bool processed = process(*item->future, item->request);
+
+ items.pop();
+ delete item;
+
+ if (processed) {
+ next();
+ }
+}
+
+
+bool HttpProxy::process(const Future<Response>& future, const Request& request)
+{
+ if (!future.isReady()) {
+ // TODO(benh): Consider handling other "states" of future
+ // (discarded, failed, etc) with different HTTP statuses.
+ socket_manager->send(ServiceUnavailable(), request, socket);
+ return true; // All done, can process next response.
+ }
+
+ Response response = future.get();
+
+ // If the response specifies a path, try and perform a sendfile.
+ if (response.type == Response::PATH) {
+ // Make sure no body is sent (this is really an error and
+ // should be reported and no response sent.
+ response.body.clear();
+
+ const string& path = response.path;
+ int fd = open(path.c_str(), O_RDONLY);
+ if (fd < 0) {
+ if (errno == ENOENT || errno == ENOTDIR) {
+ VLOG(1) << "Returning '404 Not Found' for path '" << path << "'";
+ socket_manager->send(NotFound(), request, socket);
+ } else {
+ const char* error = strerror(errno);
+ VLOG(1) << "Failed to send file at '" << path << "': " << error;
+ socket_manager->send(InternalServerError(), request, socket);
+ }
+ } else {
+ struct stat s; // Need 'struct' because of function named 'stat'.
+ if (fstat(fd, &s) != 0) {
+ const char* error = strerror(errno);
+ VLOG(1) << "Failed to send file at '" << path << "': " << error;
+ socket_manager->send(InternalServerError(), request, socket);
+ } else if (S_ISDIR(s.st_mode)) {
+ VLOG(1) << "Returning '404 Not Found' for directory '" << path << "'";
+ socket_manager->send(NotFound(), request, socket);
+ } else {
+ // While the user is expected to properly set a 'Content-Type'
+ // header, we fill in (or overwrite) 'Content-Length' header.
+ stringstream out;
+ out << s.st_size;
+ response.headers["Content-Length"] = out.str();
+
+ if (s.st_size == 0) {
+ socket_manager->send(response, request, socket);
+ return true; // All done, can process next request.
+ }
+
+ VLOG(1) << "Sending file at '" << path << "' with length " << s.st_size;
+
+ // TODO(benh): Consider a way to have the socket manager turn
+ // on TCP_CORK for both sends and then turn it off.
+ socket_manager->send(
+ new HttpResponseEncoder(socket, response, request),
+ true);
+
+ // Note the file descriptor gets closed by FileEncoder.
+ socket_manager->send(
+ new FileEncoder(socket, fd, s.st_size),
+ request.keepAlive);
+ }
+ }
+ } else if (response.type == Response::PIPE) {
+ // Make sure no body is sent (this is really an error and
+ // should be reported and no response sent.
+ response.body.clear();
+
+ // Make sure the pipe is nonblocking.
+ Try<Nothing> nonblock = os::nonblock(response.pipe);
+ if (nonblock.isError()) {
+ const char* error = strerror(errno);
+ VLOG(1) << "Failed make pipe nonblocking: " << error;
+ socket_manager->send(InternalServerError(), request, socket);
+ return true; // All done, can process next response.
+ }
+
+ // While the user is expected to properly set a 'Content-Type'
+ // header, we fill in (or overwrite) 'Transfer-Encoding' header.
+ response.headers["Transfer-Encoding"] = "chunked";
+
+ VLOG(1) << "Starting \"chunked\" streaming";
+
+ socket_manager->send(
+ new HttpResponseEncoder(socket, response, request),
+ true);
+
+ pipe = response.pipe;
+
+ io::poll(pipe.get(), io::READ).onAny(
+ defer(self(), &Self::stream, lambda::_1, request));
+
+ return false; // Streaming, don't process next response (yet)!
+ } else {
+ socket_manager->send(response, request, socket);
+ }
+
+ return true; // All done, can process next response.
+}
+
+
+void HttpProxy::stream(const Future<short>& poll, const Request& request)
+{
+ // TODO(benh): Use 'splice' on Linux.
+
+ CHECK(pipe.isSome());
+
+ bool finished = false; // Whether we're done streaming.
+
+ if (poll.isReady()) {
+ // Read and write.
+ CHECK(poll.get() == io::READ);
+ const size_t size = 4 * 1024; // 4K.
+ char data[size];
+ while (!finished) {
+ ssize_t length = ::read(pipe.get(), data, size);
+ if (length < 0 && (errno == EINTR)) {
+ // Interrupted, try again now.
+ continue;
+ } else if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ // Might block, try again later.
+ io::poll(pipe.get(), io::READ).onAny(
+ defer(self(), &Self::stream, lambda::_1, request));
+ break;
+ } else {
+ std::ostringstream out;
+ if (length <= 0) {
+ // Error or closed, treat both as closed.
+ if (length < 0) {
+ // Error.
+ const char* error = strerror(errno);
+ VLOG(1) << "Read error while streaming: " << error;
+ }
+ out << "0\r\n" << "\r\n";
+ finished = true;
+ } else {
+ // Data!
+ out << std::hex << length << "\r\n";
+ out.write(data, length);
+ out << "\r\n";
+ }
+
+ // We always persist the connection when we're not finished
+ // streaming.
+ socket_manager->send(
+ new DataEncoder(socket, out.str()),
+ finished ? request.keepAlive : true);
+ }
+ }
+ } else if (poll.isFailed()) {
+ VLOG(1) << "Failed to poll: " << poll.failure();
+ socket_manager->send(InternalServerError(), request, socket);
+ finished = true;
+ } else {
+ VLOG(1) << "Unexpected discarded future while polling";
+ socket_manager->send(InternalServerError(), request, socket);
+ finished = true;
+ }
+
+ if (finished) {
+ os::close(pipe.get());
+ pipe = None();
+ next();
+ }
+}
+
+
+SocketManager::SocketManager()
+{
+ synchronizer(this) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
+}
+
+
+SocketManager::~SocketManager() {}
+
+
+Socket SocketManager::accepted(int s)
+{
+ synchronized (this) {
+ return sockets[s] = Socket(s);
+ }
+}
+
+
+void SocketManager::link(ProcessBase* process, const UPID& to)
+{
+ // TODO(benh): The semantics we want to support for link are such
+ // that if there is nobody to link to (local or remote) then an
+ // ExitedEvent gets generated. This functionality has only been
+ // implemented when the link is local, not remote. Of course, if
+ // there is nobody listening on the remote side, then this should
+ // work remotely ... but if there is someone listening remotely just
+ // not at that id, then it will silently continue executing.
+
+ CHECK(process != NULL);
+
+ Node node(to.ip, to.port);
+
+ synchronized (this) {
+ // Check if node is remote and there isn't a persistant link.
+ if ((node.ip != __ip__ || node.port != __port__)
+ && persists.count(node) == 0) {
+ // Okay, no link, lets create a socket.
+ int s;
+
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ PLOG(FATAL) << "Failed to link, socket";
+ }
+
+ Try<Nothing> nonblock = os::nonblock(s);
+ if (nonblock.isError()) {
+ LOG(FATAL) << "Failed to link, nonblock: " << nonblock.error();
+ }
+
+ Try<Nothing> cloexec = os::cloexec(s);
+ if (cloexec.isError()) {
+ LOG(FATAL) << "Failed to link, cloexec: " << cloexec.error();
+ }
+
+ sockets[s] = Socket(s);
+ nodes[s] = node;
+
+ persists[node] = s;
+
+ // Allocate and initialize the decoder and watcher (we really
+ // only "receive" on this socket so that we can react when it
+ // gets closed and generate appropriate lost events).
+ DataDecoder* decoder = new DataDecoder(sockets[s]);
+
+ ev_io* watcher = new ev_io();
+ watcher->data = decoder;
+
+ // Try and connect to the node using this socket.
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = PF_INET;
+ addr.sin_port = htons(to.port);
+ addr.sin_addr.s_addr = to.ip;
+
+ if (connect(s, (sockaddr*) &addr, sizeof(addr)) < 0) {
+ if (errno != EINPROGRESS) {
+ PLOG(FATAL) << "Failed to link, connect";
+ }
+
+ // Wait for socket to be connected.
+ ev_io_init(watcher, receiving_connect, s, EV_WRITE);
+ } else {
+ ev_io_init(watcher, recv_data, s, EV_READ);
+ }
+
+ // Enqueue the watcher.
+ synchronized (watchers) {
+ watchers->push(watcher);
+ }
+
+ // Interrupt the loop.
+ ev_async_send(loop, &async_watcher);
+ }
+
+ links[to].insert(process);
+ }
+}
+
+
+PID<HttpProxy> SocketManager::proxy(const Socket& socket)
+{
+ HttpProxy* proxy = NULL;
+
+ synchronized (this) {
+ // This socket might have been asked to get closed (e.g., remote
+ // side hang up) while a process is attempting to handle an HTTP
+ // request. Thus, if there is no more socket, return an empty PID.
+ if (sockets.count(socket) > 0) {
+ if (proxies.count(socket) > 0) {
+ return proxies[socket]->self();
+ } else {
+ proxy = new HttpProxy(sockets[socket]);
+ proxies[socket] = proxy;
+ }
+ }
+ }
+
+ // Now check if we need to spawn a newly created proxy. Note that we
+ // need to do this outside of the synchronized block above to avoid
+ // a possible deadlock (because spawn eventually synchronizes on
+ // ProcessManager and ProcessManager::cleanup synchronizes on
+ // ProcessManager and then SocketManager, so a deadlock results if
+ // we do spawn within the synchronized block above).
+ if (proxy != NULL) {
+ return spawn(proxy, true);
+ }
+
+ return PID<HttpProxy>();
+}
+
+
+void SocketManager::send(Encoder* encoder, bool persist)
+{
+ CHECK(encoder != NULL);
+
+ synchronized (this) {
+ if (sockets.count(encoder->socket()) > 0) {
+ // Update whether or not this socket should get disposed after
+ // there is no more data to send.
+ if (!persist) {
+ dispose.insert(encoder->socket());
+ }
+
+ if (outgoing.count(encoder->socket()) > 0) {
+ outgoing[encoder->socket()].push(encoder);
+ } else {
+ // Initialize the outgoing queue.
+ outgoing[encoder->socket()];
+
+ // Allocate and initialize the watcher.
+ ev_io* watcher = new ev_io();
+ watcher->data = encoder;
+
+ ev_io_init(watcher, encoder->sender(), encoder->socket(), EV_WRITE);
+
+ synchronized (watchers) {
+ watchers->push(watcher);
+ }
+
+ ev_async_send(loop, &async_watcher);
+ }
+ } else {
+ VLOG(1) << "Attempting to send on a no longer valid socket!";
+ delete encoder;
+ }
+ }
+}
+
+
+void SocketManager::send(
+ const Response& response,
+ const Request& request,
+ const Socket& socket)
+{
+ bool persist = request.keepAlive;
+
+ // Don't persist the connection if the headers include
+ // 'Connection: close'.
+ if (response.headers.contains("Connection")) {
+ if (response.headers.get("Connection").get() == "close") {
+ persist = false;
+ }
+ }
+
+ send(new HttpResponseEncoder(socket, response, request), persist);
+}
+
+
+void SocketManager::send(Message* message)
+{
+ CHECK(message != NULL);
+
+ Node node(message->to.ip, message->to.port);
+
+ synchronized (this) {
+ // Check if there is already a socket.
+ bool persist = persists.count(node) > 0;
+ bool temp = temps.count(node) > 0;
+ if (persist || temp) {
+ int s = persist ? persists[node] : temps[node];
+ CHECK(sockets.count(s) > 0);
+ send(new MessageEncoder(sockets[s], message), persist);
+ } else {
+ // No peristant or temporary socket to the node currently
+ // exists, so we create a temporary one.
+ int s;
+
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ PLOG(FATAL) << "Failed to send, socket";
+ }
+
+ Try<Nothing> nonblock = os::nonblock(s);
+ if (nonblock.isError()) {
+ LOG(FATAL) << "Failed to send, nonblock: " << nonblock.error();
+ }
+
+ Try<Nothing> cloexec = os::cloexec(s);
+ if (cloexec.isError()) {
+ LOG(FATAL) << "Failed to send, cloexec: " << cloexec.error();
+ }
+
+ sockets[s] = Socket(s);
+ nodes[s] = node;
+ temps[node] = s;
+
+ dispose.insert(s);
+
+ // Initialize the outgoing queue.
+ outgoing[s];
+
+ // Allocate and initialize the watcher.
+ ev_io* watcher = new ev_io();
+ watcher->data = new MessageEncoder(sockets[s], message);
+
+ // Try and connect to the node using this socket.
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = PF_INET;
+ addr.sin_port = htons(message->to.port);
+ addr.sin_addr.s_addr = message->to.ip;
+
+ if (connect(s, (sockaddr*) &addr, sizeof(addr)) < 0) {
+ if (errno != EINPROGRESS) {
+ PLOG(FATAL) << "Failed to send, connect";
+ }
+
+ // Initialize watcher for connecting.
+ ev_io_init(watcher, sending_connect, s, EV_WRITE);
+ } else {
+ // Initialize watcher for sending.
+ ev_io_init(watcher, send_data, s, EV_WRITE);
+ }
+
+ // Enqueue the watcher.
+ synchronized (watchers) {
+ watchers->push(watcher);
+ }
+
+ ev_async_send(loop, &async_watcher);
+ }
+ }
+}
+
+
+Encoder* SocketManager::next(int s)
+{
+ HttpProxy* proxy = NULL; // Non-null if needs to be terminated.
+
+ synchronized (this) {
+ // We cannot assume 'sockets.count(s) > 0' here because it's
+ // possible that 's' has been removed with a a call to
+ // SocketManager::close. For example, it could be the case that a
+ // socket has gone to CLOSE_WAIT and the call to 'recv' in
+ // recv_data returned 0 causing SocketManager::close to get
+ // invoked. Later a call to 'send' or 'sendfile' (e.g., in
+ // send_data or send_file) can "succeed" (because the socket is
+ // not "closed" yet because there are still some Socket
+ // references, namely the reference being used in send_data or
+ // send_file!). However, when SocketManger::next is actually
+ // invoked we find out there there is no more data and thus stop
+ // sending.
+ // TODO(benh): Should we actually finish sending the data!?
+ if (sockets.count(s) > 0) {
+ CHECK(outgoing.count(s) > 0);
+
+ if (!outgoing[s].empty()) {
+ // More messages!
+ Encoder* encoder = outgoing[s].front();
+ outgoing[s].pop();
+ return encoder;
+ } else {
+ // No more messages ... erase the outgoing queue.
+ outgoing.erase(s);
+
+ if (dispose.count(s) > 0) {
+ // This is either a temporary socket we created or it's a
+ // socket that we were receiving data from and possibly
+ // sending HTTP responses back on. Clean up either way.
+ if (nodes.count(s) > 0) {
+ const Node& node = nodes[s];
+ CHECK(temps.count(node) > 0 && temps[node] == s);
+ temps.erase(node);
+ nodes.erase(s);
+ }
+
+ if (proxies.count(s) > 0) {
+ proxy = proxies[s];
+ proxies.erase(s);
+ }
+
+ dispose.erase(s);
+ sockets.erase(s);
+
+ // We don't actually close the socket (we wait for the Socket
+ // abstraction to close it once there are no more references),
+ // but we do shutdown the receiving end so any DataDecoder
+ // will get cleaned up (which might have the last reference).
+ shutdown(s, SHUT_RD);
+ }
+ }
+ }
+ }
+
+ // We terminate the proxy outside the synchronized block to avoid
+ // possible deadlock between the ProcessManager and SocketManager
+ // (see comment in SocketManager::proxy for more information).
+ if (proxy != NULL) {
+ terminate(proxy);
+ }
+
+ return NULL;
+}
+
+
+void SocketManager::close(int s)
+{
+ HttpProxy* proxy = NULL; // Non-null if needs to be terminated.
+
+ synchronized (this) {
+ // This socket might not be active if it was already asked to get
+ // closed (e.g., a write on the socket failed so we try and close
+ // it and then later the read side of the socket gets closed so we
+ // try and close it again). Thus, ignore the request if we don't
+ // know about the socket.
+ if (sockets.count(s) > 0) {
+ // Clean up any remaining encoders for this socket.
+ if (outgoing.count(s) > 0) {
+ while (!outgoing[s].empty()) {
+ Encoder* encoder = outgoing[s].front();
+ delete encoder;
+ outgoing[s].pop();
+ }
+
+ outgoing.erase(s);
+ }
+
+ // Clean up after sockets used for node communication.
+ if (nodes.count(s) > 0) {
+ const Node& node = nodes[s];
+
+ // Don't bother invoking exited unless socket was persistant.
+ if (persists.count(node) > 0 && persists[node] == s) {
+ persists.erase(node);
+ exited(node); // Generate ExitedEvent(s)!
+ } else if (temps.count(node) > 0 && temps[node] == s) {
+ temps.erase(node);
+ }
+
+ nodes.erase(s);
+ }
+
+ // Clean up any proxy associated with this socket.
+ if (proxies.count(s) > 0) {
+ proxy = proxies[s];
+ proxies.erase(s);
+ }
+
+ dispose.erase(s);
+ sockets.erase(s);
+ }
+ }
+
+ // We terminate the proxy outside the synchronized block to avoid
+ // possible deadlock between the ProcessManager and SocketManager.
+ if (proxy != NULL) {
+ terminate(proxy);
+ }
+
+ // Note that we don't actually:
+ //
+ // close(s);
+ //
+ // Because, for example, there could be a race between an HttpProxy
+ // trying to do send a response with SocketManager::send() or a
+ // process might be responding to another Request (e.g., trying
+ // to do a sendfile) since these things may be happening
+ // asynchronously we can't close the socket yet, because it might
+ // get reused before any of the above things have finished, and then
+ // we'll end up sending data on the wrong socket! Instead, we rely
+ // on the last reference of our Socket object to close the
+ // socket. Note, however, that since socket is no longer in
+ // 'sockets' any attempt to send with it will just get ignored.
+}
+
+
+void SocketManager::exited(const Node& node)
+{
+ // TODO(benh): It would be cleaner if this routine could call back
+ // into ProcessManager ... then we wouldn't have to convince
+ // ourselves that the accesses to each Process object will always be
+ // valid.
+ synchronized (this) {
+ list<UPID> removed;
+ // Look up all linked processes.
+ foreachpair (const UPID& linkee, set<ProcessBase*>& processes, links) {
+ if (linkee.ip == node.ip && linkee.port == node.port) {
+ foreach (ProcessBase* linker, processes) {
+ linker->enqueue(new ExitedEvent(linkee));
+ }
+ removed.push_back(linkee);
+ }
+ }
+
+ foreach (const UPID& pid, removed) {
+ links.erase(pid);
+ }
+ }
+}
+
+
+void SocketManager::exited(ProcessBase* process)
+{
+ // An exited event is enough to cause the process to get deleted
+ // (e.g., by the garbage collector), which means we can't
+ // dereference process (or even use the address) after we enqueue at
+ // least one exited event. Thus, we save the process pid.
+ const UPID pid = process->pid;
+
+ // Likewise, we need to save the current time of the process so we
+ // can update the clocks of linked processes as appropriate.
+ const Time time = Clock::now(process);
+
+ synchronized (this) {
+ // Iterate through the links, removing any links the process might
+ // have had and creating exited events for any linked processes.
+ foreachpair (const UPID& linkee, set<ProcessBase*>& processes, links) {
+ processes.erase(process);
+
+ if (linkee == pid) {
+ foreach (ProcessBase* linker, processes) {
+ CHECK(linker != process) << "Process linked with itself";
+ synchronized (timeouts) {
+ if (Clock::paused()) {
+ Clock::update(linker, time);
+ }
+ }
+ linker->enqueue(new ExitedEvent(linkee));
+ }
+ }
+ }
+
+ links.erase(pid);
+ }
+}
+
+
+ProcessManager::ProcessManager(const string& _delegate)
+ : delegate(_delegate)
+{
+ synchronizer(processes) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
+ synchronizer(runq) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
+ running = 0;
+ __sync_synchronize(); // Ensure write to 'running' visible in other threads.
+}
+
+
+ProcessManager::~ProcessManager() {}
+
+
+ProcessReference ProcessManager::use(const UPID& pid)
+{
+ if (pid.ip == __ip__ && pid.port == __port__) {
+ synchronized (processes) {
+ if (processes.count(pid.id) > 0) {
+ // Note that the ProcessReference constructor _must_ get
+ // called while holding the lock on processes so that waiting
+ // for references is atomic (i.e., race free).
+ return ProcessReference(processes[pid.id]);
+ }
+ }
+ }
+
+ return ProcessReference(NULL);
+}
+
+
+bool ProcessManager::handle(
+ const Socket& socket,
+ Request* request)
+{
+ CHECK(request != NULL);
+
+ // Check if this is a libprocess request (i.e., 'User-Agent:
+ // libprocess/id@ip:port') and if so, parse as a message.
+ if (libprocess(request)) {
+ Message* message = parse(request);
+ if (message != NULL) {
+ delete request;
+ // TODO(benh): Use the sender PID in order to capture
+ // happens-before timing relationships for testing.
+ return deliver(message->to, new MessageEvent(message));
+ }
+
+ VLOG(1) << "Failed to handle libprocess request: "
+ << request->method << " " << request->path
+ << " (User-Agent: " << request->headers["User-Agent"] << ")";
+
+ delete request;
+ return false;
+ }
+
+ // Treat this as an HTTP request. Start by checking that the path
+ // starts with a '/' (since the code below assumes as much).
+ if (request->path.find('/') != 0) {
+ VLOG(1) << "Returning '400 Bad Request' for '" << request->path << "'";
+
+ // Get the HttpProxy pid for this socket.
+ PID<HttpProxy> proxy = socket_manager->proxy(socket);
+
+ // Enqueue the response with the HttpProxy so that it respects the
+ // order of requests to account for HTTP/1.1 pipelining.
+ dispatch(proxy, &HttpProxy::enqueue, BadRequest(), *request);
+
+ // Cleanup request.
+ delete request;
+ return false;
+ }
+
+ // Ignore requests with relative paths (i.e., contain "/..").
+ if (request->path.find("/..") != string::npos) {
+ VLOG(1) << "Returning '404 Not Found' for '" << request->path
+ << "' (ignoring requests with relative paths)";
+
+ // Get the HttpProxy pid for this socket.
+ PID<HttpProxy> proxy = socket_manager->proxy(socket);
+
+ // Enqueue the response with the HttpProxy so that it respects the
+ // order of requests to account for HTTP/1.1 pipelining.
+ dispatch(proxy, &HttpProxy::enqueue, NotFound(), *request);
+
+ // Cleanup request.
+ delete request;
+ return false;
+ }
+
+ // Split the path by '/'.
+ vector<string> tokens = strings::tokenize(request->path, "/");
+
+ // Try and determine a receiver, otherwise try and delegate.
+ ProcessReference receiver;
+
+ if (tokens.size() == 0 && delegate != "") {
+ request->path = "/" + delegate;
+ receiver = use(UPID(delegate, __ip__, __port__));
+ } else if (tokens.size() > 0) {
+ receiver = use(UPID(tokens[0], __ip__, __port__));
+ }
+
+ if (!receiver && delegate != "") {
+ // Try and delegate the request.
+ request->path = "/" + delegate + request->path;
+ receiver = use(UPID(delegate, __ip__, __port__));
+ }
+
+ if (receiver) {
+ // TODO(benh): Use the sender PID in order to capture
+ // happens-before timing relationships for testing.
+ return deliver(receiver, new HttpEvent(socket, request));
+ }
+
+ // This has no receiver, send error response.
+ VLOG(1) << "Returning '404 Not Found' for '" << request->path << "'";
+
+ // Get the HttpProxy pid for this socket.
+ PID<HttpProxy> proxy = socket_manager->proxy(socket);
+
+ // Enqueue the response with the HttpProxy so that it respects the
+ // order of requests to account for HTTP/1.1 pipelining.
+ dispatch(proxy, &HttpProxy::enqueue, NotFound(), *request);
+
+ // Cleanup request.
+ delete request;
+ return false;
+}
+
+
+bool ProcessManager::deliver(
+ ProcessBase* receiver,
+ Event* event,
+ ProcessBase* sender)
+{
+ CHECK(event != NULL);
+
+ // If we are using a manual clock then update the current time of
+ // the receiver using the sender if necessary to preserve the
+ // happens-before relationship between the sender and receiver. Note
+ // that the assumption is that the sender remains valid for at least
+ // the duration of this routine (so that we can look up it's current
+ // time).
+ if (Clock::paused()) {
+ synchronized (timeouts) {
+ if (Clock::paused()) {
+ if (sender != NULL) {
+ Clock::order(sender, receiver);
+ } else {
+ Clock::update(receiver, Clock::now());
+ }
+ }
+ }
+ }
+
+ receiver->enqueue(event);
+
+ return true;
+}
+
+bool ProcessManager::deliver(
+ const UPID& to,
+ Event* event,
+ ProcessBase* sender)
+{
+ CHECK(event != NULL);
+
+ if (ProcessReference receiver = use(to)) {
+ return deliver(receiver, event, sender);
+ }
+
+ delete event;
+ return false;
+}
+
+
+UPID ProcessManager::spawn(ProcessBase* process, bool manage)
+{
+ CHECK(process != NULL);
+
+ synchronized (processes) {
+ if (processes.count(process->pid.id) > 0) {
+ return UPID();
+ } else {
+ processes[process->pid.id] = process;
+ }
+ }
+
+ // Use the garbage collector if requested.
+ if (manage) {
+ dispatch(gc, &GarbageCollector::manage<ProcessBase>, process);
+ }
+
+ // We save the PID before enqueueing the process to avoid the race
+ // condition that occurs when a user has a very short process and
+ // the process gets run and cleaned up before we return from enqueue
+ // (e.g., when 'manage' is set to true).
+ UPID pid = process->self();
+
+ // Add process to the run queue (so 'initialize' will get invoked).
+ enqueue(process);
+
+ VLOG(2) << "Spawned process " << pid;
+
+ return pid;
+}
+
+
+void ProcessManager::resume(ProcessBase* process)
+{
+ __process__ = process;
+
+ VLOG(2) << "Resuming " << process->pid << " at " << Clock::now();
+
+ bool terminate = false;
+ bool blocked = false;
+
+ CHECK(process->state == ProcessBase::BOTTOM ||
+ process->state == ProcessBase::READY);
+
+ if (process->state == ProcessBase::BOTTOM) {
+ process->state = ProcessBase::RUNNING;
+ try { process->initialize(); }
+ catch (...) { terminate = true; }
+ }
+
+ while (!terminate && !blocked) {
+ Event* event = NULL;
+
+ process->lock();
+ {
+ if (process->events.size() > 0) {
+ event = process->events.front();
+ process->events.pop_front();
+ process->state = ProcessBase::RUNNING;
+ } else {
+ process->state = ProcessBase::BLOCKED;
+ blocked = true;
+ }
+ }
+ process->unlock();
+
+ if (!blocked) {
+ CHECK(event != NULL);
+
+ // Determine if we should filter this event.
+ synchronized (filterer) {
+ if (filterer != NULL) {
+ bool filter = false;
+ struct FilterVisitor : EventVisitor
+ {
+ FilterVisitor(bool* _filter) : filter(_filter) {}
+
+ virtual void visit(const MessageEvent& event)
+ {
+ *filter = filterer->filter(event);
+ }
+
+ virtual void visit(const DispatchEvent& event)
+ {
+ *filter = filterer->filter(event);
+ }
+
+ virtual void visit(const HttpEvent& event)
+ {
+ *filter = filterer->filter(event);
+ }
+
+ virtual void visit(const ExitedEvent& event)
+ {
+ *filter = filterer->filter(event);
+ }
+
+ bool* filter;
+ } visitor(&filter);
+
+ event->visit(&visitor);
+
+ if (filter) {
+ delete event;
+ continue; // Try and execute the next event.
+ }
+ }
+ }
+
+ // Determine if we should terminate.
+ terminate = event->is<TerminateEvent>();
+
+ // Now service the event.
+ try {
+ process->serve(*event);
+ } catch (const std::exception& e) {
+ std::cerr << "libprocess: " << process->pid
+ << " terminating due to "
+ << e.what() << std::endl;
+ terminate = true;
+ } catch (...) {
+ std::cerr << "libprocess: " << process->pid
+ << " terminating due to unknown exception" << std::endl;
+ terminate = true;
+ }
+
+ delete event;
+
+ if (terminate) {
+ cleanup(process);
+ }
+ }
+ }
+
+ __process__ = NULL;
+
+ CHECK_GE(running, 1);
+ __sync_fetch_and_sub(&running, 1);
+}
+
+
+void ProcessManager::cleanup(ProcessBase* process)
+{
+ VLOG(2) << "Cleaning up " << process->pid;
+
+ // First, set the terminating state so no more events will get
+ // enqueued and delete al the pending events. We want to delete the
+ // events before we hold the processes lock because deleting an
+ // event could cause code outside libprocess to get executed which
+ // might cause a deadlock with the processes lock. Likewise,
+ // deleting the events now rather than later has the nice property
+ // of making sure that any events that might have gotten enqueued on
+ // the process we are cleaning up will get dropped (since it's
+ // terminating) and eliminates the potential of enqueueing them on
+ // another process that gets spawned with the same PID.
+ deque<Event*> events;
+
+ process->lock();
+ {
+ process->state = ProcessBase::TERMINATING;
+ events = process->events;
+ process->events.clear();
+ }
+ process->unlock();
+
+ // Delete pending events.
+ while (!events.empty()) {
+ Event* event = events.front();
+ events.pop_front();
+ delete event;
+ }
+
+ // Possible gate non-libprocess threads are waiting at.
+ Gate* gate = NULL;
+
+ // Remove process.
+ synchronized (processes) {
+ // Wait for all process references to get cleaned up.
+ while (process->refs > 0) {
+ asm ("pause");
+ __sync_synchronize();
+ }
+
+ process->lock();
+ {
+ CHECK(process->events.empty());
+
+ processes.erase(process->pid.id);
+
+ // Lookup gate to wake up waiting threads.
+ map<ProcessBase*, Gate*>::iterator it = gates.find(process);
+ if (it != gates.end()) {
+ gate = it->second;
+ // N.B. The last thread that leaves the gate also free's it.
+ gates.erase(it);
+ }
+
+ CHECK(process->refs == 0);
+ process->state = ProcessBase::TERMINATED;
+ }
+ process->unlock();
+
+ // Note that we don't remove the process from the clock during
+ // cleanup, but rather the clock is reset for a process when it is
+ // created (see ProcessBase::ProcessBase). We do this so that
+ // SocketManager::exited can access the current time of the
+ // process to "order" exited events. TODO(benh): It might make
+ // sense to consider storing the time of the process as a field of
+ // the class instead.
+
+ // Now we tell the socket manager about this process exiting so
+ // that it can create exited events for linked processes. We
+ // _must_ do this while synchronized on processes because
+ // otherwise another process could attempt to link this process
+ // and SocketManger::link would see that the processes doesn't
+ // exist when it attempts to get a ProcessReference (since we
+ // removed the process above) thus causing an exited event, which
+ // could cause the process to get deleted (e.g., the garbage
+ // collector might link _after_ the process has already been
+ // removed from processes thus getting an exited event but we
+ // don't want that exited event to fire and actually delete the
+ // process until after we have used the process in
+ // SocketManager::exited).
+ socket_manager->exited(process);
+
+ // ***************************************************************
+ // At this point we can no longer dereference the process since it
+ // might already be deallocated (e.g., by the garbage collector).
+ // ***************************************************************
+
+ // Note that we need to open the gate while synchronized on
+ // processes because otherwise we might _open_ the gate before
+ // another thread _approaches_ the gate causing that thread to
+ // wait on _arrival_ to the gate forever (see
+ // ProcessManager::wait).
+ if (gate != NULL) {
+ gate->open();
+ }
+ }
+}
+
+
+void ProcessManager::link(ProcessBase* process, const UPID& to)
+{
+ // Check if the pid is local.
+ if (!(to.ip == __ip__ && to.port == __port__)) {
+ socket_manager->link(process, to);
+ } else {
+ // Since the pid is local we want to get a reference to it's
+ // underlying process so that while we are invoking the link
+ // manager we don't miss sending a possible ExitedEvent.
+ if (ProcessReference _ = use(to)) {
+ socket_manager->link(process, to);
+ } else {
+ // Since the pid isn't valid it's process must have already died
+ // (or hasn't been spawned yet) so send a process exit message.
+ process->enqueue(new ExitedEvent(to));
+ }
+ }
+}
+
+
+void ProcessManager::terminate(
+ const UPID& pid,
+ bool inject,
+ ProcessBase* sender)
+{
+ if (ProcessReference process = use(pid)) {
+ if (Clock::paused()) {
+ synchronized (timeouts) {
+ if (Clock::paused()) {
+ if (sender != NULL) {
+ Clock::order(sender, process);
+ } else {
+ Clock::update(process, Clock::now());
+ }
+ }
+ }
+ }
+
+ if (sender != NULL) {
+ process->enqueue(new TerminateEvent(sender->self()), inject);
+ } else {
+ process->enqueue(new TerminateEvent(UPID()), inject);
+ }
+ }
+}
+
+
+bool ProcessManager::wait(const UPID& pid)
+{
+ // We use a gate for waiters. A gate is single use. That is, a new
+ // gate is created when the first thread shows up and wants to wait
+ // for a process that currently has no gate. Once that process
+ // exits, the last thread to leave the gate will also clean it
+ // up. Note that a gate will never get more threads waiting on it
+ // after it has been opened, since the process should no longer be
+ // valid and therefore will not have an entry in 'processes'.
+
+ Gate* gate = NULL;
+ Gate::state_t old;
+
+ ProcessBase* process = NULL; // Set to non-null if we donate thread.
+
+ // Try and approach the gate if necessary.
+ synchronized (processes) {
+ if (processes.count(pid.id) > 0) {
+ process = processes[pid.id];
+ CHECK(process->state != ProcessBase::TERMINATED);
+
+ // Check and see if a gate already exists.
+ if (gates.find(process) == gates.end()) {
+ gates[process] = new Gate();
+ }
+
+ gate = gates[process];
+ old = gate->approach();
+
+ // Check if it is runnable in order to donate this thread.
+ if (process->state == ProcessBase::BOTTOM ||
+ process->state == ProcessBase::READY) {
+ synchronized (runq) {
+ list<ProcessBase*>::iterator it =
+ find(runq.begin(), runq.end(), process);
+ if (it != runq.end()) {
+ runq.erase(it);
+ } else {
+ // Another thread has resumed the process ...
+ process = NULL;
+ }
+ }
+ } else {
+ // Process is not runnable, so no need to donate ...
+ process = NULL;
+ }
+ }
+ }
+
+ if (process != NULL) {
+ VLOG(2) << "Donating thread to " << process->pid << " while waiting";
+ ProcessBase* donator = __process__;
+ __sync_fetch_and_add(&running, 1);
+ process_manager->resume(process);
+ __process__ = donator;
+ }
+
+ // TODO(benh): Donating only once may not be sufficient, so we might
+ // still deadlock here ... perhaps warn if that's the case?
+
+ // Now arrive at the gate and wait until it opens.
+ if (gate != NULL) {
+ gate->arrive(old);
+
+ if (gate->empty()) {
+ delete gate;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+
+void ProcessManager::enqueue(ProcessBase* process)
+{
+ CHECK(process != NULL);
+
+ // TODO(benh): Check and see if this process has it's own thread. If
+ // it does, push it on that threads runq, and wake up that thread if
+ // it's not running. Otherwise, check and see which thread this
+ // process was last running on, and put it on that threads runq.
+
+ synchronized (runq) {
+ CHECK(find(runq.begin(), runq.end(), process) == runq.end());
+ runq.push_back(process);
+ }
+
+ // Wake up the processing thread if necessary.
+ gate->open();
+}
+
+
+ProcessBase* ProcessManager::dequeue()
+{
+ // TODO(benh): Remove a process from this thread's runq. If there
+ // are no processes to run, and this is not a dedicated thread, then
+ // steal one from another threads runq.
+
+ ProcessBase* process = NULL;
+
+ synchronized (runq) {
+ if (!runq.empty()) {
+ process = runq.front();
+ runq.pop_front();
+ // Increment the running count of processes in order to support
+ // the Clock::settle() operation (this must be done atomically
+ // with removing the process from the runq).
+ __sync_fetch_and_add(&running, 1);
+ }
+ }
+
+ return process;
+}
+
+
+void ProcessManager::settle()
+{
+ bool done = true;
+ do {
+ os::sleep(Milliseconds(10));
+ done = true;
+ // Hopefully this is the only place we acquire both these locks.
+ synchronized (runq) {
+ synchronized (timeouts) {
+ CHECK(Clock::paused()); // Since another thread could resume the clock!
+
+ if (!runq.empty()) {
+ done = false;
+ }
+
+ __sync_synchronize(); // Read barrier for 'running'.
+ if (running > 0) {
+ done = false;
+ }
+
+ if (timeouts->size() > 0 &&
+ timeouts->begin()->first <= clock::current) {
+ done = false;
+ }
+
+ if (pending_timers) {
+ done = false;
+ }
+ }
+ }
+ } while (!done);
+}
+
+
+Timer Timer::create(
+ const Duration& duration,
+ const lambda::function<void(void)>& thunk)
+{
+ static uint64_t id = 1; // Start at 1 since Timer() instances start with 0.
+
+ // Assumes Clock::now() does Clock::now(__process__).
+ Timeout timeout = Timeout::in(duration);
+
+ UPID pid = __process__ != NULL ? __process__->self() : UPID();
+
+ Timer timer(__sync_fetch_and_add(&id, 1), timeout, pid, thunk);
+
+ VLOG(3) << "Created a timer for " << timeout.time();
+
+ // Add the timer.
+ synchronized (timeouts) {
+ if (timeouts->size() == 0 ||
+ timer.timeout().time() < timeouts->begin()->first) {
+ // Need to interrupt the loop to update/set timer repeat.
+ (*timeouts)[timer.timeout().time()].push_back(timer);
+ update_timer = true;
+ ev_async_send(loop, &async_watcher);
+ } else {
+ // Timer repeat is adequate, just add the timeout.
+ CHECK(timeouts->size() >= 1);
+ (*timeouts)[timer.timeout().time()].push_back(timer);
+ }
+ }
+
+ return timer;
+}
+
+
+bool Timer::cancel(const Timer& timer)
+{
+ bool canceled = false;
+ synchronized (timeouts) {
+ // Check if the timeout is still pending, and if so, erase it. In
+ // addition, erase an empty list if we just removed the last
+ // timeout.
+ // TODO(benh): If two timers are created with the same timeout,
+ // this will erase *both*. Fix this!
+ Time time = timer.timeout().time();
+ if (timeouts->count(time) > 0) {
+ canceled = true;
+ (*timeouts)[time].remove(timer);
+ if ((*timeouts)[time].empty()) {
+ timeouts->erase(time);
+ }
+ }
+ }
+
+ return canceled;
+}
+
+
+ProcessBase::ProcessBase(const string& id)
+{
+ process::initialize();
+
+ state = ProcessBase::BOTTOM;
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&m, &attr);
+ pthread_mutexattr_destroy(&attr);
+
+ refs = 0;
+
+ pid.id = id != "" ? id : ID::generate();
+ pid.ip = __ip__;
+ pid.port = __port__;
+
+ // If using a manual clock, try and set current time of process
+ // using happens before relationship between creator and createe!
+ if (Clock::paused()) {
+ synchronized (timeouts) {
+ if (Clock::paused()) {
+ clock::currents->erase(this); // In case the address is reused!
+ if (__process__ != NULL) {
+ Clock::order(__process__, this);
+ } else {
+ Clock::update(this, Clock::now());
+ }
+ }
+ }
+ }
+}
+
+
+ProcessBase::~ProcessBase() {}
+
+
+void ProcessBase::enqueue(Event* event, bool inject)
+{
+ CHECK(event != NULL);
+
+ lock();
+ {
+ if (state != TERMINATING && state != TERMINATED) {
+ if (!inject) {
+ events.push_back(event);
+ } else {
+ events.push_front(event);
+ }
+
+ if (state == BLOCKED) {
+ state = READY;
+ process_manager->enqueue(this);
+ }
+
+ CHECK(state == BOTTOM ||
+ state == READY ||
+ state == RUNNING);
+ } else {
+ delete event;
+ }
+ }
+ unlock();
+}
+
+
+void ProcessBase::inject(const UPID& from, const string& name, const char* data, size_t length)
+{
+ if (!from)
+ return;
+
+ Message* message = encode(from, pid, name, string(data, length));
+
+ enqueue(new MessageEvent(message), true);
+}
+
+
+void ProcessBase::send(const UPID& to, const string& name, const char* data, size_t length)
+{
+ if (!to) {
+ return;
+ }
+
+ // Encode and transport outgoing message.
+ transport(encode(pid, to, name, string(data, length)), this);
+}
+
+
+void ProcessBase::visit(const MessageEvent& event)
+{
+ if (handlers.message.count(event.message->name) > 0) {
+ handlers.message[event.message->name](
+ event.message->from,
+ event.message->body);
+ } else if (delegates.count(event.message->name) > 0) {
+ VLOG(1) << "Delegating message '" << event.message->name
+ << "' to " << delegates[event.message->name];
+ Message* message = new Message(*event.message);
+ message->to = delegates[event.message->name];
+ transport(message, this);
+ }
+}
+
+
+void ProcessBase::visit(const DispatchEvent& event)
+{
+ (*event.f)(this);
+}
+
+
+void ProcessBase::visit(const HttpEvent& event)
+{
+ VLOG(1) << "Handling HTTP event for process '" << pid.id << "'"
+ << " with path: '" << event.request->path << "'";
+
+ CHECK(event.request->path.find('/') == 0); // See ProcessManager::handle.
+
+ // Split the path by '/'.
+ vector<string> tokens = strings::tokenize(event.request->path, "/");
+ CHECK(tokens.size() >= 1);
+ CHECK(tokens[0] == pid.id);
+
+ const string& name = tokens.size() > 1 ? tokens[1] : "";
+
+ if (handlers.http.count(name) > 0) {
+ // Create the promise to link with whatever gets returned, as well
+ // as a future to wait for the response.
+ std::tr1::shared_ptr<Promise<Response> > promise(
+ new Promise<Response>());
+
+ Future<Response>* future = new Future<Response>(promise->future());
+
+ // Get the HttpProxy pid for this socket.
+ PID<HttpProxy> proxy = socket_manager->proxy(event.socket);
+
+ // Let the HttpProxy know about this request (via the future).
+ dispatch(proxy, &HttpProxy::handle, future, *event.request);
+
+ // Now call the handler and associate the response with the promise.
+ promise->associate(handlers.http[name](*event.request));
+ } else if (assets.count(name) > 0) {
+ OK response;
+ response.type = Response::PATH;
+ response.path = assets[name].path;
+
+ // Construct the final path by appending remaining tokens.
+ for (int i = 2; i < tokens.size(); i++) {
+ response.path += "/" + tokens[i];
+ }
+
+ // Try and determine the Content-Type from an extension.
+ Try<string> basename = os::basename(response.path);
+ if (!basename.isError()) {
+ size_t index = basename.get().find_last_of('.');
+ if (index != string::npos) {
+ string extension = basename.get().substr(index);
+ if (assets[name].types.count(extension) > 0) {
+ response.headers["Content-Type"] = assets[name].types[extension];
+ }
+ }
+ }
+
+ // TODO(benh): Use "text/plain" for assets that don't have an
+ // extension or we don't have a mapping for? It might be better to
+ // just let the browser guess (or do it's own default).
+
+ // Get the HttpProxy pid for this socket.
+ PID<HttpProxy> proxy = socket_manager->proxy(event.socket);
+
+ // Enqueue the response with the HttpProxy so that it respects the
+ // order of requests to account for HTTP/1.1 pipelining.
+ dispatch(proxy, &HttpProxy::enqueue, response, *event.request);
+ } else {
+ VLOG(1) << "Returning '404 Not Found' for '" << event.request->path << "'";
+
+ // Get the HttpProxy pid for this socket.
+ PID<HttpProxy> proxy = socket_manager->proxy(event.socket);
+
+ // Enqueue the response with the HttpProxy so that it respects the
+ // order of requests to account for HTTP/1.1 pipelining.
+ dispatch(proxy, &HttpProxy::enqueue, NotFound(), *event.request);
+ }
+}
+
+
+void ProcessBase::visit(const ExitedEvent& event)
+{
+ exited(event.pid);
+}
+
+
+void ProcessBase::visit(const TerminateEvent& event)
+{
+ finalize();
+}
+
+
+UPID ProcessBase::link(const UPID& to)
+{
+ if (!to) {
+ return to;
+ }
+
+ process_manager->link(this, to);
+
+ return to;
+}
+
+
+UPID spawn(ProcessBase* process, bool manage)
+{
+ process::initialize();
+
+ if (process != NULL) {
+ // If using a manual clock, try and set current time of process
+ // using happens before relationship between spawner and spawnee!
+ if (Clock::paused()) {
+ synchronized (timeouts) {
+ if (Clock::paused()) {
+ if (__process__ != NULL) {
+ Clock::order(__process__, process);
+ } else {
+ Clock::update(process, Clock::now());
+ }
+ }
+ }
+ }
+
+ return process_manager->spawn(process, manage);
+ } else {
+ return UPID();
+ }
+}
+
+
+void terminate(const UPID& pid, bool inject)
+{
+ process_manager->terminate(pid, inject, __process__);
+}
+
+
+class WaitWaiter : public Process<WaitWaiter>
+{
+public:
+ WaitWaiter(const UPID& _pid, const Duration& _duration, bool* _waited)
+ : ProcessBase(ID::generate("__waiter__")),
+ pid(_pid),
+ duration(_duration),
+ waited(_waited) {}
+
+ virtual void initialize()
+ {
+ VLOG(3) << "Running waiter process for " << pid;
+ link(pid);
+ delay(duration, self(), &WaitWaiter::timeout);
+ }
+
+private:
+ virtual void exited(const UPID&)
+ {
+ VLOG(3) << "Waiter process waited for " << pid;
+ *waited = true;
+ terminate(self());
+ }
+
+ void timeout()
+ {
+ VLOG(3) << "Waiter process timed out waiting for " << pid;
+ *waited = false;
+ terminate(self());
+ }
+
+private:
+ const UPID pid;
+ const Duration duration;
+ bool* const waited;
+};
+
+
+bool wait(const UPID& pid, const Duration& duration)
+{
+ process::initialize();
+
+ if (!pid) {
+ return false;
+ }
+
+ // This could result in a deadlock if some code decides to wait on a
+ // process that has invoked that code!
+ if (__process__ != NULL && __process__->self() == pid) {
+ std::cerr << "\n**** DEADLOCK DETECTED! ****\nYou are waiting on process "
+ << pid << " that it is currently executing." << std::endl;
+ }
+
+ if (duration == Seconds(-1)) {
+ return process_manager->wait(pid);
+ }
+
+ bool waited = false;
+
+ WaitWaiter waiter(pid, duration, &waited);
+ spawn(waiter);
+ wait(waiter);
+
+ return waited;
+}
+
+
+void filter(Filter *filter)
+{
+ process::initialize();
+
+ synchronized (filterer) {
+ filterer = filter;
+ }
<TRUNCATED>
[16/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/timer.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/timer.hpp b/third_party/libprocess/include/process/timer.hpp
deleted file mode 100644
index 333a806..0000000
--- a/third_party/libprocess/include/process/timer.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef __PROCESS_TIMER_HPP__
-#define __PROCESS_TIMER_HPP__
-
-#include <stdlib.h> // For abort.
-
-#include <tr1/functional>
-
-#include <process/timeout.hpp>
-
-#include <stout/duration.hpp>
-
-namespace process {
-
-// Timer support!
-
-class Timer
-{
-public:
- Timer() : id(0), pid(process::UPID()), thunk(&abort) {}
-
- static Timer create(
- const Duration& duration,
- const std::tr1::function<void(void)>& thunk);
-
- static bool cancel(const Timer& timer);
-
- bool operator == (const Timer& that) const
- {
- return id == that.id;
- }
-
- // Invokes this timer's thunk.
- void operator () () const
- {
- thunk();
- }
-
- // Returns the timeout associated with this timer.
- Timeout timeout() const
- {
- return t;
- }
-
- // Returns the PID of the running process when this timer was
- // created (via timers::create) or an empty PID if no process was
- // running when this timer was created.
- process::UPID creator() const
- {
- return pid;
- }
-
-private:
- Timer(long _id,
- const Timeout& _t,
- const process::UPID& _pid,
- const std::tr1::function<void(void)>& _thunk)
- : id(_id), t(_t), pid(_pid), thunk(_thunk)
- {}
-
- uint64_t id; // Used for equality.
-
- Timeout t;
-
- // We store the PID of the "issuing" (i.e., "running") process (if
- // there is one). We don't store a pointer to the process because we
- // can't dereference it since it might no longer be valid. (Instead,
- // the PID can be used internally to check if the process is still
- // valid and get a refernce to it.)
- process::UPID pid;
-
- std::tr1::function<void(void)> thunk;
-};
-
-} // namespace process {
-
-#endif // __PROCESS_TIMER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/tuples/details.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/tuples/details.hpp b/third_party/libprocess/include/process/tuples/details.hpp
deleted file mode 100644
index 34a9fb5..0000000
--- a/third_party/libprocess/include/process/tuples/details.hpp
+++ /dev/null
@@ -1,170 +0,0 @@
-template <MSGID ID> class tuple;
-
-#undef IDENTITY
-#define IDENTITY(...) __VA_ARGS__
-
-#undef TUPLE
-#define TUPLE(ID, types) \
- template <> class tuple<ID> : public boost::tuple<IDENTITY types> \
- { \
- public: \
- tuple(const boost::tuple<IDENTITY types> &t) \
- : boost::tuple<IDENTITY types>(t) {} \
- \
- tuple(const std::string &data) \
- { \
- std::istringstream is(data); \
- process::tuples::deserializer d(is); \
- deserialize(d, *this); \
- } \
- \
- operator std::string () const \
- { \
- std::ostringstream os; \
- process::tuples::serializer s(os); \
- serialize(s, *this); \
- return os.str(); \
- } \
- }
-
-
-inline void serialize(process::tuples::serializer &s,
- const boost::tuples::null_type &)
-{
-}
-
-
-template <typename H, typename T>
-inline void serialize(process::tuples::serializer &s,
- const boost::tuples::cons<H, T> &c)
-{
- s & c.get_head();
- serialize(s, c.get_tail());
-}
-
-
-inline void deserialize(process::tuples::deserializer &d,
- const boost::tuples::null_type &)
-{
-}
-
-
-template <typename H, typename T>
-inline void deserialize(process::tuples::deserializer &d,
- boost::tuples::cons<H, T> &c)
-{
- d & c.get_head();
- deserialize(d, c.get_tail());
-}
-
-
-template <MSGID ID>
-tuple<ID> pack()
-{
- return tuple<ID>(::boost::make_tuple());
-}
-
-
-template <MSGID ID, typename T0>
-tuple<ID> pack(const T0 &t0)
-{
- return tuple<ID>(::boost::make_tuple(t0));
-}
-
-
-template <MSGID ID, typename T0, typename T1>
-tuple<ID> pack(const T0 &t0, const T1 &t1)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1));
-}
-
-
-template <MSGID ID, typename T0, typename T1, typename T2>
-tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1, t2));
-}
-
-
-template <MSGID ID,
- typename T0, typename T1, typename T2, typename T3>
-tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3));
-}
-
-
-template <MSGID ID,
- typename T0, typename T1, typename T2, typename T3, typename T4>
-tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
- const T4 &t4)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4));
-}
-
-
-template <MSGID ID,
- typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5>
-tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
- const T4 &t4, const T5 &t5)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5));
-}
-
-
-template <MSGID ID,
- typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6>
-tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
- const T4 &t4, const T5 &t5, const T6 &t6)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5, t6));
-}
-
-
-template <MSGID ID,
- typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7>
-tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
- const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5, t6, t7));
-}
-
-
-template <MSGID ID,
- typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8>
-tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
- const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7,
- const T8 &t8)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5, t6, t7, t8));
-}
-
-
-template <MSGID ID,
- typename T0, typename T1, typename T2, typename T3, typename T4,
- typename T5, typename T6, typename T7, typename T8, typename T9>
-tuple<ID> pack(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3,
- const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7,
- const T8 &t8, const T9 &t9)
-{
- return tuple<ID>(::boost::make_tuple(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9));
-}
-
-
-template <MSGID ID>
-tuple<ID> unpack(const std::string &data)
-{
- return tuple<ID>(data);
-}
-
-
-template <MSGID ID, int N>
-typename boost::tuples::element<N, tuple<ID> >::type unpack(
- const std::string &data)
-{
- return boost::tuples::get<N>(unpack<ID>(data));
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/tuples/tuples.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/tuples/tuples.hpp b/third_party/libprocess/include/process/tuples/tuples.hpp
deleted file mode 100644
index 16445fa..0000000
--- a/third_party/libprocess/include/process/tuples/tuples.hpp
+++ /dev/null
@@ -1,154 +0,0 @@
-#ifndef __PROCESS_TUPLES_HPP__
-#define __PROCESS_TUPLES_HPP__
-
-#include <stdlib.h>
-
-#include <arpa/inet.h>
-
-#include <sstream>
-#include <string>
-#include <utility>
-
-#include <boost/tuple/tuple.hpp>
-
-
-namespace process { namespace tuples {
-
-// TODO(benh): Check stream errors! Report errors! Ahhhh!
-
-struct serializer
-{
- std::ostringstream& stream;
-
- serializer(std::ostringstream& s) : stream(s) {}
-
- void operator & (const int32_t & i)
- {
- uint32_t netInt = htonl((uint32_t) i);
- stream.write((char *) &netInt, sizeof(netInt));
- }
-
- void operator & (const int64_t & i)
- {
- uint32_t hiInt = htonl((uint32_t) (i >> 32));
- uint32_t loInt = htonl((uint32_t) (i & 0xFFFFFFFF));
- stream.write((char *) &hiInt, sizeof(hiInt));
- stream.write((char *) &loInt, sizeof(loInt));
- }
-
-#ifdef __APPLE__
- void operator & (const intptr_t &i)
- {
- if (sizeof(intptr_t) == sizeof(int32_t))
- *this & ((int32_t &) i);
- else if (sizeof(intptr_t) == sizeof(int64_t))
- *this & ((int64_t &) i);
- else
- abort();
- }
-#endif
-
- void operator & (const size_t &i)
- {
- if (sizeof(size_t) == sizeof(int32_t))
- *this & ((int32_t &) i);
- else if (sizeof(size_t) == sizeof(int64_t))
- *this & ((int64_t &) i);
- else
- abort();
- }
-
- void operator & (const double &d)
- {
- // TODO(*): Deal with endian issues?
- stream.write((char *) &d, sizeof(d));
- }
-
- void operator & (const std::string &s)
- {
- size_t size = s.size();
- *this & (size);
- stream.write(s.data(), size);
- }
-
- void operator & (const PID &pid)
- {
- *this & ((int32_t) pid.pipe);
- *this & ((int32_t) pid.ip);
- *this & ((int32_t) pid.port);
- }
-};
-
-
-struct deserializer
-{
- std::istringstream &stream;
-
- deserializer(std::istringstream &s) : stream(s) {}
-
- void operator & (int32_t &i)
- {
- uint32_t netInt;
- stream.read((char *) &netInt, sizeof(netInt));
- i = ntohl(netInt);
- }
-
- void operator & (int64_t &i)
- {
- uint32_t hiInt, loInt;
- stream.read((char *) &hiInt, sizeof(hiInt));
- stream.read((char *) &loInt, sizeof(loInt));
- int64_t hi64 = ntohl(hiInt);
- int64_t lo64 = ntohl(loInt);
- i = (hi64 << 32) | lo64;
- }
-
-#ifdef __APPLE__
- void operator & (intptr_t &i)
- {
- if (sizeof(intptr_t) == sizeof(int32_t))
- *this & ((int32_t &) i);
- else if (sizeof(intptr_t) == sizeof(int64_t))
- *this & ((int64_t &) i);
- else
- abort();
- }
-#endif
-
- void operator & (size_t &i)
- {
- if (sizeof(size_t) == sizeof(int32_t))
- *this & ((int32_t &) i);
- else if (sizeof(size_t) == sizeof(int64_t))
- *this & ((int64_t &) i);
- else
- abort();
- }
-
- void operator & (double &d)
- {
- // TODO(*): Deal with endian issues?
- stream.read((char *) &d, sizeof(d));
- }
-
- void operator & (std::string &s)
- {
- size_t size;
- *this & (size);
- s.resize(size);
- stream.read((char *) s.data(), size);
- }
-
- void operator & (PID &pid)
- {
- *this & ((int32_t &) pid.pipe);
- *this & ((int32_t &) pid.ip);
- *this & ((int32_t &) pid.port);
- }
-};
-
-
-}} // namespace process { namespace tuples {
-
-
-#endif // __PROCESS_TUPLES_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/install-sh
----------------------------------------------------------------------
diff --git a/third_party/libprocess/install-sh b/third_party/libprocess/install-sh
deleted file mode 100755
index 6781b98..0000000
--- a/third_party/libprocess/install-sh
+++ /dev/null
@@ -1,520 +0,0 @@
-#!/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/third_party/libprocess/m4/acx_pthread.m4
----------------------------------------------------------------------
diff --git a/third_party/libprocess/m4/acx_pthread.m4 b/third_party/libprocess/m4/acx_pthread.m4
deleted file mode 100644
index 2cf20de..0000000
--- a/third_party/libprocess/m4/acx_pthread.m4
+++ /dev/null
@@ -1,363 +0,0 @@
-# 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/third_party/libprocess/src/config.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/config.hpp b/third_party/libprocess/src/config.hpp
deleted file mode 100644
index 1daa476..0000000
--- a/third_party/libprocess/src/config.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef CONFIG_HPP
-#define CONFIG_HPP
-
-#ifdef __sun__
-#define gethostbyname2(name, _) gethostbyname(name)
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
-#endif
-#ifndef SOL_TCP
-#define SOL_TCP IPPROTO_TCP
-#endif
-#ifndef MAP_32BIT
-#define MAP_32BIT 0
-#endif
-#endif /* __sun__ */
-
-#ifdef __APPLE__
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
-#endif
-#ifndef SOL_TCP
-#define SOL_TCP IPPROTO_TCP
-#endif
-#ifndef MAP_32BIT
-#define MAP_32BIT 0
-#endif
-#define sendfile(s, fd, offset, size) \
- ({ off_t length = size; \
- sendfile(fd, s, offset, &length, NULL, 0) == 0 \
- ? length \
- : (errno == EAGAIN ? (length > 0 ? length : -1) : -1); })
-#endif /* __APPLE__ */
-
-#ifdef __linux__
-#ifndef MAP_32BIT
-#define MAP_32BIT 0
-#endif
-#include <sys/sendfile.h>
-#define sendfile(s, fd, offset, size) \
- ({ off_t _offset = offset; \
- sendfile(s, fd, &_offset, size) == -1 ? -1 : _offset - offset; })
-#endif /* __linux__ */
-
-#endif /* CONFIG_HPP */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/decoder.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/decoder.hpp b/third_party/libprocess/src/decoder.hpp
deleted file mode 100644
index 4c29229..0000000
--- a/third_party/libprocess/src/decoder.hpp
+++ /dev/null
@@ -1,412 +0,0 @@
-#ifndef __DECODER_HPP__
-#define __DECODER_HPP__
-
-#include <http_parser.h>
-
-#include <deque>
-#include <string>
-#include <vector>
-
-#include <process/http.hpp>
-#include <process/socket.hpp>
-
-#include <stout/foreach.hpp>
-#include <stout/gzip.hpp>
-#include <stout/try.hpp>
-
-
-// TODO(bmahler): Upgrade our http_parser to the latest version.
-namespace process {
-
-// TODO: Make DataDecoder abstract and make RequestDecoder a concrete subclass.
-class DataDecoder
-{
-public:
- DataDecoder(const Socket& _s)
- : s(_s), failure(false), request(NULL)
- {
- settings.on_message_begin = &DataDecoder::on_message_begin;
- settings.on_header_field = &DataDecoder::on_header_field;
- settings.on_header_value = &DataDecoder::on_header_value;
- settings.on_path = &DataDecoder::on_path;
- settings.on_url = &DataDecoder::on_url;
- settings.on_fragment = &DataDecoder::on_fragment;
- settings.on_query_string = &DataDecoder::on_query_string;
- settings.on_body = &DataDecoder::on_body;
- settings.on_headers_complete = &DataDecoder::on_headers_complete;
- settings.on_message_complete = &DataDecoder::on_message_complete;
-
- http_parser_init(&parser, HTTP_REQUEST);
-
- parser.data = this;
- }
-
- std::deque<http::Request*> decode(const char* data, size_t length)
- {
- size_t parsed = http_parser_execute(&parser, &settings, data, length);
-
- if (parsed != length) {
- failure = true;
- }
-
- if (!requests.empty()) {
- std::deque<http::Request*> result = requests;
- requests.clear();
- return result;
- }
-
- return std::deque<http::Request*>();
- }
-
- bool failed() const
- {
- return failure;
- }
-
- Socket socket() const
- {
- return s;
- }
-
-private:
- static int on_message_begin(http_parser* p)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
-
- assert(!decoder->failure);
-
- decoder->header = HEADER_FIELD;
- decoder->field.clear();
- decoder->value.clear();
- decoder->query.clear();
-
- assert(decoder->request == NULL);
- decoder->request = new http::Request();
- decoder->request->headers.clear();
- decoder->request->method.clear();
- decoder->request->path.clear();
- decoder->request->url.clear();
- decoder->request->fragment.clear();
- decoder->request->query.clear();
- decoder->request->body.clear();
-
- return 0;
- }
-
- static int on_headers_complete(http_parser* p)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
-
- // Add final header.
- decoder->request->headers[decoder->field] = decoder->value;
- decoder->field.clear();
- decoder->value.clear();
-
- decoder->request->method = http_method_str((http_method) decoder->parser.method);
- decoder->request->keepAlive = http_should_keep_alive(&decoder->parser);
- return 0;
- }
-
- static int on_message_complete(http_parser* p)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
-// std::cout << "http::Request:" << std::endl;
-// std::cout << " method: " << decoder->request->method << std::endl;
-// std::cout << " path: " << decoder->request->path << std::endl;
- // Parse the query key/values.
- Try<std::string> decoded = http::decode(decoder->query);
- if (decoded.isError()) {
- return 1;
- }
- decoder->request->query = http::query::parse(decoded.get());
-
- Option<std::string> encoding =
- decoder->request->headers.get("Content-Encoding");
- if (encoding.isSome() && encoding.get() == "gzip") {
- Try<std::string> decompressed = gzip::decompress(decoder->request->body);
- if (decompressed.isError()) {
- return 1;
- }
- decoder->request->body = decompressed.get();
- decoder->request->headers["Content-Length"] =
- decoder->request->body.length();
- }
-
- decoder->requests.push_back(decoder->request);
- decoder->request = NULL;
- return 0;
- }
-
- static int on_header_field(http_parser* p, const char* data, size_t length)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
-
- if (decoder->header != HEADER_FIELD) {
- decoder->request->headers[decoder->field] = decoder->value;
- decoder->field.clear();
- decoder->value.clear();
- }
-
- decoder->field.append(data, length);
- decoder->header = HEADER_FIELD;
-
- return 0;
- }
-
- static int on_header_value(http_parser* p, const char* data, size_t length)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
- decoder->value.append(data, length);
- decoder->header = HEADER_VALUE;
- return 0;
- }
-
- static int on_path(http_parser* p, const char* data, size_t length)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
- decoder->request->path.append(data, length);
- return 0;
- }
-
- static int on_url(http_parser* p, const char* data, size_t length)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
- decoder->request->url.append(data, length);
- return 0;
- }
-
- static int on_query_string(http_parser* p, const char* data, size_t length)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
- decoder->query.append(data, length);
- return 0;
- }
-
- static int on_fragment(http_parser* p, const char* data, size_t length)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
- decoder->request->fragment.append(data, length);
- return 0;
- }
-
- static int on_body(http_parser* p, const char* data, size_t length)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
- decoder->request->body.append(data, length);
- return 0;
- }
-
- const Socket s; // The socket this decoder is associated with.
-
- bool failure;
-
- http_parser parser;
- http_parser_settings settings;
-
- enum {
- HEADER_FIELD,
- HEADER_VALUE
- } header;
-
- std::string field;
- std::string value;
- std::string query;
-
- http::Request* request;
-
- std::deque<http::Request*> requests;
-};
-
-
-class ResponseDecoder
-{
-public:
- ResponseDecoder()
- : failure(false), header(HEADER_FIELD), response(NULL)
- {
- settings.on_message_begin = &ResponseDecoder::on_message_begin;
- settings.on_header_field = &ResponseDecoder::on_header_field;
- settings.on_header_value = &ResponseDecoder::on_header_value;
- settings.on_path = &ResponseDecoder::on_path;
- settings.on_url = &ResponseDecoder::on_url;
- settings.on_fragment = &ResponseDecoder::on_fragment;
- settings.on_query_string = &ResponseDecoder::on_query_string;
- settings.on_body = &ResponseDecoder::on_body;
- settings.on_headers_complete = &ResponseDecoder::on_headers_complete;
- settings.on_message_complete = &ResponseDecoder::on_message_complete;
-
- http_parser_init(&parser, HTTP_RESPONSE);
-
- parser.data = this;
- }
-
- std::deque<http::Response*> decode(const char* data, size_t length)
- {
- size_t parsed = http_parser_execute(&parser, &settings, data, length);
-
- if (parsed != length) {
- failure = true;
- }
-
- if (!responses.empty()) {
- std::deque<http::Response*> result = responses;
- responses.clear();
- return result;
- }
-
- return std::deque<http::Response*>();
- }
-
- bool failed() const
- {
- return failure;
- }
-
-private:
- static int on_message_begin(http_parser* p)
- {
- ResponseDecoder* decoder = (ResponseDecoder*) p->data;
-
- assert(!decoder->failure);
-
- decoder->header = HEADER_FIELD;
- decoder->field.clear();
- decoder->value.clear();
-
- assert(decoder->response == NULL);
- decoder->response = new http::Response();
- decoder->response->status.clear();
- decoder->response->headers.clear();
- decoder->response->type = http::Response::BODY;
- decoder->response->body.clear();
- decoder->response->path.clear();
-
- return 0;
- }
-
- static int on_headers_complete(http_parser* p)
- {
- ResponseDecoder* decoder = (ResponseDecoder*) p->data;
-
- // Add final header.
- decoder->response->headers[decoder->field] = decoder->value;
- decoder->field.clear();
- decoder->value.clear();
-
- return 0;
- }
-
- static int on_message_complete(http_parser* p)
- {
- ResponseDecoder* decoder = (ResponseDecoder*) p->data;
-
- // Get the response status string.
- if (http::statuses.contains(decoder->parser.status_code)) {
- decoder->response->status = http::statuses[decoder->parser.status_code];
- } else {
- decoder->failure = true;
- return 1;
- }
-
- // We can only provide the gzip encoding.
- Option<std::string> encoding =
- decoder->response->headers.get("Content-Encoding");
- if (encoding.isSome() && encoding.get() == "gzip") {
- Try<std::string> decompressed = gzip::decompress(decoder->response->body);
- if (decompressed.isError()) {
- decoder->failure = true;
- return 1;
- }
- decoder->response->body = decompressed.get();
- decoder->response->headers["Content-Length"] =
- decoder->response->body.length();
- }
-
- decoder->responses.push_back(decoder->response);
- decoder->response = NULL;
- return 0;
- }
-
- static int on_header_field(http_parser* p, const char* data, size_t length)
- {
- ResponseDecoder* decoder = (ResponseDecoder*) p->data;
- assert(decoder->response != NULL);
-
- if (decoder->header != HEADER_FIELD) {
- decoder->response->headers[decoder->field] = decoder->value;
- decoder->field.clear();
- decoder->value.clear();
- }
-
- decoder->field.append(data, length);
- decoder->header = HEADER_FIELD;
-
- return 0;
- }
-
- static int on_header_value(http_parser* p, const char* data, size_t length)
- {
- ResponseDecoder* decoder = (ResponseDecoder*) p->data;
- assert(decoder->response != NULL);
- decoder->value.append(data, length);
- decoder->header = HEADER_VALUE;
- return 0;
- }
-
- static int on_path(http_parser* p, const char* data, size_t length)
- {
- return 0;
- }
-
- static int on_url(http_parser* p, const char* data, size_t length)
- {
- return 0;
- }
-
- static int on_query_string(http_parser* p, const char* data, size_t length)
- {
- return 0;
- }
-
- static int on_fragment(http_parser* p, const char* data, size_t length)
- {
- return 0;
- }
-
- static int on_body(http_parser* p, const char* data, size_t length)
- {
- ResponseDecoder* decoder = (ResponseDecoder*) p->data;
- assert(decoder->response != NULL);
- decoder->response->body.append(data, length);
- return 0;
- }
-
- bool failure;
-
- http_parser parser;
- http_parser_settings settings;
-
- enum {
- HEADER_FIELD,
- HEADER_VALUE
- } header;
-
- std::string field;
- std::string value;
-
- http::Response* response;
-
- std::deque<http::Response*> responses;
-};
-
-
-} // namespace process {
-
-#endif // __DECODER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/encoder.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/encoder.hpp b/third_party/libprocess/src/encoder.hpp
deleted file mode 100644
index 55aba22..0000000
--- a/third_party/libprocess/src/encoder.hpp
+++ /dev/null
@@ -1,262 +0,0 @@
-#ifndef __ENCODER_HPP__
-#define __ENCODER_HPP__
-
-#include <map>
-#include <sstream>
-
-#include <process/http.hpp>
-#include <process/process.hpp>
-
-#include <stout/foreach.hpp>
-#include <stout/gzip.hpp>
-#include <stout/hashmap.hpp>
-#include <stout/numify.hpp>
-#include <stout/os.hpp>
-
-// NOTE: We forward declare "ev_loop" and "ev_io" here because,
-// on OSX, including "ev.h" causes conflict with "EV_ERROR" declared
-// in "/usr/include/sys/event.h".
-struct ev_loop;
-struct ev_io;
-
-namespace process {
-
-const uint32_t GZIP_MINIMUM_BODY_LENGTH = 1024;
-
-typedef void (*Sender)(struct ev_loop*, ev_io*, int);
-
-extern void send_data(struct ev_loop*, ev_io*, int);
-extern void send_file(struct ev_loop*, ev_io*, int);
-
-
-class Encoder
-{
-public:
- Encoder(const Socket& _s) : s(_s) {}
- virtual ~Encoder() {}
-
- virtual Sender sender() = 0;
-
- Socket socket() const
- {
- return s;
- }
-
-private:
- const Socket s; // The socket this encoder is associated with.
-};
-
-
-class DataEncoder : public Encoder
-{
-public:
- DataEncoder(const Socket& s, const std::string& _data)
- : Encoder(s), data(_data), index(0) {}
-
- virtual ~DataEncoder() {}
-
- virtual Sender sender()
- {
- return send_data;
- }
-
- virtual const char* next(size_t* length)
- {
- size_t temp = index;
- index = data.size();
- *length = data.size() - temp;
- return data.data() + temp;
- }
-
- virtual void backup(size_t length)
- {
- if (index >= length) {
- index -= length;
- }
- }
-
- virtual size_t remaining() const
- {
- return data.size() - index;
- }
-
-private:
- const std::string data;
- size_t index;
-};
-
-
-class MessageEncoder : public DataEncoder
-{
-public:
- MessageEncoder(const Socket& s, Message* _message)
- : DataEncoder(s, encode(_message)), message(_message) {}
-
- virtual ~MessageEncoder()
- {
- if (message != NULL) {
- delete message;
- }
- }
-
- static std::string encode(Message* message)
- {
- if (message != NULL) {
- std::ostringstream out;
-
- out << "POST /" << message->to.id << "/" << message->name
- << " HTTP/1.0\r\n"
- << "User-Agent: libprocess/" << message->from << "\r\n"
- << "Connection: Keep-Alive\r\n";
-
- if (message->body.size() > 0) {
- out << "Transfer-Encoding: chunked\r\n\r\n"
- << std::hex << message->body.size() << "\r\n";
- out.write(message->body.data(), message->body.size());
- out << "\r\n"
- << "0\r\n"
- << "\r\n";
- } else {
- out << "\r\n";
- }
-
- return out.str();
- }
- }
-
-private:
- Message* message;
-};
-
-
-class HttpResponseEncoder : public DataEncoder
-{
-public:
- HttpResponseEncoder(
- const Socket& s,
- const http::Response& response,
- const http::Request& request)
- : DataEncoder(s, encode(response, request)) {}
-
- static std::string encode(
- const http::Response& response,
- const http::Request& request)
- {
- std::ostringstream out;
-
- // TODO(benh): Check version?
-
- out << "HTTP/1.1 " << response.status << "\r\n";
-
- hashmap<std::string, std::string> headers = response.headers;
-
- // HTTP 1.1 requires the "Date" header. In the future once we
- // start checking the version (above) then we can conditionally
- // add this header, but for now, we always do.
- time_t rawtime;
- time(&rawtime);
-
- char date[256];
-
- // TODO(benh): Check return code of strftime!
- strftime(date, 256, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&rawtime));
-
- headers["Date"] = date;
-
- // Should we compress this response?
- std::string body = response.body;
-
- if (response.type == http::Response::BODY &&
- response.body.length() >= GZIP_MINIMUM_BODY_LENGTH &&
- !headers.contains("Content-Encoding") &&
- request.accepts("gzip")) {
- Try<std::string> compressed = gzip::compress(body);
- if (compressed.isError()) {
- LOG(WARNING) << "Failed to gzip response body: " << compressed.error();
- } else {
- body = compressed.get();
- headers["Content-Length"] = stringify(body.length());
- headers["Content-Encoding"] = "gzip";
- }
- }
-
- foreachpair (const std::string& key, const std::string& value, headers) {
- out << key << ": " << value << "\r\n";
- }
-
- // Add a Content-Length header if the response is of type "none"
- // or "body" and no Content-Length header has been supplied.
- if (response.type == http::Response::NONE &&
- !headers.contains("Content-Length")) {
- out << "Content-Length: 0\r\n";
- } else if (response.type == http::Response::BODY &&
- !headers.contains("Content-Length")) {
- out << "Content-Length: " << body.size() << "\r\n";
- }
-
- // Use a CRLF to mark end of headers.
- out << "\r\n";
-
- // Add the body if necessary.
- if (response.type == http::Response::BODY) {
- // If the Content-Length header was supplied, only write as much data
- // as the length specifies.
- Result<uint32_t> length = numify<uint32_t>(headers.get("Content-Length"));
- if (length.isSome() && length.get() <= body.length()) {
- out.write(body.data(), length.get());
- } else {
- out.write(body.data(), body.size());
- }
- }
-
- return out.str();
- }
-};
-
-
-class FileEncoder : public Encoder
-{
-public:
- FileEncoder(const Socket& s, int _fd, size_t _size)
- : Encoder(s), fd(_fd), size(_size), index(0) {}
-
- virtual ~FileEncoder()
- {
- os::close(fd);
- }
-
- virtual Sender sender()
- {
- return send_file;
- }
-
- virtual int next(off_t* offset, size_t* length)
- {
- off_t temp = index;
- index = size;
- *offset = temp;
- *length = size - temp;
- return fd;
- }
-
- virtual void backup(size_t length)
- {
- if (index >= length) {
- index -= length;
- }
- }
-
- virtual size_t remaining() const
- {
- return size - index;
- }
-
-private:
- int fd;
- size_t size;
- off_t index;
-};
-
-} // namespace process {
-
-#endif // __ENCODER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/fatal.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/fatal.cpp b/third_party/libprocess/src/fatal.cpp
deleted file mode 100644
index b2934e0..0000000
--- a/third_party/libprocess/src/fatal.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-void __fatal(const char *file, int line, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, " (%s:%u)\n", file, line);
- fflush(stderr);
- va_end(args);
- exit(1);
-}
-
-void __fatalerror(const char *file, int line, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, " (%s:%u): ", file, line);
- perror(NULL);
- fflush(stderr);
- va_end(args);
- exit(1);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/fatal.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/fatal.hpp b/third_party/libprocess/src/fatal.hpp
deleted file mode 100644
index 38646f3..0000000
--- a/third_party/libprocess/src/fatal.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Basic perror + exit routines.
- *
- * Contributed by Benjamin Hindman <be...@berkeley.edu>, 2008.
- */
-
-#ifndef FATAL_HPP
-#define FATAL_HPP
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/*
- * Like the non-debug version except includes the file name and line
- * number in the output.
- */
-#define fatal(fmt...) __fatal(__FILE__, __LINE__, fmt)
-void __fatal(const char *file, int line, const char *fmt, ...);
-
-/*
- * Like the non-debug version except includes the file name and line
- * number in the output.
- */
-#define fatalerror(fmt...) __fatalerror(__FILE__, __LINE__, fmt)
-void __fatalerror(const char *file, int line, const char *fmt, ...);
-
-#endif /* FATAL_HPP */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/gate.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/gate.hpp b/third_party/libprocess/src/gate.hpp
deleted file mode 100644
index 954f620..0000000
--- a/third_party/libprocess/src/gate.hpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef GATE_H
-#define GATE_H
-
-/* TODO(benh): Provide an implementation directly on-top-of futex's for Linux. */
-//#ifdef __linux__
-//#else
-
-class Gate
-{
-public:
- typedef intptr_t state_t;
-
-private:
- int waiters;
- state_t state;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-
-public:
- Gate() : waiters(0), state(0)
- {
- pthread_mutex_init(&mutex, NULL);
- pthread_cond_init(&cond, NULL);
- }
-
- ~Gate()
- {
- pthread_cond_destroy(&cond);
- pthread_mutex_destroy(&mutex);
- }
-
- void open(bool all = true)
- {
- pthread_mutex_lock(&mutex);
- {
- state++;
- if (all) pthread_cond_broadcast(&cond);
- else pthread_cond_signal(&cond);
- }
- pthread_mutex_unlock(&mutex);
- }
-
- void wait()
- {
- pthread_mutex_lock(&mutex);
- {
- waiters++;
- state_t old = state;
- while (old == state)
- pthread_cond_wait(&cond, &mutex);
- waiters--;
- }
- pthread_mutex_unlock(&mutex);
- }
-
- state_t approach()
- {
- state_t old;
- pthread_mutex_lock(&mutex);
- {
- waiters++;
- old = state;
- }
- pthread_mutex_unlock(&mutex);
- return old;
- }
-
- void arrive(state_t old)
- {
- pthread_mutex_lock(&mutex);
- {
- while (old == state) {
- pthread_cond_wait(&cond, &mutex);
- }
- waiters--;
- }
- pthread_mutex_unlock(&mutex);
- }
-
- void leave()
- {
- pthread_mutex_lock(&mutex);
- {
- waiters--;
- }
- pthread_mutex_unlock(&mutex);
- }
-
- bool empty()
- {
- bool occupied = true;
- pthread_mutex_lock(&mutex);
- {
- occupied = waiters > 0 ? true : false;
- }
- pthread_mutex_unlock(&mutex);
- return !occupied;
- }
-};
-
-//#endif
-
-#endif /* GATE_H */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/httpd.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/httpd.cpp b/third_party/libprocess/src/httpd.cpp
deleted file mode 100644
index 793a5b0..0000000
--- a/third_party/libprocess/src/httpd.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-/* TODO(benh): TCP_CORK!!!!! */
-/* TODO(benh): Complete HttpParser & HttpMessage implementation. */
-/* TODO(benh): Turn off Nagle (on TCP_NODELAY) for pipelined requests. */
-
-#include <string.h>
-
-#include <process.hpp>
-#include <tuple.hpp>
-
-#include <iostream>
-#include <map>
-#include <sstream>
-#include <stdexcept>
-
-#include <arpa/inet.h>
-
-#include <stout/os.hpp>
-
-#include "net.hpp"
-
-#include "http-parser/http_parser.h"
-
-using std::cerr;
-using std::cout;
-using std::endl;
-using std::runtime_error;
-using std::string;
-using std::map;
-
-using process::tuple::Tuple;
-
-#define malloc(bytes) \
- ({ void *tmp; if ((tmp = malloc(bytes)) == NULL) abort(); tmp; })
-
-#define realloc(address, bytes) \
- ({ void *tmp; if ((tmp = realloc(address, bytes)) == NULL) abort(); tmp; })
-
-#define HTTP_500 \
- "HTTP/1.1 500 Internal Server Error\r\n\r\n"
-
-#define HTTP_501 \
- "HTTP/1.1 501 Not Implemented\r\n\r\n"
-
-#define HTTP_404 \
- "HTTP/1.1 404 Not Found\r\n\r\n"
-
-
-struct HttpMessage
-{
- unsigned short method;
- /* TODO(*): Use HTTP_MAX_URI_SIZE. */
- string uri;
-};
-
-
-class HttpParser
-{
-protected:
- static int on_uri(http_parser *parser, const char *p, size_t len)
- {
- HttpMessage *message = (HttpMessage *) parser->data;
- message->uri += string(p, len);
- return 0;
- }
-
- static int on_headers_complete(http_parser *parser)
- {
- HttpMessage *message = (HttpMessage *) parser->data;
- message->method = parser->method;
- return 0;
- }
-
-public:
- static HttpMessage * parse(const string &raw)
- {
- http_parser parser;
- http_parser_init(&parser, HTTP_REQUEST);
-
- HttpMessage *message = new HttpMessage;
-
- parser.data = message;
-
- parser.on_message_begin = NULL;
- parser.on_header_field = NULL;
- parser.on_header_value = NULL;
- parser.on_path = NULL;
- parser.on_uri = &HttpParser::on_uri;
- parser.on_fragment = NULL;
- parser.on_query_string = NULL;
- parser.on_body = NULL;
- parser.on_headers_complete = &HttpParser::on_headers_complete;
- parser.on_message_complete = NULL;
-
- http_parser_execute(&parser, raw.c_str(), raw.length());
-
- if (http_parser_has_error(&parser)) {
- //cerr << "parser error" << endl;
- abort();
- }
-
- return message;
- }
-};
-
-
-class HttpConnection : public SocketProcess<TCP>
-{
-protected:
- void operator () ()
- {
- //cout << ht_id() << ": running " << this << " connection (1)" << endl;
-
- string raw;
-
- /* Read headers (until CRLF CRLF). */
- do {
- char buf[512];
- ssize_t len = recv(buf, 512);
- raw += string(buf, len);
- } while (raw.find("\r\n\r\n") == string::npos);
-
- //cout << ht_id() << ": running " << this << " connection (2)" << endl;
-
- /* Parse headers. */
- HttpMessage *message = HttpParser::parse(raw);
-
- /* Handle request. */
- switch (message->method) {
- case HTTP_GET: {
- message->uri =
- message->uri != "/"
- ? "." + message->uri
- : "./index.html";
-
- //cout << "URI: " << message->uri << endl;
-
- /* Open file (if possible). */
- int fd;
-
- if ((fd = open(message->uri.c_str(), O_RDONLY, 0)) < 0) {
- send(HTTP_404, strlen(HTTP_404));
- return;
- }
-
- /* Lookup file size. */
- struct stat fd_stat;
-
- if (fstat(fd, &fd_stat) < 0) {
- send(HTTP_500, strlen(HTTP_500));
- os::close(fd);
- return;
- }
-
- /* TODO(benh): Use TCP_CORK. */
-
- /* Transmit reply header. */
- std::stringstream out;
-
- out << "HTTP/1.1 200 OK\r\n";
-
- /* Determine the content type. */
- if (message->uri.find(".jpg") != string::npos) {
- out << "Content-Type: image/jpeg\r\n";
- } else if (message->uri.find(".gif") != string::npos) {
- out << "Content-Type: image/gif\r\n";
- } else if (message->uri.find(".png") != string::npos) {
- out << "Content-Type: image/png\r\n";
- } else if (message->uri.find(".css") != string::npos) {
- out << "Content-Type: text/css\r\n";
- } else {
- out << "Content-Type: text/html\r\n";
- }
-
- out <<
- "Content-Length: " << fd_stat.st_size << "\r\n"
- "\r\n";
-
- //cout << out.str() << endl;
-
- send(out.str().c_str(), out.str().size());
-
- //cout << ht_id() << ": running " << this << " connection (3)" << endl;
-
- /* Transmit file (TODO(benh): Use file cache.). */
- sendfile(fd, fd_stat.st_size);
-
- //cout << ht_id() << ": running " << this << " connection (4)" << endl;
-
- os::close(fd);
-
- break;
- }
-
- default:
- /* Unimplemented. */
- send(HTTP_501, strlen(HTTP_501));
- break;
- }
- }
-
-public:
- HttpConnection(int s) : SocketProcess<TCP>(s) {}
- ~HttpConnection() {}
-};
-
-
-enum HTTP_MESSAGES { ACCEPT = PROCESS_MSGID };
-
-namespace process { namespace tuple { TUPLE(::ACCEPT, (int)); }}
-
-class HttpAcceptor : public Tuple< Acceptor<TCP> >
-{
-private:
- PID server;
-
-protected:
- void operator () ()
- {
- do {
- struct sockaddr_in addr;
- int c = accept(addr);
- //cout << ht_id() << ": running acceptor" << endl;
- send<ACCEPT>(server, c);
- } while (true);
- }
-
-public:
- HttpAcceptor(const PID &_server, int s) : server(_server) { socket(s); }
-};
-
-
-
-class HttpServer : public Tuple< Server<TCP> >
-{
-private:
- map<PID, HttpConnection *> connections;
-
-protected:
- void operator () ()
- {
- int on = 1;
- setsockopt(SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
- bind();
- listen(100000);
-
- HttpAcceptor *acceptor = new HttpAcceptor(self(), s);
- link(spawn(acceptor));
-
- do {
- switch (receive()) {
- case ACCEPT: {
- //cout << ht_id() << ": running server (accept)" << endl;
- int c;
- unpack<ACCEPT>(c);
- HttpConnection *connection = new HttpConnection(c);
- connections[link(spawn(connection))] = connection;
- //cout << "...started (" << connection << ")..." << endl;
- break;
- }
- case PROCESS_EXIT: {
- //cout << ht_id() << ": running server (exit)" << endl;
- if (from() == acceptor->getPID()) {
- throw runtime_error("unimplemented acceptor failure");
- } else if (connections.find(from()) != connections.end()) {
- HttpConnection *connection = connections[from()];
- connections.erase(from());
- delete connection;
- //cout << "...finished (" << connection << ")..." << endl;
- }
- break;
- }
- default:
- cout << "HttpServer received unexpected message" << endl;
- break;
- }
- } while (true);
- }
-
-public:
- HttpServer(int port) { init(INADDR_ANY, port); }
-};
-
-
-
-int main(int argc, char **argv)
-{
- /* TODO(benh): Blah, 'sendfile' doesn't let us use MSG_NOSIGNAL. :( */
- signal(SIGPIPE, SIG_IGN);
-
- if (argc != 2) {
- cerr << "usage: " << argv[0] << " <port>" << endl;
- return -1;
- }
-
-#ifdef USE_LITHE
- ProcessScheduler *scheduler = new ProcessScheduler();
- Process::spawn(new HttpServer(atoi(argv[1])));
- /* TODO(benh): Make Process::wait take and use the hart if using Lithe! */
- for (;;)
- sleep(10000);
-#else
- Process::wait(Process::spawn(new HttpServer(atoi(argv[1]))));
-#endif /* USE_LITHE */
-
- return 0;
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/latch.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/latch.cpp b/third_party/libprocess/src/latch.cpp
deleted file mode 100644
index a6f1256..0000000
--- a/third_party/libprocess/src/latch.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <process/id.hpp>
-#include <process/latch.hpp>
-#include <process/process.hpp>
-
-#include <stout/duration.hpp>
-
-namespace process {
-
-// TODO(benh): Provide an "optimized" implementation of a latch that
-// is libprocess aware. That is, allow integrate "waiting" on a latch
-// within libprocess such that it doesn't cost a memory allocation, a
-// spawn, a message send, a wait, and two user-space context-switchs.
-
-Latch::Latch()
-{
- triggered = false;
-
- // Deadlock is possible if one thread is trying to delete a latch
- // but the libprocess thread(s) is trying to acquire a resource the
- // deleting thread is holding. Hence, we only save the PID for
- // triggering the latch and let the GC actually do the deleting
- // (thus no waiting is necessary, and deadlocks are avoided).
- pid = spawn(new ProcessBase(ID::generate("__latch__")), true);
-}
-
-
-Latch::~Latch()
-{
- terminate(pid);
-}
-
-
-void Latch::trigger()
-{
- if (!triggered) {
- terminate(pid);
- triggered = true;
- }
-}
-
-
-bool Latch::await(const Duration& duration)
-{
- if (!triggered) {
- process::wait(pid, duration); // Explict to disambiguate.
- // It's possible that we failed to wait because:
- // (1) Our process has already terminated.
- // (2) We timed out (i.e., duration was not "infinite").
-
- // In the event of (1) we might need to return 'true' since a
- // terminated process might imply that the latch has been
- // triggered. To capture this we simply return the value of
- // 'triggered' (which will also capture cases where we actually
- // timed out but have since triggered, which seems like an
- // acceptable semantics given such a "tie").
- return triggered;
- }
-
- return true;
-}
-
-} // namespace process {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/net.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/net.hpp b/third_party/libprocess/src/net.hpp
deleted file mode 100644
index 2fdc62a..0000000
--- a/third_party/libprocess/src/net.hpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* TODO(benh): Write a form of 'Client' process. */
-
-#ifndef NET_HPP
-#define NET_HPP
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <process.hpp>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-
-#include <sys/ioctl.h>
-#include <sys/sendfile.h>
-#include <sys/socket.h>
-
-#include <stdexcept>
-#include <iostream>
-
-#include <stout/os.hpp>
-
-typedef enum Protocol { TCP = SOCK_STREAM, UDP = SOCK_DGRAM } Protocol;
-
-using std::runtime_error;
-using std::string;
-
-
-template <Protocol protocol>
-class SocketProcess : public Process
-{
-protected:
- int s;
-
- void setsockopt(int level, int optname, const void *optval, socklen_t optlen)
- {
- if (::setsockopt(s, level, optname, optval, optlen) < 0)
- throw std::runtime_error(string("setsockopt: ") += strerror(errno));
- }
-
- virtual void socket()
- {
- if ((s = ::socket(AF_INET, protocol, IPPROTO_IP)) < 0)
- throw runtime_error(string("socket: ") += strerror(errno));
-
- socket(s);
- }
-
- virtual void socket(int sd)
- {
- s = sd;
-
- int flags = 1;
- if (ioctl(s, FIONBIO, &flags) &&
- ((flags = fcntl(s, F_GETFL, 0)) < 0 ||
- fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0))
- throw runtime_error(string("ioctl/fcntl: ") += strerror(errno));
-
- if (fcntl(s, F_SETFD, FD_CLOEXEC) < 0) {
- throw runtime_error(string("fcntl: ") += strerror(errno));
- }
- }
-
- virtual void bind(in_addr_t ip, in_port_t port)
- {
- struct sockaddr_in addr;
- addr.sin_family = PF_INET;
- addr.sin_addr.s_addr = ip;
- addr.sin_port = htons(port);
-
- if (::bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0)
- throw runtime_error(string("bind: ") += strerror(errno));
- }
-
- virtual ssize_t recv(void *buf, size_t bytes)
- {
- ssize_t len = 0;
- do {
- len = ::recv(s, buf, bytes, 0);
-
- if (len > 0)
- return len;
- else if (len < 0 && errno == EWOULDBLOCK)
- while (!await(s, RDONLY));
- else if (len == 0)
- throw runtime_error(string("recv: connection terminated"));
- else
- throw runtime_error(string("recv: ") += strerror(errno));
- } while (!(len > 0));
-
- return len;
- }
-
- virtual ssize_t recvall(void *buf, size_t bytes)
- {
- ssize_t len, offset = 0;
- do {
- len = ::recv(s, (char *) buf + offset, bytes - offset, 0);
-
- if (len > 0)
- offset += len;
- else if (len < 0 && errno == EWOULDBLOCK)
- while (!await(s, RDONLY));
- else if (len == 0)
- throw runtime_error(string("recvall: connection terminated"));
- else
- throw runtime_error(string("recvall: ") += strerror(errno));
- } while (offset != bytes);
-
- return offset;
- }
-
- virtual void send(const void *buf, size_t bytes)
- {
- size_t offset = 0;
- do {
- size_t len =
- ::send(s, (char *) buf + offset, bytes - offset, MSG_NOSIGNAL);
-
- if (len > 0)
- offset += len;
- else if (len < 0 && errno == EWOULDBLOCK)
- while (!await(s, WRONLY));
- else if (len == 0)
- throw runtime_error(string("send: connection terminated"));
- else
- throw runtime_error(string("send: ") += strerror(errno));
- } while (offset != bytes);
- }
-
- virtual void sendfile(int fd, size_t bytes)
- {
- off_t offset = 0;
- do {
- size_t len = ::sendfile(s, fd, 0, bytes - offset);
-
- if (len > 0)
- offset += len;
- else if (len < 0 && errno == EWOULDBLOCK)
- while (!await(s, WRONLY));
- else if (len == 0)
- throw runtime_error(string("sendfile: connection terminated"));
- else
- throw runtime_error(string("sendfile: ") += strerror(errno));
- } while (offset != bytes);
- }
-
-public:
- SocketProcess() : s(-1) {}
- SocketProcess(int _s) : s(_s)
- {
- int flags = 1;
- if (ioctl(s, FIONBIO, &flags) &&
- ((flags = fcntl(s, F_GETFL, 0)) < 0 ||
- fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0))
- throw runtime_error(string("ioctl/fcntl: ") += strerror(errno));
- }
- ~SocketProcess() { os::close(s); }
-};
-
-
-template <Protocol protocol>
-class Acceptor : public SocketProcess<protocol>
-{
-protected:
- virtual int accept(struct sockaddr_in &addr)
- {
- int c;
-
- do {
- while (!await(SocketProcess<protocol>::s, Process::RDONLY));
-
- size_t size = sizeof(struct sockaddr_in);
-
- c = ::accept(SocketProcess<protocol>::s,
- (struct sockaddr *) &addr,
- (socklen_t *) &size);
-
- if (c == 0)
- throw runtime_error(string("accept: ") += strerror(errno));
- else if (c < 0 && (errno != EWOULDBLOCK))
- throw runtime_error(string("accept: ") += strerror(errno));
- } while (!(c > 0));
-
- return c;
- }
-
-public:
- Acceptor() {}
- Acceptor(int s) : SocketProcess<protocol>(s) {}
-};
-
-
-template <Protocol protocol>
-class Server : public Acceptor<protocol>
-{
-protected:
- in_addr_t ip;
- in_port_t port;
-
- void init(in_addr_t _ip = INADDR_ANY, in_port_t _port = 0)
- {
- ip = _ip;
- port = _port;
- SocketProcess<protocol>::socket();
- }
-
- virtual void listen(int n)
- {
- int &s = SocketProcess<protocol>::s;
- if (::listen(s, n) < 0)
- throw runtime_error(string("listen: ") += strerror(errno));
- }
-
- virtual void bind()
- {
- SocketProcess<protocol>::bind(ip, port);
- }
-
-public:
- Server(in_addr_t _ip = INADDR_ANY, in_port_t _port = 0)
- : ip(_ip), port(_port)
- {
- SocketProcess<protocol>::socket();
- }
-};
-
-
-#endif /* NET_HH */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/pid.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/pid.cpp b/third_party/libprocess/src/pid.cpp
deleted file mode 100644
index 8f32b08..0000000
--- a/third_party/libprocess/src/pid.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-#include <errno.h>
-#include <netdb.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <arpa/inet.h>
-
-#include <glog/logging.h>
-
-#include <iostream>
-#include <string>
-
-#include <boost/unordered_map.hpp>
-
-#include <process/pid.hpp>
-#include <process/process.hpp>
-
-#include "config.hpp"
-
-#ifdef __APPLE__
-#define gethostbyname2_r(name, af, ret, buf, buflen, result, h_errnop) \
- ({ *(result) = gethostbyname2(name, af); 0; })
-#endif // __APPLE__
-
-
-using std::istream;
-using std::ostream;
-using std::size_t;
-using std::string;
-
-
-namespace process {
-
-UPID::UPID(const char* s)
-{
- std::istringstream in(s);
- in >> *this;
-}
-
-
-UPID::UPID(const std::string& s)
-{
- std::istringstream in(s);
- in >> *this;
-}
-
-
-// TODO(benh): Make this inline-able (cyclic dependency issues).
-UPID::UPID(const ProcessBase& process)
-{
- id = process.self().id;
- ip = process.self().ip;
- port = process.self().port;
-}
-
-
-UPID::operator std::string() const
-{
- std::ostringstream out;
- out << *this;
- return out.str();
-}
-
-
-ostream& operator << (ostream& stream, const UPID& pid)
-{
- // Call inet_ntop since inet_ntoa is not thread-safe!
- char ip[INET_ADDRSTRLEN];
- if (inet_ntop(AF_INET, (in_addr *) &pid.ip, ip, INET_ADDRSTRLEN) == NULL)
- memset(ip, 0, INET_ADDRSTRLEN);
-
- stream << pid.id << "@" << ip << ":" << pid.port;
- return stream;
-}
-
-
-istream& operator >> (istream& stream, UPID& pid)
-{
- pid.id = "";
- pid.ip = 0;
- pid.port = 0;
-
- string str;
- if (!(stream >> str)) {
- stream.setstate(std::ios_base::badbit);
- return stream;
- }
-
- VLOG(2) << "Attempting to parse '" << str << "' into a PID";
-
- if (str.size() == 0) {
- stream.setstate(std::ios_base::badbit);
- return stream;
- }
-
- string id;
- string host;
- uint32_t ip;
- uint16_t port;
-
- size_t index = str.find('@');
-
- if (index != string::npos) {
- id = str.substr(0, index);
- } else {
- stream.setstate(std::ios_base::badbit);
- return stream;
- }
-
- str = str.substr(index + 1);
-
- index = str.find(':');
-
- if (index != string::npos) {
- host = str.substr(0, index);
- } else {
- stream.setstate(std::ios_base::badbit);
- return stream;
- }
-
- hostent he, *hep;
- char* temp;
- size_t length;
- int result;
- int herrno;
-
- // Allocate temporary buffer for gethostbyname2_r.
- length = 1024;
- temp = new char[length];
-
- while ((result = gethostbyname2_r(host.c_str(), AF_INET, &he,
- temp, length, &hep, &herrno)) == ERANGE) {
- // Enlarge the buffer.
- delete[] temp;
- length *= 2;
- temp = new char[length];
- }
-
- if (result != 0 || hep == NULL) {
- VLOG(2) << "Failed to parse host '" << host
- << "' because " << hstrerror(herrno);
- delete[] temp;
- stream.setstate(std::ios_base::badbit);
- return stream;
- }
-
- if (hep->h_addr_list[0] == NULL) {
- VLOG(2) << "Got no addresses for '" << host << "'";
- delete[] temp;
- stream.setstate(std::ios_base::badbit);
- return stream;
- }
-
- ip = *((uint32_t*) hep->h_addr_list[0]);
-
- delete[] temp;
-
- str = str.substr(index + 1);
-
- if (sscanf(str.c_str(), "%hu", &port) != 1) {
- stream.setstate(std::ios_base::badbit);
- return stream;
- }
-
- pid.id = id;
- pid.ip = ip;
- pid.port = port;
-
- return stream;
-}
-
-
-size_t hash_value(const UPID& pid)
-{
- size_t seed = 0;
- boost::hash_combine(seed, pid.id);
- boost::hash_combine(seed, pid.ip);
- boost::hash_combine(seed, pid.port);
- return seed;
-}
-
-} // namespace process {
[33/35] git commit: Used ThreadLocal from stout.
Posted by be...@apache.org.
Used ThreadLocal from stout.
Review: https://reviews.apache.org/r/11475
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/1caf21b4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/1caf21b4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/1caf21b4
Branch: refs/heads/master
Commit: 1caf21b4faea2322cf39ecabaa0d0578132ab6ce
Parents: bb1c353
Author: Benjamin Hindman <be...@twitter.com>
Authored: Mon May 27 12:29:53 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:20:25 2013 -0700
----------------------------------------------------------------------
3rdparty/libprocess/3rdparty/Makefile.am | 1 +
3rdparty/libprocess/Makefile.am | 1 -
3rdparty/libprocess/include/process/executor.hpp | 2 +-
3rdparty/libprocess/include/process/process.hpp | 2 +-
3rdparty/libprocess/include/process/thread.hpp | 49 -----------------
3rdparty/libprocess/src/process.cpp | 2 +-
3rdparty/libprocess/src/tests/process_tests.cpp | 23 --------
7 files changed, 4 insertions(+), 76 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1caf21b4/3rdparty/libprocess/3rdparty/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/Makefile.am b/3rdparty/libprocess/3rdparty/Makefile.am
index 20599ec..7a9ede6 100644
--- a/3rdparty/libprocess/3rdparty/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/Makefile.am
@@ -128,6 +128,7 @@ stout_tests_SOURCES = \
$(STOUT)/tests/none_tests.cpp \
$(STOUT)/tests/os_tests.cpp \
$(STOUT)/tests/strings_tests.cpp \
+ $(STOUT)/tests/thread_tests.cpp \
$(STOUT)/tests/uuid_tests.cpp
if OS_LINUX
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1caf21b4/3rdparty/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/Makefile.am b/3rdparty/libprocess/Makefile.am
index b6b8abd..9facdd9 100644
--- a/3rdparty/libprocess/Makefile.am
+++ b/3rdparty/libprocess/Makefile.am
@@ -87,7 +87,6 @@ libprocess_la_SOURCES += \
$(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
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1caf21b4/3rdparty/libprocess/include/process/executor.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/executor.hpp b/3rdparty/libprocess/include/process/executor.hpp
index 72fb2f1..f203476 100644
--- a/3rdparty/libprocess/include/process/executor.hpp
+++ b/3rdparty/libprocess/include/process/executor.hpp
@@ -4,9 +4,9 @@
#include <process/deferred.hpp>
#include <process/dispatch.hpp>
#include <process/id.hpp>
-#include <process/thread.hpp>
#include <stout/preprocessor.hpp>
+#include <stout/thread.hpp>
namespace process {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1caf21b4/3rdparty/libprocess/include/process/process.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/process.hpp b/3rdparty/libprocess/include/process/process.hpp
index 8228e4f..e70b4f7 100644
--- a/3rdparty/libprocess/include/process/process.hpp
+++ b/3rdparty/libprocess/include/process/process.hpp
@@ -16,9 +16,9 @@
#include <process/message.hpp>
#include <process/mime.hpp>
#include <process/pid.hpp>
-#include <process/thread.hpp>
#include <stout/duration.hpp>
+#include <stout/thread.hpp>
namespace process {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1caf21b4/3rdparty/libprocess/include/process/thread.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/thread.hpp b/3rdparty/libprocess/include/process/thread.hpp
deleted file mode 100644
index 3e3b5d2..0000000
--- a/3rdparty/libprocess/include/process/thread.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef __PROCESS_THREAD_HPP__
-#define __PROCESS_THREAD_HPP__
-
-#include <pthread.h>
-#include <stdio.h> // For perror.
-#include <stdlib.h> // For abort.
-
-template <typename T>
-struct ThreadLocal
-{
- ThreadLocal()
- {
- if (pthread_key_create(&key, NULL) != 0) {
- perror("Failed to create thread local, pthread_key_create");
- abort();
- }
- }
-
- ThreadLocal<T>& operator = (T* t)
- {
- if (pthread_setspecific(key, t) != 0) {
- perror("Failed to set thread local, pthread_setspecific");
- abort();
- }
- return *this;
- }
-
- operator T* () const
- {
- return reinterpret_cast<T*>(pthread_getspecific(key));
- }
-
- T* operator -> () const
- {
- return reinterpret_cast<T*>(pthread_getspecific(key));
- }
-
-private:
- // Not expecting any other operators to be used (and the rest?).
- bool operator * (const ThreadLocal<T>&) const;
- bool operator == (const ThreadLocal<T>&) const;
- bool operator != (const ThreadLocal<T>&) const;
- bool operator < (const ThreadLocal<T>&) const;
- bool operator > (const ThreadLocal<T>&) const;
-
- pthread_key_t key;
-};
-
-#endif // __PROCESS_THREAD_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1caf21b4/3rdparty/libprocess/src/process.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/process.cpp b/3rdparty/libprocess/src/process.cpp
index 86414e5..3ffe0b5 100644
--- a/3rdparty/libprocess/src/process.cpp
+++ b/3rdparty/libprocess/src/process.cpp
@@ -61,7 +61,6 @@
#include <process/profiler.hpp>
#include <process/socket.hpp>
#include <process/statistics.hpp>
-#include <process/thread.hpp>
#include <process/time.hpp>
#include <process/timer.hpp>
@@ -71,6 +70,7 @@
#include <stout/net.hpp>
#include <stout/os.hpp>
#include <stout/strings.hpp>
+#include <stout/thread.hpp>
#include "config.hpp"
#include "decoder.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1caf21b4/3rdparty/libprocess/src/tests/process_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/process_tests.cpp b/3rdparty/libprocess/src/tests/process_tests.cpp
index dc5c671..dfa11df 100644
--- a/3rdparty/libprocess/src/tests/process_tests.cpp
+++ b/3rdparty/libprocess/src/tests/process_tests.cpp
@@ -22,7 +22,6 @@
#include <process/gtest.hpp>
#include <process/process.hpp>
#include <process/run.hpp>
-#include <process/thread.hpp>
#include <process/time.hpp>
#include <stout/duration.hpp>
@@ -42,28 +41,6 @@ using testing::ReturnArg;
// TODO(bmahler): Move tests into their own files as appropriate.
-TEST(Process, thread)
-{
- ThreadLocal<ProcessBase>* _process_ = new ThreadLocal<ProcessBase>();
-
- ProcessBase* process = new ProcessBase();
-
- ASSERT_TRUE(*(_process_) == NULL);
-
- (*_process_) = process;
-
- ASSERT_TRUE(*(_process_) == process);
- ASSERT_FALSE(*(_process_) == NULL);
-
- (*_process_) = NULL;
-
- ASSERT_TRUE(*(_process_) == NULL);
-
- delete process;
- delete _process_;
-}
-
-
TEST(Process, event)
{
Event* event = new TerminateEvent(UPID());
[15/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/process.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/process.cpp b/third_party/libprocess/src/process.cpp
deleted file mode 100644
index 86414e5..0000000
--- a/third_party/libprocess/src/process.cpp
+++ /dev/null
@@ -1,3446 +0,0 @@
-#include <errno.h>
-#include <ev.h>
-#include <limits.h>
-#include <libgen.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <arpa/inet.h>
-
-#include <glog/logging.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-
-#include <algorithm>
-#include <deque>
-#include <fstream>
-#include <iomanip>
-#include <iostream>
-#include <list>
-#include <map>
-#include <queue>
-#include <set>
-#include <sstream>
-#include <stack>
-#include <stdexcept>
-#include <vector>
-
-#include <tr1/functional>
-#include <tr1/memory> // TODO(benh): Replace all shared_ptr with unique_ptr.
-
-#include <boost/shared_array.hpp>
-
-#include <process/clock.hpp>
-#include <process/defer.hpp>
-#include <process/delay.hpp>
-#include <process/dispatch.hpp>
-#include <process/executor.hpp>
-#include <process/filter.hpp>
-#include <process/future.hpp>
-#include <process/gc.hpp>
-#include <process/id.hpp>
-#include <process/io.hpp>
-#include <process/logging.hpp>
-#include <process/mime.hpp>
-#include <process/process.hpp>
-#include <process/profiler.hpp>
-#include <process/socket.hpp>
-#include <process/statistics.hpp>
-#include <process/thread.hpp>
-#include <process/time.hpp>
-#include <process/timer.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/foreach.hpp>
-#include <stout/lambda.hpp>
-#include <stout/net.hpp>
-#include <stout/os.hpp>
-#include <stout/strings.hpp>
-
-#include "config.hpp"
-#include "decoder.hpp"
-#include "encoder.hpp"
-#include "gate.hpp"
-#include "synchronized.hpp"
-
-using process::wait; // Necessary on some OS's to disambiguate.
-
-using process::http::BadRequest;
-using process::http::InternalServerError;
-using process::http::NotFound;
-using process::http::OK;
-using process::http::Request;
-using process::http::Response;
-using process::http::ServiceUnavailable;
-
-using std::deque;
-using std::find;
-using std::list;
-using std::map;
-using std::ostream;
-using std::pair;
-using std::queue;
-using std::set;
-using std::stack;
-using std::string;
-using std::stringstream;
-using std::vector;
-
-// Represents a remote "node" (encapsulates IP address and port).
-class Node
-{
-public:
- Node(uint32_t _ip = 0, uint16_t _port = 0)
- : ip(_ip), port(_port) {}
-
- bool operator < (const Node& that) const
- {
- if (ip == that.ip) {
- return port < that.port;
- } else {
- return ip < that.ip;
- }
- }
-
- ostream& operator << (ostream& stream) const
- {
- stream << ip << ":" << port;
- return stream;
- }
-
- uint32_t ip;
- uint16_t port;
-};
-
-
-namespace process {
-
-namespace ID {
-
-string generate(const string& prefix)
-{
- static map<string, int> prefixes;
- stringstream out;
- out << __sync_add_and_fetch(&prefixes[prefix], 1);
- return prefix + "(" + out.str() + ")";
-}
-
-} // namespace ID {
-
-
-namespace http {
-
-hashmap<uint16_t, string> statuses;
-
-} // namespace http {
-
-
-namespace mime {
-
-map<string, string> types;
-
-} // namespace mime {
-
-
-// Provides reference counting semantics for a process pointer.
-class ProcessReference
-{
-public:
- ProcessReference() : process(NULL) {}
-
- ~ProcessReference()
- {
- cleanup();
- }
-
- ProcessReference(const ProcessReference& that)
- {
- copy(that);
- }
-
- ProcessReference& operator = (const ProcessReference& that)
- {
- if (this != &that) {
- cleanup();
- copy(that);
- }
- return *this;
- }
-
- ProcessBase* operator -> ()
- {
- return process;
- }
-
- operator ProcessBase* ()
- {
- return process;
- }
-
- operator bool () const
- {
- return process != NULL;
- }
-
-private:
- friend class ProcessManager; // For ProcessManager::use.
-
- ProcessReference(ProcessBase* _process)
- : process(_process)
- {
- if (process != NULL) {
- __sync_fetch_and_add(&(process->refs), 1);
- }
- }
-
- void copy(const ProcessReference& that)
- {
- process = that.process;
-
- if (process != NULL) {
- // There should be at least one reference to the process, so
- // we don't need to worry about checking if it's exiting or
- // not, since we know we can always create another reference.
- CHECK(process->refs > 0);
- __sync_fetch_and_add(&(process->refs), 1);
- }
- }
-
- void cleanup()
- {
- if (process != NULL) {
- __sync_fetch_and_sub(&(process->refs), 1);
- }
- }
-
- ProcessBase* process;
-};
-
-
-// Provides a process that manages sending HTTP responses so as to
-// satisfy HTTP/1.1 pipelining. Each request should either enqueue a
-// response, or ask the proxy to handle a future response. The process
-// is responsible for making sure the responses are sent in the same
-// order as the requests. Note that we use a 'Socket' in order to keep
-// the underyling file descriptor from getting closed while there
-// might still be outstanding responses even though the client might
-// have closed the connection (see more discussion in
-// SocketManger::close and SocketManager::proxy).
-class HttpProxy : public Process<HttpProxy>
-{
-public:
- HttpProxy(const Socket& _socket);
- virtual ~HttpProxy();
-
- // Enqueues the response to be sent once all previously enqueued
- // responses have been processed (e.g., waited for and sent).
- void enqueue(const Response& response, const Request& request);
-
- // Enqueues a future to a response that will get waited on (up to
- // some timeout) and then sent once all previously enqueued
- // responses have been processed (e.g., waited for and sent).
- void handle(Future<Response>* future, const Request& request);
-
-private:
- // Starts "waiting" on the next available future response.
- void next();
-
- // Invoked once a future response has been satisfied.
- void waited(const Future<Response>& future);
-
- // Demuxes and handles a response.
- bool process(const Future<Response>& future, const Request& request);
-
- // Handles stream (i.e., pipe) based responses.
- void stream(const Future<short>& poll, const Request& request);
-
- Socket socket; // Wrap the socket to keep it from getting closed.
-
- // Describes a queue "item" that wraps the future to the response
- // and the original request.
- // The original request contains needed information such as what encodings
- // are acceptable and whether to persist the connection.
- struct Item
- {
- Item(const Request& _request, Future<Response>* _future)
- : request(_request), future(_future) {}
-
- ~Item()
- {
- delete future;
- }
-
- const Request request; // Make a copy.
- Future<Response>* future;
- };
-
- queue<Item*> items;
-
- Option<int> pipe; // Current pipe, if streaming.
-};
-
-
-class SocketManager
-{
-public:
- SocketManager();
- ~SocketManager();
-
- Socket accepted(int s);
-
- void link(ProcessBase* process, const UPID& to);
-
- PID<HttpProxy> proxy(const Socket& socket);
-
- void send(Encoder* encoder, bool persist);
- void send(const Response& response,
- const Request& request,
- const Socket& socket);
- void send(Message* message);
-
- Encoder* next(int s);
-
- void close(int s);
-
- void exited(const Node& node);
- void exited(ProcessBase* process);
-
-private:
- // Map from UPID (local/remote) to process.
- map<UPID, set<ProcessBase*> > links;
-
- // Collection of all actice sockets.
- map<int, Socket> sockets;
-
- // Collection of sockets that should be disposed when they are
- // finished being used (e.g., when there is no more data to send on
- // them).
- set<int> dispose;
-
- // Map from socket to node (ip, port).
- map<int, Node> nodes;
-
- // Maps from node (ip, port) to temporary sockets (i.e., they will
- // get closed once there is no more data to send on them).
- map<Node, int> temps;
-
- // Maps from node (ip, port) to persistent sockets (i.e., they will
- // remain open even if there is no more data to send on them). We
- // distinguish these from the 'temps' collection so we can tell when
- // a persistant socket has been lost (and thus generate
- // ExitedEvents).
- map<Node, int> persists;
-
- // Map from socket to outgoing queue.
- map<int, queue<Encoder*> > outgoing;
-
- // HTTP proxies.
- map<int, HttpProxy*> proxies;
-
- // Protects instance variables.
- synchronizable(this);
-};
-
-
-class ProcessManager
-{
-public:
- ProcessManager(const string& delegate);
- ~ProcessManager();
-
- ProcessReference use(const UPID& pid);
-
- bool handle(
- const Socket& socket,
- Request* request);
-
- bool deliver(
- ProcessBase* receiver,
- Event* event,
- ProcessBase* sender = NULL);
-
- bool deliver(
- const UPID& to,
- Event* event,
- ProcessBase* sender = NULL);
-
- UPID spawn(ProcessBase* process, bool manage);
- void resume(ProcessBase* process);
- void cleanup(ProcessBase* process);
- void link(ProcessBase* process, const UPID& to);
- void terminate(const UPID& pid, bool inject, ProcessBase* sender = NULL);
- bool wait(const UPID& pid);
-
- void enqueue(ProcessBase* process);
- ProcessBase* dequeue();
-
- void settle();
-
-private:
- // Delegate process name to receive root HTTP requests.
- const string delegate;
-
- // Map of all local spawned and running processes.
- map<string, ProcessBase*> processes;
- synchronizable(processes);
-
- // Gates for waiting threads (protected by synchronizable(processes)).
- map<ProcessBase*, Gate*> gates;
-
- // Queue of runnable processes (implemented using list).
- list<ProcessBase*> runq;
- synchronizable(runq);
-
- // Number of running processes, to support Clock::settle operation.
- int running;
-};
-
-
-// Unique id that can be assigned to each process.
-static uint32_t __id__ = 0;
-
-// Local server socket.
-static int __s__ = -1;
-
-// Local IP address.
-static uint32_t __ip__ = 0;
-
-// Local port.
-static uint16_t __port__ = 0;
-
-// Active SocketManager (eventually will probably be thread-local).
-static SocketManager* socket_manager = NULL;
-
-// Active ProcessManager (eventually will probably be thread-local).
-static ProcessManager* process_manager = NULL;
-
-// Event loop.
-static struct ev_loop* loop = NULL;
-
-// Asynchronous watcher for interrupting loop.
-static ev_async async_watcher;
-
-// Watcher for timeouts.
-static ev_timer timeouts_watcher;
-
-// Server watcher for accepting connections.
-static ev_io server_watcher;
-
-// Queue of I/O watchers.
-static queue<ev_io*>* watchers = new queue<ev_io*>();
-static synchronizable(watchers) = SYNCHRONIZED_INITIALIZER;
-
-// We store the timers in a map of lists indexed by the timeout of the
-// timer so that we can have two timers that have the same timeout. We
-// exploit that the map is SORTED!
-static map<Time, list<Timer> >* timeouts =
- new map<Time, list<Timer> >();
-static synchronizable(timeouts) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
-
-// For supporting Clock::settle(), true if timers have been removed
-// from 'timeouts' but may not have been executed yet. Protected by
-// the timeouts lock. This is only used when the clock is paused.
-static bool pending_timers = false;
-
-// Flag to indicate whether or to update the timer on async interrupt.
-static bool update_timer = false;
-
-// Scheduling gate that threads wait at when there is nothing to run.
-static Gate* gate = new Gate();
-
-// Filter. Synchronized support for using the filterer needs to be
-// recursive incase a filterer wants to do anything fancy (which is
-// possible and likely given that filters will get used for testing).
-static Filter* filterer = NULL;
-static synchronizable(filterer) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
-
-// Global garbage collector.
-PID<GarbageCollector> gc;
-
-// Per thread process pointer.
-ThreadLocal<ProcessBase>* _process_ = new ThreadLocal<ProcessBase>();
-
-// Per thread executor pointer.
-ThreadLocal<Executor>* _executor_ = new ThreadLocal<Executor>();
-
-
-// We namespace the clock related variables to keep them well
-// named. In the future we'll probably want to associate a clock with
-// a specific ProcessManager/SocketManager instance pair, so this will
-// likely change.
-namespace clock {
-
-map<ProcessBase*, Time>* currents = new map<ProcessBase*, Time>();
-
-Time initial = Time::EPOCH;
-Time current = Time::EPOCH;
-
-bool paused = false;
-
-} // namespace clock {
-
-
-Time Time::EPOCH = Time(Duration::zero());
-
-
-Time Time::MAX = Time(Duration::max());
-
-
-Time Clock::now()
-{
- return now(__process__);
-}
-
-
-Time Clock::now(ProcessBase* process)
-{
- synchronized (timeouts) {
- if (Clock::paused()) {
- if (process != NULL) {
- if (clock::currents->count(process) != 0) {
- return (*clock::currents)[process];
- } else {
- return (*clock::currents)[process] = clock::initial;
- }
- } else {
- return clock::current;
- }
- }
- }
-
- // TODO(benh): Versus ev_now()?
- double d = ev_time();
- Try<Time> time = Time::create(d);
-
- // TODO(xujyan): Move CHECK_SOME to libprocess and add CHECK_SOME
- // here.
- if (time.isError()) {
- LOG(FATAL) << "Failed to create a Time from " << d << ": "
- << time.error();
- }
- return time.get();
-}
-
-
-void Clock::pause()
-{
- process::initialize(); // To make sure the libev watchers are ready.
-
- synchronized (timeouts) {
- if (!clock::paused) {
- clock::initial = clock::current = now();
- clock::paused = true;
- VLOG(2) << "Clock paused at " << clock::initial;
- }
- }
-
- // Note that after pausing the clock an existing libev timer might
- // still fire (invoking handle_timeout), but since paused == true no
- // "time" will actually have passed, so no timer will actually fire.
-}
-
-
-bool Clock::paused()
-{
- return clock::paused;
-}
-
-
-void Clock::resume()
-{
- process::initialize(); // To make sure the libev watchers are ready.
-
- synchronized (timeouts) {
- if (clock::paused) {
- VLOG(2) << "Clock resumed at " << clock::current;
- clock::paused = false;
- clock::currents->clear();
- update_timer = true;
- ev_async_send(loop, &async_watcher);
- }
- }
-}
-
-
-void Clock::advance(const Duration& duration)
-{
- synchronized (timeouts) {
- if (clock::paused) {
- clock::current += duration;
- VLOG(2) << "Clock advanced (" << duration << ") to " << clock::current;
- if (!update_timer) {
- update_timer = true;
- ev_async_send(loop, &async_watcher);
- }
- }
- }
-}
-
-
-void Clock::advance(ProcessBase* process, const Duration& duration)
-{
- synchronized (timeouts) {
- if (clock::paused) {
- Time current = now(process);
- current += duration;
- (*clock::currents)[process] = current;
- VLOG(2) << "Clock of " << process->self() << " advanced (" << duration
- << ") to " << current;
- }
- }
-}
-
-
-void Clock::update(const Time& time)
-{
- synchronized (timeouts) {
- if (clock::paused) {
- if (clock::current < time) {
- clock::current = Time(time);
- VLOG(2) << "Clock updated to " << clock::current;
- if (!update_timer) {
- update_timer = true;
- ev_async_send(loop, &async_watcher);
- }
- }
- }
- }
-}
-
-
-void Clock::update(ProcessBase* process, const Time& time)
-{
- synchronized (timeouts) {
- if (clock::paused) {
- if (now(process) < time) {
- VLOG(2) << "Clock of " << process->self() << " updated to " << time;
- (*clock::currents)[process] = Time(time);
- }
- }
- }
-}
-
-
-void Clock::order(ProcessBase* from, ProcessBase* to)
-{
- update(to, now(from));
-}
-
-
-void Clock::settle()
-{
- CHECK(clock::paused); // TODO(benh): Consider returning a bool instead.
- process_manager->settle();
-}
-
-
-static Message* encode(const UPID& from,
- const UPID& to,
- const string& name,
- const string& data = "")
-{
- Message* message = new Message();
- message->from = from;
- message->to = to;
- message->name = name;
- message->body = data;
- return message;
-}
-
-
-static void transport(Message* message, ProcessBase* sender = NULL)
-{
- if (message->to.ip == __ip__ && message->to.port == __port__) {
- // Local message.
- process_manager->deliver(message->to, new MessageEvent(message), sender);
- } else {
- // Remote message.
- socket_manager->send(message);
- }
-}
-
-
-static bool libprocess(Request* request)
-{
- return request->method == "POST" &&
- request->headers.count("User-Agent") > 0 &&
- request->headers["User-Agent"].find("libprocess/") == 0;
-}
-
-
-static Message* parse(Request* request)
-{
- // TODO(benh): Do better error handling (to deal with a malformed
- // libprocess message, malicious or otherwise).
- const string& agent = request->headers["User-Agent"];
- const string& identifier = "libprocess/";
- size_t index = agent.find(identifier);
- if (index != string::npos) {
- // Okay, now determine 'from'.
- const UPID from(agent.substr(index + identifier.size(), agent.size()));
-
- // Now determine 'to'.
- index = request->path.find('/', 1);
- index = index != string::npos ? index - 1 : string::npos;
- const UPID to(request->path.substr(1, index), __ip__, __port__);
-
- // And now determine 'name'.
- index = index != string::npos ? index + 2: request->path.size();
- const string& name = request->path.substr(index);
-
- VLOG(2) << "Parsed message name '" << name
- << "' for " << to << " from " << from;
-
- Message* message = new Message();
- message->name = name;
- message->from = from;
- message->to = to;
- message->body = request->body;
-
- return message;
- }
-
- return NULL;
-}
-
-
-void handle_async(struct ev_loop* loop, ev_async* _, int revents)
-{
- synchronized (watchers) {
- // Start all the new I/O watchers.
- while (!watchers->empty()) {
- ev_io* watcher = watchers->front();
- watchers->pop();
- ev_io_start(loop, watcher);
- }
- }
-
- synchronized (timeouts) {
- if (update_timer) {
- if (!timeouts->empty()) {
- // Determine when the next timer should fire.
- timeouts_watcher.repeat = (timeouts->begin()->first - Clock::now()).secs();
-
- if (timeouts_watcher.repeat <= 0) {
- // Feed the event now!
- timeouts_watcher.repeat = 0;
- ev_timer_again(loop, &timeouts_watcher);
- ev_feed_event(loop, &timeouts_watcher, EV_TIMEOUT);
- } else {
- // Don't fire the timer if the clock is paused since we
- // don't want time to advance (instead a call to
- // clock::advance() will handle the timer).
- if (Clock::paused() && timeouts_watcher.repeat > 0) {
- timeouts_watcher.repeat = 0;
- }
-
- ev_timer_again(loop, &timeouts_watcher);
- }
- }
-
- update_timer = false;
- }
- }
-}
-
-
-void handle_timeouts(struct ev_loop* loop, ev_timer* _, int revents)
-{
- list<Timer> timedout;
-
- synchronized (timeouts) {
- Time now = Clock::now();
-
- VLOG(3) << "Handling timeouts up to " << now;
-
- foreachkey (const Time& timeout, *timeouts) {
- if (timeout > now) {
- break;
- }
-
- VLOG(3) << "Have timeout(s) at " << timeout;
-
- // Record that we have pending timers to execute so the
- // Clock::settle() operation can wait until we're done.
- pending_timers = true;
-
- foreach (const Timer& timer, (*timeouts)[timeout]) {
- timedout.push_back(timer);
- }
- }
-
- // Now erase the range of timeouts that timed out.
- timeouts->erase(timeouts->begin(), timeouts->upper_bound(now));
-
- // Okay, so the timeout for the next timer should not have fired.
- CHECK(timeouts->empty() || (timeouts->begin()->first > now));
-
- // Update the timer as necessary.
- if (!timeouts->empty()) {
- // Determine when the next timer should fire.
- timeouts_watcher.repeat =
- (timeouts->begin()->first - Clock::now()).secs();
-
- if (timeouts_watcher.repeat <= 0) {
- // Feed the event now!
- timeouts_watcher.repeat = 0;
- ev_timer_again(loop, &timeouts_watcher);
- ev_feed_event(loop, &timeouts_watcher, EV_TIMEOUT);
- } else {
- // Don't fire the timer if the clock is paused since we don't
- // want time to advance (instead a call to Clock::advance()
- // will handle the timer).
- if (Clock::paused() && timeouts_watcher.repeat > 0) {
- timeouts_watcher.repeat = 0;
- }
-
- ev_timer_again(loop, &timeouts_watcher);
- }
- }
-
- update_timer = false; // Since we might have a queued update_timer.
- }
-
- // Update current time of process (if it's present/valid). It might
- // be necessary to actually add some more synchronization around
- // this so that, for example, pausing and resuming the clock doesn't
- // cause some processes to get thier current times updated and
- // others not. Since ProcessManager::use acquires the 'processes'
- // lock we had to move this out of the synchronized (timeouts) above
- // since there was a deadlock with acquring 'processes' then
- // 'timeouts' (reverse order) in ProcessManager::cleanup. Note that
- // current time may be greater than the timeout if a local message
- // was received (and happens-before kicks in).
- if (Clock::paused()) {
- foreach (const Timer& timer, timedout) {
- if (ProcessReference process = process_manager->use(timer.creator())) {
- Clock::update(process, timer.timeout().time());
- }
- }
- }
-
- // Invoke the timers that timed out (TODO(benh): Do this
- // asynchronously so that we don't tie up the event thread!).
- foreach (const Timer& timer, timedout) {
- timer();
- }
-
- // Mark ourselves as done executing the timers since it's now safe
- // for a call to Clock::settle() to check if there will be any
- // future timeouts reached.
- synchronized (timeouts) {
- pending_timers = false;
- }
-}
-
-
-void recv_data(struct ev_loop* loop, ev_io* watcher, int revents)
-{
- DataDecoder* decoder = (DataDecoder*) watcher->data;
-
- int s = watcher->fd;
-
- while (true) {
- const ssize_t size = 80 * 1024;
- ssize_t length = 0;
-
- char data[size];
-
- length = recv(s, data, size, 0);
-
- if (length < 0 && (errno == EINTR)) {
- // Interrupted, try again now.
- continue;
- } else if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
- // Might block, try again later.
- break;
- } else if (length <= 0) {
- // Socket error or closed.
- if (length < 0) {
- const char* error = strerror(errno);
- VLOG(1) << "Socket error while receiving: " << error;
- } else {
- VLOG(1) << "Socket closed while receiving";
- }
- socket_manager->close(s);
- delete decoder;
- ev_io_stop(loop, watcher);
- delete watcher;
- break;
- } else {
- CHECK(length > 0);
-
- // Decode as much of the data as possible into HTTP requests.
- const deque<Request*>& requests = decoder->decode(data, length);
-
- if (!requests.empty()) {
- foreach (Request* request, requests) {
- process_manager->handle(decoder->socket(), request);
- }
- } else if (requests.empty() && decoder->failed()) {
- VLOG(1) << "Decoder error while receiving";
- socket_manager->close(s);
- delete decoder;
- ev_io_stop(loop, watcher);
- delete watcher;
- break;
- }
- }
- }
-}
-
-
-void send_data(struct ev_loop* loop, ev_io* watcher, int revents)
-{
- DataEncoder* encoder = (DataEncoder*) watcher->data;
-
- int s = watcher->fd;
-
- while (true) {
- const void* data;
- size_t size;
-
- data = encoder->next(&size);
- CHECK(size > 0);
-
- ssize_t length = send(s, data, size, MSG_NOSIGNAL);
-
- if (length < 0 && (errno == EINTR)) {
- // Interrupted, try again now.
- encoder->backup(size);
- continue;
- } else if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
- // Might block, try again later.
- encoder->backup(size);
- break;
- } else if (length <= 0) {
- // Socket error or closed.
- if (length < 0) {
- const char* error = strerror(errno);
- VLOG(1) << "Socket error while sending: " << error;
- } else {
- VLOG(1) << "Socket closed while sending";
- }
- socket_manager->close(s);
- delete encoder;
- ev_io_stop(loop, watcher);
- delete watcher;
- break;
- } else {
- CHECK(length > 0);
-
- // Update the encoder with the amount sent.
- encoder->backup(size - length);
-
- // See if there is any more of the message to send.
- if (encoder->remaining() == 0) {
- delete encoder;
-
- // Stop this watcher for now.
- ev_io_stop(loop, watcher);
-
- // Check for more stuff to send on socket.
- Encoder* next = socket_manager->next(s);
- if (next != NULL) {
- watcher->data = next;
- ev_io_init(watcher, next->sender(), s, EV_WRITE);
- ev_io_start(loop, watcher);
- } else {
- // Nothing more to send right now, clean up.
- delete watcher;
- }
- break;
- }
- }
- }
-}
-
-
-void send_file(struct ev_loop* loop, ev_io* watcher, int revents)
-{
- FileEncoder* encoder = (FileEncoder*) watcher->data;
-
- int s = watcher->fd;
-
- while (true) {
- int fd;
- off_t offset;
- size_t size;
-
- fd = encoder->next(&offset, &size);
- CHECK(size > 0);
-
- ssize_t length = sendfile(s, fd, offset, size);
-
- if (length < 0 && (errno == EINTR)) {
- // Interrupted, try again now.
- encoder->backup(size);
- continue;
- } else if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
- // Might block, try again later.
- encoder->backup(size);
- break;
- } else if (length <= 0) {
- // Socket error or closed.
- if (length < 0) {
- const char* error = strerror(errno);
- VLOG(1) << "Socket error while sending: " << error;
- } else {
- VLOG(1) << "Socket closed while sending";
- }
- socket_manager->close(s);
- delete encoder;
- ev_io_stop(loop, watcher);
- delete watcher;
- break;
- } else {
- CHECK(length > 0);
-
- // Update the encoder with the amount sent.
- encoder->backup(size - length);
-
- // See if there is any more of the message to send.
- if (encoder->remaining() == 0) {
- delete encoder;
-
- // Stop this watcher for now.
- ev_io_stop(loop, watcher);
-
- // Check for more stuff to send on socket.
- Encoder* next = socket_manager->next(s);
- if (next != NULL) {
- watcher->data = next;
- ev_io_init(watcher, next->sender(), s, EV_WRITE);
- ev_io_start(loop, watcher);
- } else {
- // Nothing more to send right now, clean up.
- delete watcher;
- }
- break;
- }
- }
- }
-}
-
-
-void sending_connect(struct ev_loop* loop, ev_io* watcher, int revents)
-{
- int s = watcher->fd;
-
- // Now check that a successful connection was made.
- int opt;
- socklen_t optlen = sizeof(opt);
-
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0 || opt != 0) {
- // Connect failure.
- VLOG(1) << "Socket error while connecting";
- socket_manager->close(s);
- MessageEncoder* encoder = (MessageEncoder*) watcher->data;
- delete encoder;
- ev_io_stop(loop, watcher);
- delete watcher;
- } else {
- // We're connected! Now let's do some sending.
- ev_io_stop(loop, watcher);
- ev_io_init(watcher, send_data, s, EV_WRITE);
- ev_io_start(loop, watcher);
- }
-}
-
-
-void receiving_connect(struct ev_loop* loop, ev_io* watcher, int revents)
-{
- int s = watcher->fd;
-
- // Now check that a successful connection was made.
- int opt;
- socklen_t optlen = sizeof(opt);
-
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0 || opt != 0) {
- // Connect failure.
- VLOG(1) << "Socket error while connecting";
- socket_manager->close(s);
- DataDecoder* decoder = (DataDecoder*) watcher->data;
- delete decoder;
- ev_io_stop(loop, watcher);
- delete watcher;
- } else {
- // We're connected! Now let's do some receiving.
- ev_io_stop(loop, watcher);
- ev_io_init(watcher, recv_data, s, EV_READ);
- ev_io_start(loop, watcher);
- }
-}
-
-
-void accept(struct ev_loop* loop, ev_io* watcher, int revents)
-{
- CHECK_EQ(__s__, watcher->fd);
-
- sockaddr_in addr;
- socklen_t addrlen = sizeof(addr);
-
- int s = ::accept(__s__, (sockaddr*) &addr, &addrlen);
-
- if (s < 0) {
- return;
- }
-
- Try<Nothing> nonblock = os::nonblock(s);
- if (nonblock.isError()) {
- LOG_IF(INFO, VLOG_IS_ON(1)) << "Failed to accept, nonblock: "
- << nonblock.error();
- os::close(s);
- return;
- }
-
- Try<Nothing> cloexec = os::cloexec(s);
- if (cloexec.isError()) {
- LOG_IF(INFO, VLOG_IS_ON(1)) << "Failed to accept, cloexec: "
- << cloexec.error();
- os::close(s);
- return;
- }
-
- // Turn off Nagle (TCP_NODELAY) so pipelined requests don't wait.
- int on = 1;
- if (setsockopt(s, SOL_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) {
- const char* error = strerror(errno);
- VLOG(1) << "Failed to turn off the Nagle algorithm: " << error;
- os::close(s);
- } else {
- // Inform the socket manager for proper bookkeeping.
- const Socket& socket = socket_manager->accepted(s);
-
- // Allocate and initialize the decoder and watcher.
- DataDecoder* decoder = new DataDecoder(socket);
-
- ev_io* watcher = new ev_io();
- watcher->data = decoder;
-
- ev_io_init(watcher, recv_data, s, EV_READ);
- ev_io_start(loop, watcher);
- }
-}
-
-
-void polled(struct ev_loop* loop, ev_io* watcher, int revents)
-{
- Promise<short>* promise = (Promise<short>*) watcher->data;
- promise->set(revents);
- delete promise;
-
- ev_io_stop(loop, watcher);
- delete watcher;
-}
-
-
-void* serve(void* arg)
-{
- ev_loop(((struct ev_loop*) arg), 0);
-
- return NULL;
-}
-
-
-void* schedule(void* arg)
-{
- do {
- ProcessBase* process = process_manager->dequeue();
- if (process == NULL) {
- Gate::state_t old = gate->approach();
- process = process_manager->dequeue();
- if (process == NULL) {
- gate->arrive(old); // Wait at gate if idle.
- continue;
- } else {
- gate->leave();
- }
- }
- process_manager->resume(process);
- } while (true);
-}
-
-
-// We might find value in catching terminating signals at some point.
-// However, for now, adding signal handlers freely is not allowed
-// because they will clash with Java and Python virtual machines and
-// causes hard to debug crashes/segfaults.
-
-// void sigbad(int signal, struct sigcontext *ctx)
-// {
-// // Pass on the signal (so that a core file is produced).
-// struct sigaction sa;
-// sa.sa_handler = SIG_DFL;
-// sigemptyset(&sa.sa_mask);
-// sa.sa_flags = 0;
-// sigaction(signal, &sa, NULL);
-// raise(signal);
-// }
-
-
-void initialize(const string& delegate)
-{
- // TODO(benh): Return an error if attempting to initialize again
- // with a different delegate then originally specified.
-
- // static pthread_once_t init = PTHREAD_ONCE_INIT;
- // pthread_once(&init, ...);
-
- static volatile bool initialized = false;
- static volatile bool initializing = true;
-
- // Try and do the initialization or wait for it to complete.
- if (initialized && !initializing) {
- return;
- } else if (initialized && initializing) {
- while (initializing);
- return;
- } else {
- if (!__sync_bool_compare_and_swap(&initialized, false, true)) {
- while (initializing);
- return;
- }
- }
-
-// // Install signal handler.
-// struct sigaction sa;
-
-// sa.sa_handler = (void (*) (int)) sigbad;
-// sigemptyset (&sa.sa_mask);
-// sa.sa_flags = SA_RESTART;
-
-// sigaction (SIGTERM, &sa, NULL);
-// sigaction (SIGINT, &sa, NULL);
-// sigaction (SIGQUIT, &sa, NULL);
-// sigaction (SIGSEGV, &sa, NULL);
-// sigaction (SIGILL, &sa, NULL);
-// #ifdef SIGBUS
-// sigaction (SIGBUS, &sa, NULL);
-// #endif
-// #ifdef SIGSTKFLT
-// sigaction (SIGSTKFLT, &sa, NULL);
-// #endif
-// sigaction (SIGABRT, &sa, NULL);
-
-// sigaction (SIGFPE, &sa, NULL);
-
-#ifdef __sun__
- /* Need to ignore this since we can't do MSG_NOSIGNAL on Solaris. */
- signal(SIGPIPE, SIG_IGN);
-#endif // __sun__
-
- // Create a new ProcessManager and SocketManager.
- process_manager = new ProcessManager(delegate);
- socket_manager = new SocketManager();
-
- // Setup processing threads.
- long cpus = std::max(4L, sysconf(_SC_NPROCESSORS_ONLN));
-
- for (int i = 0; i < cpus; i++) {
- pthread_t thread; // For now, not saving handles on our threads.
- if (pthread_create(&thread, NULL, schedule, NULL) != 0) {
- LOG(FATAL) << "Failed to initialize, pthread_create";
- }
- }
-
- __ip__ = 0;
- __port__ = 0;
-
- char* value;
-
- // Check environment for ip.
- value = getenv("LIBPROCESS_IP");
- if (value != NULL) {
- int result = inet_pton(AF_INET, value, &__ip__);
- if (result == 0) {
- LOG(FATAL) << "LIBPROCESS_IP=" << value << " was unparseable";
- } else if (result < 0) {
- PLOG(FATAL) << "Failed to initialize, inet_pton";
- }
- }
-
- // Check environment for port.
- value = getenv("LIBPROCESS_PORT");
- if (value != NULL) {
- int result = atoi(value);
- if (result < 0 || result > USHRT_MAX) {
- LOG(FATAL) << "LIBPROCESS_PORT=" << value << " is not a valid port";
- }
- __port__ = result;
- }
-
- // Create a "server" socket for communicating with other nodes.
- if ((__s__ = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- PLOG(FATAL) << "Failed to initialize, socket";
- }
-
- // Make socket non-blocking.
- Try<Nothing> nonblock = os::nonblock(__s__);
- if (nonblock.isError()) {
- LOG(FATAL) << "Failed to initialize, nonblock: " << nonblock.error();
- }
-
- // Set FD_CLOEXEC flag.
- Try<Nothing> cloexec = os::cloexec(__s__);
- if (cloexec.isError()) {
- LOG(FATAL) << "Failed to initialize, cloexec: " << cloexec.error();
- }
-
- // Allow address reuse.
- int on = 1;
- if (setsockopt(__s__, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
- PLOG(FATAL) << "Failed to initialize, setsockopt(SO_REUSEADDR)";
- }
-
- // Set up socket.
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = PF_INET;
- addr.sin_addr.s_addr = __ip__;
- addr.sin_port = htons(__port__);
-
- if (bind(__s__, (sockaddr*) &addr, sizeof(addr)) < 0) {
- PLOG(FATAL) << "Failed to initialize, bind";
- }
-
- // Lookup and store assigned ip and assigned port.
- socklen_t addrlen = sizeof(addr);
- if (getsockname(__s__, (sockaddr*) &addr, &addrlen) < 0) {
- PLOG(FATAL) << "Failed to initialize, getsockname";
- }
-
- __ip__ = addr.sin_addr.s_addr;
- __port__ = ntohs(addr.sin_port);
-
- // Lookup hostname if missing ip or if ip is 127.0.0.1 in case we
- // actually have a valid external ip address. Note that we need only
- // one ip address, so that other processes can send and receive and
- // don't get confused as to whom they are sending to.
- if (__ip__ == 0 || __ip__ == 2130706433) {
- char hostname[512];
-
- if (gethostname(hostname, sizeof(hostname)) < 0) {
- PLOG(FATAL) << "Ffailed to initialize, gethostname";
- }
-
- // Lookup IP address of local hostname.
- hostent* he;
-
- if ((he = gethostbyname2(hostname, AF_INET)) == NULL) {
- PLOG(FATAL) << "Failed to initialize, gethostbyname2";
- }
-
- __ip__ = *((uint32_t *) he->h_addr_list[0]);
- }
-
- if (listen(__s__, 500000) < 0) {
- PLOG(FATAL) << "Failed to initialize, listen";
- }
-
- // Setup event loop.
-#ifdef __sun__
- loop = ev_default_loop(EVBACKEND_POLL | EVBACKEND_SELECT);
-#else
- loop = ev_default_loop(EVFLAG_AUTO);
-#endif // __sun__
-
- ev_async_init(&async_watcher, handle_async);
- ev_async_start(loop, &async_watcher);
-
- ev_timer_init(&timeouts_watcher, handle_timeouts, 0., 2100000.0);
- ev_timer_again(loop, &timeouts_watcher);
-
- ev_io_init(&server_watcher, accept, __s__, EV_READ);
- ev_io_start(loop, &server_watcher);
-
-// ev_child_init(&child_watcher, child_exited, pid, 0);
-// ev_child_start(loop, &cw);
-
-// /* Install signal handler. */
-// struct sigaction sa;
-
-// sa.sa_handler = ev_sighandler;
-// sigfillset (&sa.sa_mask);
-// sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
-// sigaction (w->signum, &sa, 0);
-
-// sigemptyset (&sa.sa_mask);
-// sigaddset (&sa.sa_mask, w->signum);
-// sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
-
- pthread_t thread; // For now, not saving handles on our threads.
- if (pthread_create(&thread, NULL, serve, loop) != 0) {
- LOG(FATAL) << "Failed to initialize, pthread_create";
- }
-
- // Need to set initialzing here so that we can actually invoke
- // 'spawn' below for the garbage collector.
- initializing = false;
-
- // TODO(benh): Make sure creating the garbage collector, logging
- // process, and profiler always succeeds and use supervisors to make
- // sure that none terminate.
-
- // Create global garbage collector process.
- gc = spawn(new GarbageCollector());
-
- // Create the global logging process.
- spawn(new Logging(), true);
-
- // Create the global profiler process.
- spawn(new Profiler(), true);
-
- // Create the global statistics.
- // TODO(bmahler): Investigate memory implications of this window
- // size. We may also want to provide a maximum memory size rather than
- // time window. Or, offload older data to disk, etc.
- process::statistics = new Statistics(Weeks(2));
-
- // Initialize the mime types.
- mime::initialize();
-
- // Initialize the response statuses.
- http::initialize();
-
- char temp[INET_ADDRSTRLEN];
- if (inet_ntop(AF_INET, (in_addr*) &__ip__, temp, INET_ADDRSTRLEN) == NULL) {
- PLOG(FATAL) << "Failed to initialize, inet_ntop";
- }
-
- VLOG(1) << "libprocess is initialized on " << temp << ":" << __port__
- << " for " << cpus << " cpus";
-}
-
-
-uint32_t ip()
-{
- process::initialize();
- return __ip__;
-}
-
-
-uint16_t port()
-{
- process::initialize();
- return __port__;
-}
-
-
-HttpProxy::HttpProxy(const Socket& _socket)
- : ProcessBase(ID::generate("__http__")),
- socket(_socket) {}
-
-
-HttpProxy::~HttpProxy()
-{
- // Need to make sure response producers know not to continue to
- // create a response (streaming or otherwise).
- if (pipe.isSome()) {
- os::close(pipe.get());
- }
- pipe = None();
-
- while (!items.empty()) {
- Item* item = items.front();
-
- // Attempt to discard the future.
- item->future->discard();
-
- // But it might have already been ready ...
- if (item->future->isReady()) {
- const Response& response = item->future->get();
- if (response.type == Response::PIPE) {
- os::close(response.pipe);
- }
- }
-
- items.pop();
- delete item;
- }
-}
-
-
-void HttpProxy::enqueue(const Response& response, const Request& request)
-{
- handle(new Future<Response>(response), request);
-}
-
-
-void HttpProxy::handle(Future<Response>* future, const Request& request)
-{
- items.push(new Item(request, future));
-
- if (items.size() == 1) {
- next();
- }
-}
-
-
-void HttpProxy::next()
-{
- if (items.size() > 0) {
- // Wait for any transition of the future.
- items.front()->future->onAny(
- defer(self(), &HttpProxy::waited, lambda::_1));
- }
-}
-
-
-void HttpProxy::waited(const Future<Response>& future)
-{
- CHECK(items.size() > 0);
- Item* item = items.front();
-
- CHECK(future == *item->future);
-
- // Process the item and determine if we're done or not (so we know
- // whether to start waiting on the next responses).
- bool processed = process(*item->future, item->request);
-
- items.pop();
- delete item;
-
- if (processed) {
- next();
- }
-}
-
-
-bool HttpProxy::process(const Future<Response>& future, const Request& request)
-{
- if (!future.isReady()) {
- // TODO(benh): Consider handling other "states" of future
- // (discarded, failed, etc) with different HTTP statuses.
- socket_manager->send(ServiceUnavailable(), request, socket);
- return true; // All done, can process next response.
- }
-
- Response response = future.get();
-
- // If the response specifies a path, try and perform a sendfile.
- if (response.type == Response::PATH) {
- // Make sure no body is sent (this is really an error and
- // should be reported and no response sent.
- response.body.clear();
-
- const string& path = response.path;
- int fd = open(path.c_str(), O_RDONLY);
- if (fd < 0) {
- if (errno == ENOENT || errno == ENOTDIR) {
- VLOG(1) << "Returning '404 Not Found' for path '" << path << "'";
- socket_manager->send(NotFound(), request, socket);
- } else {
- const char* error = strerror(errno);
- VLOG(1) << "Failed to send file at '" << path << "': " << error;
- socket_manager->send(InternalServerError(), request, socket);
- }
- } else {
- struct stat s; // Need 'struct' because of function named 'stat'.
- if (fstat(fd, &s) != 0) {
- const char* error = strerror(errno);
- VLOG(1) << "Failed to send file at '" << path << "': " << error;
- socket_manager->send(InternalServerError(), request, socket);
- } else if (S_ISDIR(s.st_mode)) {
- VLOG(1) << "Returning '404 Not Found' for directory '" << path << "'";
- socket_manager->send(NotFound(), request, socket);
- } else {
- // While the user is expected to properly set a 'Content-Type'
- // header, we fill in (or overwrite) 'Content-Length' header.
- stringstream out;
- out << s.st_size;
- response.headers["Content-Length"] = out.str();
-
- if (s.st_size == 0) {
- socket_manager->send(response, request, socket);
- return true; // All done, can process next request.
- }
-
- VLOG(1) << "Sending file at '" << path << "' with length " << s.st_size;
-
- // TODO(benh): Consider a way to have the socket manager turn
- // on TCP_CORK for both sends and then turn it off.
- socket_manager->send(
- new HttpResponseEncoder(socket, response, request),
- true);
-
- // Note the file descriptor gets closed by FileEncoder.
- socket_manager->send(
- new FileEncoder(socket, fd, s.st_size),
- request.keepAlive);
- }
- }
- } else if (response.type == Response::PIPE) {
- // Make sure no body is sent (this is really an error and
- // should be reported and no response sent.
- response.body.clear();
-
- // Make sure the pipe is nonblocking.
- Try<Nothing> nonblock = os::nonblock(response.pipe);
- if (nonblock.isError()) {
- const char* error = strerror(errno);
- VLOG(1) << "Failed make pipe nonblocking: " << error;
- socket_manager->send(InternalServerError(), request, socket);
- return true; // All done, can process next response.
- }
-
- // While the user is expected to properly set a 'Content-Type'
- // header, we fill in (or overwrite) 'Transfer-Encoding' header.
- response.headers["Transfer-Encoding"] = "chunked";
-
- VLOG(1) << "Starting \"chunked\" streaming";
-
- socket_manager->send(
- new HttpResponseEncoder(socket, response, request),
- true);
-
- pipe = response.pipe;
-
- io::poll(pipe.get(), io::READ).onAny(
- defer(self(), &Self::stream, lambda::_1, request));
-
- return false; // Streaming, don't process next response (yet)!
- } else {
- socket_manager->send(response, request, socket);
- }
-
- return true; // All done, can process next response.
-}
-
-
-void HttpProxy::stream(const Future<short>& poll, const Request& request)
-{
- // TODO(benh): Use 'splice' on Linux.
-
- CHECK(pipe.isSome());
-
- bool finished = false; // Whether we're done streaming.
-
- if (poll.isReady()) {
- // Read and write.
- CHECK(poll.get() == io::READ);
- const size_t size = 4 * 1024; // 4K.
- char data[size];
- while (!finished) {
- ssize_t length = ::read(pipe.get(), data, size);
- if (length < 0 && (errno == EINTR)) {
- // Interrupted, try again now.
- continue;
- } else if (length < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
- // Might block, try again later.
- io::poll(pipe.get(), io::READ).onAny(
- defer(self(), &Self::stream, lambda::_1, request));
- break;
- } else {
- std::ostringstream out;
- if (length <= 0) {
- // Error or closed, treat both as closed.
- if (length < 0) {
- // Error.
- const char* error = strerror(errno);
- VLOG(1) << "Read error while streaming: " << error;
- }
- out << "0\r\n" << "\r\n";
- finished = true;
- } else {
- // Data!
- out << std::hex << length << "\r\n";
- out.write(data, length);
- out << "\r\n";
- }
-
- // We always persist the connection when we're not finished
- // streaming.
- socket_manager->send(
- new DataEncoder(socket, out.str()),
- finished ? request.keepAlive : true);
- }
- }
- } else if (poll.isFailed()) {
- VLOG(1) << "Failed to poll: " << poll.failure();
- socket_manager->send(InternalServerError(), request, socket);
- finished = true;
- } else {
- VLOG(1) << "Unexpected discarded future while polling";
- socket_manager->send(InternalServerError(), request, socket);
- finished = true;
- }
-
- if (finished) {
- os::close(pipe.get());
- pipe = None();
- next();
- }
-}
-
-
-SocketManager::SocketManager()
-{
- synchronizer(this) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
-}
-
-
-SocketManager::~SocketManager() {}
-
-
-Socket SocketManager::accepted(int s)
-{
- synchronized (this) {
- return sockets[s] = Socket(s);
- }
-}
-
-
-void SocketManager::link(ProcessBase* process, const UPID& to)
-{
- // TODO(benh): The semantics we want to support for link are such
- // that if there is nobody to link to (local or remote) then an
- // ExitedEvent gets generated. This functionality has only been
- // implemented when the link is local, not remote. Of course, if
- // there is nobody listening on the remote side, then this should
- // work remotely ... but if there is someone listening remotely just
- // not at that id, then it will silently continue executing.
-
- CHECK(process != NULL);
-
- Node node(to.ip, to.port);
-
- synchronized (this) {
- // Check if node is remote and there isn't a persistant link.
- if ((node.ip != __ip__ || node.port != __port__)
- && persists.count(node) == 0) {
- // Okay, no link, lets create a socket.
- int s;
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- PLOG(FATAL) << "Failed to link, socket";
- }
-
- Try<Nothing> nonblock = os::nonblock(s);
- if (nonblock.isError()) {
- LOG(FATAL) << "Failed to link, nonblock: " << nonblock.error();
- }
-
- Try<Nothing> cloexec = os::cloexec(s);
- if (cloexec.isError()) {
- LOG(FATAL) << "Failed to link, cloexec: " << cloexec.error();
- }
-
- sockets[s] = Socket(s);
- nodes[s] = node;
-
- persists[node] = s;
-
- // Allocate and initialize the decoder and watcher (we really
- // only "receive" on this socket so that we can react when it
- // gets closed and generate appropriate lost events).
- DataDecoder* decoder = new DataDecoder(sockets[s]);
-
- ev_io* watcher = new ev_io();
- watcher->data = decoder;
-
- // Try and connect to the node using this socket.
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = PF_INET;
- addr.sin_port = htons(to.port);
- addr.sin_addr.s_addr = to.ip;
-
- if (connect(s, (sockaddr*) &addr, sizeof(addr)) < 0) {
- if (errno != EINPROGRESS) {
- PLOG(FATAL) << "Failed to link, connect";
- }
-
- // Wait for socket to be connected.
- ev_io_init(watcher, receiving_connect, s, EV_WRITE);
- } else {
- ev_io_init(watcher, recv_data, s, EV_READ);
- }
-
- // Enqueue the watcher.
- synchronized (watchers) {
- watchers->push(watcher);
- }
-
- // Interrupt the loop.
- ev_async_send(loop, &async_watcher);
- }
-
- links[to].insert(process);
- }
-}
-
-
-PID<HttpProxy> SocketManager::proxy(const Socket& socket)
-{
- HttpProxy* proxy = NULL;
-
- synchronized (this) {
- // This socket might have been asked to get closed (e.g., remote
- // side hang up) while a process is attempting to handle an HTTP
- // request. Thus, if there is no more socket, return an empty PID.
- if (sockets.count(socket) > 0) {
- if (proxies.count(socket) > 0) {
- return proxies[socket]->self();
- } else {
- proxy = new HttpProxy(sockets[socket]);
- proxies[socket] = proxy;
- }
- }
- }
-
- // Now check if we need to spawn a newly created proxy. Note that we
- // need to do this outside of the synchronized block above to avoid
- // a possible deadlock (because spawn eventually synchronizes on
- // ProcessManager and ProcessManager::cleanup synchronizes on
- // ProcessManager and then SocketManager, so a deadlock results if
- // we do spawn within the synchronized block above).
- if (proxy != NULL) {
- return spawn(proxy, true);
- }
-
- return PID<HttpProxy>();
-}
-
-
-void SocketManager::send(Encoder* encoder, bool persist)
-{
- CHECK(encoder != NULL);
-
- synchronized (this) {
- if (sockets.count(encoder->socket()) > 0) {
- // Update whether or not this socket should get disposed after
- // there is no more data to send.
- if (!persist) {
- dispose.insert(encoder->socket());
- }
-
- if (outgoing.count(encoder->socket()) > 0) {
- outgoing[encoder->socket()].push(encoder);
- } else {
- // Initialize the outgoing queue.
- outgoing[encoder->socket()];
-
- // Allocate and initialize the watcher.
- ev_io* watcher = new ev_io();
- watcher->data = encoder;
-
- ev_io_init(watcher, encoder->sender(), encoder->socket(), EV_WRITE);
-
- synchronized (watchers) {
- watchers->push(watcher);
- }
-
- ev_async_send(loop, &async_watcher);
- }
- } else {
- VLOG(1) << "Attempting to send on a no longer valid socket!";
- delete encoder;
- }
- }
-}
-
-
-void SocketManager::send(
- const Response& response,
- const Request& request,
- const Socket& socket)
-{
- bool persist = request.keepAlive;
-
- // Don't persist the connection if the headers include
- // 'Connection: close'.
- if (response.headers.contains("Connection")) {
- if (response.headers.get("Connection").get() == "close") {
- persist = false;
- }
- }
-
- send(new HttpResponseEncoder(socket, response, request), persist);
-}
-
-
-void SocketManager::send(Message* message)
-{
- CHECK(message != NULL);
-
- Node node(message->to.ip, message->to.port);
-
- synchronized (this) {
- // Check if there is already a socket.
- bool persist = persists.count(node) > 0;
- bool temp = temps.count(node) > 0;
- if (persist || temp) {
- int s = persist ? persists[node] : temps[node];
- CHECK(sockets.count(s) > 0);
- send(new MessageEncoder(sockets[s], message), persist);
- } else {
- // No peristant or temporary socket to the node currently
- // exists, so we create a temporary one.
- int s;
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- PLOG(FATAL) << "Failed to send, socket";
- }
-
- Try<Nothing> nonblock = os::nonblock(s);
- if (nonblock.isError()) {
- LOG(FATAL) << "Failed to send, nonblock: " << nonblock.error();
- }
-
- Try<Nothing> cloexec = os::cloexec(s);
- if (cloexec.isError()) {
- LOG(FATAL) << "Failed to send, cloexec: " << cloexec.error();
- }
-
- sockets[s] = Socket(s);
- nodes[s] = node;
- temps[node] = s;
-
- dispose.insert(s);
-
- // Initialize the outgoing queue.
- outgoing[s];
-
- // Allocate and initialize the watcher.
- ev_io* watcher = new ev_io();
- watcher->data = new MessageEncoder(sockets[s], message);
-
- // Try and connect to the node using this socket.
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = PF_INET;
- addr.sin_port = htons(message->to.port);
- addr.sin_addr.s_addr = message->to.ip;
-
- if (connect(s, (sockaddr*) &addr, sizeof(addr)) < 0) {
- if (errno != EINPROGRESS) {
- PLOG(FATAL) << "Failed to send, connect";
- }
-
- // Initialize watcher for connecting.
- ev_io_init(watcher, sending_connect, s, EV_WRITE);
- } else {
- // Initialize watcher for sending.
- ev_io_init(watcher, send_data, s, EV_WRITE);
- }
-
- // Enqueue the watcher.
- synchronized (watchers) {
- watchers->push(watcher);
- }
-
- ev_async_send(loop, &async_watcher);
- }
- }
-}
-
-
-Encoder* SocketManager::next(int s)
-{
- HttpProxy* proxy = NULL; // Non-null if needs to be terminated.
-
- synchronized (this) {
- // We cannot assume 'sockets.count(s) > 0' here because it's
- // possible that 's' has been removed with a a call to
- // SocketManager::close. For example, it could be the case that a
- // socket has gone to CLOSE_WAIT and the call to 'recv' in
- // recv_data returned 0 causing SocketManager::close to get
- // invoked. Later a call to 'send' or 'sendfile' (e.g., in
- // send_data or send_file) can "succeed" (because the socket is
- // not "closed" yet because there are still some Socket
- // references, namely the reference being used in send_data or
- // send_file!). However, when SocketManger::next is actually
- // invoked we find out there there is no more data and thus stop
- // sending.
- // TODO(benh): Should we actually finish sending the data!?
- if (sockets.count(s) > 0) {
- CHECK(outgoing.count(s) > 0);
-
- if (!outgoing[s].empty()) {
- // More messages!
- Encoder* encoder = outgoing[s].front();
- outgoing[s].pop();
- return encoder;
- } else {
- // No more messages ... erase the outgoing queue.
- outgoing.erase(s);
-
- if (dispose.count(s) > 0) {
- // This is either a temporary socket we created or it's a
- // socket that we were receiving data from and possibly
- // sending HTTP responses back on. Clean up either way.
- if (nodes.count(s) > 0) {
- const Node& node = nodes[s];
- CHECK(temps.count(node) > 0 && temps[node] == s);
- temps.erase(node);
- nodes.erase(s);
- }
-
- if (proxies.count(s) > 0) {
- proxy = proxies[s];
- proxies.erase(s);
- }
-
- dispose.erase(s);
- sockets.erase(s);
-
- // We don't actually close the socket (we wait for the Socket
- // abstraction to close it once there are no more references),
- // but we do shutdown the receiving end so any DataDecoder
- // will get cleaned up (which might have the last reference).
- shutdown(s, SHUT_RD);
- }
- }
- }
- }
-
- // We terminate the proxy outside the synchronized block to avoid
- // possible deadlock between the ProcessManager and SocketManager
- // (see comment in SocketManager::proxy for more information).
- if (proxy != NULL) {
- terminate(proxy);
- }
-
- return NULL;
-}
-
-
-void SocketManager::close(int s)
-{
- HttpProxy* proxy = NULL; // Non-null if needs to be terminated.
-
- synchronized (this) {
- // This socket might not be active if it was already asked to get
- // closed (e.g., a write on the socket failed so we try and close
- // it and then later the read side of the socket gets closed so we
- // try and close it again). Thus, ignore the request if we don't
- // know about the socket.
- if (sockets.count(s) > 0) {
- // Clean up any remaining encoders for this socket.
- if (outgoing.count(s) > 0) {
- while (!outgoing[s].empty()) {
- Encoder* encoder = outgoing[s].front();
- delete encoder;
- outgoing[s].pop();
- }
-
- outgoing.erase(s);
- }
-
- // Clean up after sockets used for node communication.
- if (nodes.count(s) > 0) {
- const Node& node = nodes[s];
-
- // Don't bother invoking exited unless socket was persistant.
- if (persists.count(node) > 0 && persists[node] == s) {
- persists.erase(node);
- exited(node); // Generate ExitedEvent(s)!
- } else if (temps.count(node) > 0 && temps[node] == s) {
- temps.erase(node);
- }
-
- nodes.erase(s);
- }
-
- // Clean up any proxy associated with this socket.
- if (proxies.count(s) > 0) {
- proxy = proxies[s];
- proxies.erase(s);
- }
-
- dispose.erase(s);
- sockets.erase(s);
- }
- }
-
- // We terminate the proxy outside the synchronized block to avoid
- // possible deadlock between the ProcessManager and SocketManager.
- if (proxy != NULL) {
- terminate(proxy);
- }
-
- // Note that we don't actually:
- //
- // close(s);
- //
- // Because, for example, there could be a race between an HttpProxy
- // trying to do send a response with SocketManager::send() or a
- // process might be responding to another Request (e.g., trying
- // to do a sendfile) since these things may be happening
- // asynchronously we can't close the socket yet, because it might
- // get reused before any of the above things have finished, and then
- // we'll end up sending data on the wrong socket! Instead, we rely
- // on the last reference of our Socket object to close the
- // socket. Note, however, that since socket is no longer in
- // 'sockets' any attempt to send with it will just get ignored.
-}
-
-
-void SocketManager::exited(const Node& node)
-{
- // TODO(benh): It would be cleaner if this routine could call back
- // into ProcessManager ... then we wouldn't have to convince
- // ourselves that the accesses to each Process object will always be
- // valid.
- synchronized (this) {
- list<UPID> removed;
- // Look up all linked processes.
- foreachpair (const UPID& linkee, set<ProcessBase*>& processes, links) {
- if (linkee.ip == node.ip && linkee.port == node.port) {
- foreach (ProcessBase* linker, processes) {
- linker->enqueue(new ExitedEvent(linkee));
- }
- removed.push_back(linkee);
- }
- }
-
- foreach (const UPID& pid, removed) {
- links.erase(pid);
- }
- }
-}
-
-
-void SocketManager::exited(ProcessBase* process)
-{
- // An exited event is enough to cause the process to get deleted
- // (e.g., by the garbage collector), which means we can't
- // dereference process (or even use the address) after we enqueue at
- // least one exited event. Thus, we save the process pid.
- const UPID pid = process->pid;
-
- // Likewise, we need to save the current time of the process so we
- // can update the clocks of linked processes as appropriate.
- const Time time = Clock::now(process);
-
- synchronized (this) {
- // Iterate through the links, removing any links the process might
- // have had and creating exited events for any linked processes.
- foreachpair (const UPID& linkee, set<ProcessBase*>& processes, links) {
- processes.erase(process);
-
- if (linkee == pid) {
- foreach (ProcessBase* linker, processes) {
- CHECK(linker != process) << "Process linked with itself";
- synchronized (timeouts) {
- if (Clock::paused()) {
- Clock::update(linker, time);
- }
- }
- linker->enqueue(new ExitedEvent(linkee));
- }
- }
- }
-
- links.erase(pid);
- }
-}
-
-
-ProcessManager::ProcessManager(const string& _delegate)
- : delegate(_delegate)
-{
- synchronizer(processes) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
- synchronizer(runq) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
- running = 0;
- __sync_synchronize(); // Ensure write to 'running' visible in other threads.
-}
-
-
-ProcessManager::~ProcessManager() {}
-
-
-ProcessReference ProcessManager::use(const UPID& pid)
-{
- if (pid.ip == __ip__ && pid.port == __port__) {
- synchronized (processes) {
- if (processes.count(pid.id) > 0) {
- // Note that the ProcessReference constructor _must_ get
- // called while holding the lock on processes so that waiting
- // for references is atomic (i.e., race free).
- return ProcessReference(processes[pid.id]);
- }
- }
- }
-
- return ProcessReference(NULL);
-}
-
-
-bool ProcessManager::handle(
- const Socket& socket,
- Request* request)
-{
- CHECK(request != NULL);
-
- // Check if this is a libprocess request (i.e., 'User-Agent:
- // libprocess/id@ip:port') and if so, parse as a message.
- if (libprocess(request)) {
- Message* message = parse(request);
- if (message != NULL) {
- delete request;
- // TODO(benh): Use the sender PID in order to capture
- // happens-before timing relationships for testing.
- return deliver(message->to, new MessageEvent(message));
- }
-
- VLOG(1) << "Failed to handle libprocess request: "
- << request->method << " " << request->path
- << " (User-Agent: " << request->headers["User-Agent"] << ")";
-
- delete request;
- return false;
- }
-
- // Treat this as an HTTP request. Start by checking that the path
- // starts with a '/' (since the code below assumes as much).
- if (request->path.find('/') != 0) {
- VLOG(1) << "Returning '400 Bad Request' for '" << request->path << "'";
-
- // Get the HttpProxy pid for this socket.
- PID<HttpProxy> proxy = socket_manager->proxy(socket);
-
- // Enqueue the response with the HttpProxy so that it respects the
- // order of requests to account for HTTP/1.1 pipelining.
- dispatch(proxy, &HttpProxy::enqueue, BadRequest(), *request);
-
- // Cleanup request.
- delete request;
- return false;
- }
-
- // Ignore requests with relative paths (i.e., contain "/..").
- if (request->path.find("/..") != string::npos) {
- VLOG(1) << "Returning '404 Not Found' for '" << request->path
- << "' (ignoring requests with relative paths)";
-
- // Get the HttpProxy pid for this socket.
- PID<HttpProxy> proxy = socket_manager->proxy(socket);
-
- // Enqueue the response with the HttpProxy so that it respects the
- // order of requests to account for HTTP/1.1 pipelining.
- dispatch(proxy, &HttpProxy::enqueue, NotFound(), *request);
-
- // Cleanup request.
- delete request;
- return false;
- }
-
- // Split the path by '/'.
- vector<string> tokens = strings::tokenize(request->path, "/");
-
- // Try and determine a receiver, otherwise try and delegate.
- ProcessReference receiver;
-
- if (tokens.size() == 0 && delegate != "") {
- request->path = "/" + delegate;
- receiver = use(UPID(delegate, __ip__, __port__));
- } else if (tokens.size() > 0) {
- receiver = use(UPID(tokens[0], __ip__, __port__));
- }
-
- if (!receiver && delegate != "") {
- // Try and delegate the request.
- request->path = "/" + delegate + request->path;
- receiver = use(UPID(delegate, __ip__, __port__));
- }
-
- if (receiver) {
- // TODO(benh): Use the sender PID in order to capture
- // happens-before timing relationships for testing.
- return deliver(receiver, new HttpEvent(socket, request));
- }
-
- // This has no receiver, send error response.
- VLOG(1) << "Returning '404 Not Found' for '" << request->path << "'";
-
- // Get the HttpProxy pid for this socket.
- PID<HttpProxy> proxy = socket_manager->proxy(socket);
-
- // Enqueue the response with the HttpProxy so that it respects the
- // order of requests to account for HTTP/1.1 pipelining.
- dispatch(proxy, &HttpProxy::enqueue, NotFound(), *request);
-
- // Cleanup request.
- delete request;
- return false;
-}
-
-
-bool ProcessManager::deliver(
- ProcessBase* receiver,
- Event* event,
- ProcessBase* sender)
-{
- CHECK(event != NULL);
-
- // If we are using a manual clock then update the current time of
- // the receiver using the sender if necessary to preserve the
- // happens-before relationship between the sender and receiver. Note
- // that the assumption is that the sender remains valid for at least
- // the duration of this routine (so that we can look up it's current
- // time).
- if (Clock::paused()) {
- synchronized (timeouts) {
- if (Clock::paused()) {
- if (sender != NULL) {
- Clock::order(sender, receiver);
- } else {
- Clock::update(receiver, Clock::now());
- }
- }
- }
- }
-
- receiver->enqueue(event);
-
- return true;
-}
-
-bool ProcessManager::deliver(
- const UPID& to,
- Event* event,
- ProcessBase* sender)
-{
- CHECK(event != NULL);
-
- if (ProcessReference receiver = use(to)) {
- return deliver(receiver, event, sender);
- }
-
- delete event;
- return false;
-}
-
-
-UPID ProcessManager::spawn(ProcessBase* process, bool manage)
-{
- CHECK(process != NULL);
-
- synchronized (processes) {
- if (processes.count(process->pid.id) > 0) {
- return UPID();
- } else {
- processes[process->pid.id] = process;
- }
- }
-
- // Use the garbage collector if requested.
- if (manage) {
- dispatch(gc, &GarbageCollector::manage<ProcessBase>, process);
- }
-
- // We save the PID before enqueueing the process to avoid the race
- // condition that occurs when a user has a very short process and
- // the process gets run and cleaned up before we return from enqueue
- // (e.g., when 'manage' is set to true).
- UPID pid = process->self();
-
- // Add process to the run queue (so 'initialize' will get invoked).
- enqueue(process);
-
- VLOG(2) << "Spawned process " << pid;
-
- return pid;
-}
-
-
-void ProcessManager::resume(ProcessBase* process)
-{
- __process__ = process;
-
- VLOG(2) << "Resuming " << process->pid << " at " << Clock::now();
-
- bool terminate = false;
- bool blocked = false;
-
- CHECK(process->state == ProcessBase::BOTTOM ||
- process->state == ProcessBase::READY);
-
- if (process->state == ProcessBase::BOTTOM) {
- process->state = ProcessBase::RUNNING;
- try { process->initialize(); }
- catch (...) { terminate = true; }
- }
-
- while (!terminate && !blocked) {
- Event* event = NULL;
-
- process->lock();
- {
- if (process->events.size() > 0) {
- event = process->events.front();
- process->events.pop_front();
- process->state = ProcessBase::RUNNING;
- } else {
- process->state = ProcessBase::BLOCKED;
- blocked = true;
- }
- }
- process->unlock();
-
- if (!blocked) {
- CHECK(event != NULL);
-
- // Determine if we should filter this event.
- synchronized (filterer) {
- if (filterer != NULL) {
- bool filter = false;
- struct FilterVisitor : EventVisitor
- {
- FilterVisitor(bool* _filter) : filter(_filter) {}
-
- virtual void visit(const MessageEvent& event)
- {
- *filter = filterer->filter(event);
- }
-
- virtual void visit(const DispatchEvent& event)
- {
- *filter = filterer->filter(event);
- }
-
- virtual void visit(const HttpEvent& event)
- {
- *filter = filterer->filter(event);
- }
-
- virtual void visit(const ExitedEvent& event)
- {
- *filter = filterer->filter(event);
- }
-
- bool* filter;
- } visitor(&filter);
-
- event->visit(&visitor);
-
- if (filter) {
- delete event;
- continue; // Try and execute the next event.
- }
- }
- }
-
- // Determine if we should terminate.
- terminate = event->is<TerminateEvent>();
-
- // Now service the event.
- try {
- process->serve(*event);
- } catch (const std::exception& e) {
- std::cerr << "libprocess: " << process->pid
- << " terminating due to "
- << e.what() << std::endl;
- terminate = true;
- } catch (...) {
- std::cerr << "libprocess: " << process->pid
- << " terminating due to unknown exception" << std::endl;
- terminate = true;
- }
-
- delete event;
-
- if (terminate) {
- cleanup(process);
- }
- }
- }
-
- __process__ = NULL;
-
- CHECK_GE(running, 1);
- __sync_fetch_and_sub(&running, 1);
-}
-
-
-void ProcessManager::cleanup(ProcessBase* process)
-{
- VLOG(2) << "Cleaning up " << process->pid;
-
- // First, set the terminating state so no more events will get
- // enqueued and delete al the pending events. We want to delete the
- // events before we hold the processes lock because deleting an
- // event could cause code outside libprocess to get executed which
- // might cause a deadlock with the processes lock. Likewise,
- // deleting the events now rather than later has the nice property
- // of making sure that any events that might have gotten enqueued on
- // the process we are cleaning up will get dropped (since it's
- // terminating) and eliminates the potential of enqueueing them on
- // another process that gets spawned with the same PID.
- deque<Event*> events;
-
- process->lock();
- {
- process->state = ProcessBase::TERMINATING;
- events = process->events;
- process->events.clear();
- }
- process->unlock();
-
- // Delete pending events.
- while (!events.empty()) {
- Event* event = events.front();
- events.pop_front();
- delete event;
- }
-
- // Possible gate non-libprocess threads are waiting at.
- Gate* gate = NULL;
-
- // Remove process.
- synchronized (processes) {
- // Wait for all process references to get cleaned up.
- while (process->refs > 0) {
- asm ("pause");
- __sync_synchronize();
- }
-
- process->lock();
- {
- CHECK(process->events.empty());
-
- processes.erase(process->pid.id);
-
- // Lookup gate to wake up waiting threads.
- map<ProcessBase*, Gate*>::iterator it = gates.find(process);
- if (it != gates.end()) {
- gate = it->second;
- // N.B. The last thread that leaves the gate also free's it.
- gates.erase(it);
- }
-
- CHECK(process->refs == 0);
- process->state = ProcessBase::TERMINATED;
- }
- process->unlock();
-
- // Note that we don't remove the process from the clock during
- // cleanup, but rather the clock is reset for a process when it is
- // created (see ProcessBase::ProcessBase). We do this so that
- // SocketManager::exited can access the current time of the
- // process to "order" exited events. TODO(benh): It might make
- // sense to consider storing the time of the process as a field of
- // the class instead.
-
- // Now we tell the socket manager about this process exiting so
- // that it can create exited events for linked processes. We
- // _must_ do this while synchronized on processes because
- // otherwise another process could attempt to link this process
- // and SocketManger::link would see that the processes doesn't
- // exist when it attempts to get a ProcessReference (since we
- // removed the process above) thus causing an exited event, which
- // could cause the process to get deleted (e.g., the garbage
- // collector might link _after_ the process has already been
- // removed from processes thus getting an exited event but we
- // don't want that exited event to fire and actually delete the
- // process until after we have used the process in
- // SocketManager::exited).
- socket_manager->exited(process);
-
- // ***************************************************************
- // At this point we can no longer dereference the process since it
- // might already be deallocated (e.g., by the garbage collector).
- // ***************************************************************
-
- // Note that we need to open the gate while synchronized on
- // processes because otherwise we might _open_ the gate before
- // another thread _approaches_ the gate causing that thread to
- // wait on _arrival_ to the gate forever (see
- // ProcessManager::wait).
- if (gate != NULL) {
- gate->open();
- }
- }
-}
-
-
-void ProcessManager::link(ProcessBase* process, const UPID& to)
-{
- // Check if the pid is local.
- if (!(to.ip == __ip__ && to.port == __port__)) {
- socket_manager->link(process, to);
- } else {
- // Since the pid is local we want to get a reference to it's
- // underlying process so that while we are invoking the link
- // manager we don't miss sending a possible ExitedEvent.
- if (ProcessReference _ = use(to)) {
- socket_manager->link(process, to);
- } else {
- // Since the pid isn't valid it's process must have already died
- // (or hasn't been spawned yet) so send a process exit message.
- process->enqueue(new ExitedEvent(to));
- }
- }
-}
-
-
-void ProcessManager::terminate(
- const UPID& pid,
- bool inject,
- ProcessBase* sender)
-{
- if (ProcessReference process = use(pid)) {
- if (Clock::paused()) {
- synchronized (timeouts) {
- if (Clock::paused()) {
- if (sender != NULL) {
- Clock::order(sender, process);
- } else {
- Clock::update(process, Clock::now());
- }
- }
- }
- }
-
- if (sender != NULL) {
- process->enqueue(new TerminateEvent(sender->self()), inject);
- } else {
- process->enqueue(new TerminateEvent(UPID()), inject);
- }
- }
-}
-
-
-bool ProcessManager::wait(const UPID& pid)
-{
- // We use a gate for waiters. A gate is single use. That is, a new
- // gate is created when the first thread shows up and wants to wait
- // for a process that currently has no gate. Once that process
- // exits, the last thread to leave the gate will also clean it
- // up. Note that a gate will never get more threads waiting on it
- // after it has been opened, since the process should no longer be
- // valid and therefore will not have an entry in 'processes'.
-
- Gate* gate = NULL;
- Gate::state_t old;
-
- ProcessBase* process = NULL; // Set to non-null if we donate thread.
-
- // Try and approach the gate if necessary.
- synchronized (processes) {
- if (processes.count(pid.id) > 0) {
- process = processes[pid.id];
- CHECK(process->state != ProcessBase::TERMINATED);
-
- // Check and see if a gate already exists.
- if (gates.find(process) == gates.end()) {
- gates[process] = new Gate();
- }
-
- gate = gates[process];
- old = gate->approach();
-
- // Check if it is runnable in order to donate this thread.
- if (process->state == ProcessBase::BOTTOM ||
- process->state == ProcessBase::READY) {
- synchronized (runq) {
- list<ProcessBase*>::iterator it =
- find(runq.begin(), runq.end(), process);
- if (it != runq.end()) {
- runq.erase(it);
- } else {
- // Another thread has resumed the process ...
- process = NULL;
- }
- }
- } else {
- // Process is not runnable, so no need to donate ...
- process = NULL;
- }
- }
- }
-
- if (process != NULL) {
- VLOG(2) << "Donating thread to " << process->pid << " while waiting";
- ProcessBase* donator = __process__;
- __sync_fetch_and_add(&running, 1);
- process_manager->resume(process);
- __process__ = donator;
- }
-
- // TODO(benh): Donating only once may not be sufficient, so we might
- // still deadlock here ... perhaps warn if that's the case?
-
- // Now arrive at the gate and wait until it opens.
- if (gate != NULL) {
- gate->arrive(old);
-
- if (gate->empty()) {
- delete gate;
- }
-
- return true;
- }
-
- return false;
-}
-
-
-void ProcessManager::enqueue(ProcessBase* process)
-{
- CHECK(process != NULL);
-
- // TODO(benh): Check and see if this process has it's own thread. If
- // it does, push it on that threads runq, and wake up that thread if
- // it's not running. Otherwise, check and see which thread this
- // process was last running on, and put it on that threads runq.
-
- synchronized (runq) {
- CHECK(find(runq.begin(), runq.end(), process) == runq.end());
- runq.push_back(process);
- }
-
- // Wake up the processing thread if necessary.
- gate->open();
-}
-
-
-ProcessBase* ProcessManager::dequeue()
-{
- // TODO(benh): Remove a process from this thread's runq. If there
- // are no processes to run, and this is not a dedicated thread, then
- // steal one from another threads runq.
-
- ProcessBase* process = NULL;
-
- synchronized (runq) {
- if (!runq.empty()) {
- process = runq.front();
- runq.pop_front();
- // Increment the running count of processes in order to support
- // the Clock::settle() operation (this must be done atomically
- // with removing the process from the runq).
- __sync_fetch_and_add(&running, 1);
- }
- }
-
- return process;
-}
-
-
-void ProcessManager::settle()
-{
- bool done = true;
- do {
- os::sleep(Milliseconds(10));
- done = true;
- // Hopefully this is the only place we acquire both these locks.
- synchronized (runq) {
- synchronized (timeouts) {
- CHECK(Clock::paused()); // Since another thread could resume the clock!
-
- if (!runq.empty()) {
- done = false;
- }
-
- __sync_synchronize(); // Read barrier for 'running'.
- if (running > 0) {
- done = false;
- }
-
- if (timeouts->size() > 0 &&
- timeouts->begin()->first <= clock::current) {
- done = false;
- }
-
- if (pending_timers) {
- done = false;
- }
- }
- }
- } while (!done);
-}
-
-
-Timer Timer::create(
- const Duration& duration,
- const lambda::function<void(void)>& thunk)
-{
- static uint64_t id = 1; // Start at 1 since Timer() instances start with 0.
-
- // Assumes Clock::now() does Clock::now(__process__).
- Timeout timeout = Timeout::in(duration);
-
- UPID pid = __process__ != NULL ? __process__->self() : UPID();
-
- Timer timer(__sync_fetch_and_add(&id, 1), timeout, pid, thunk);
-
- VLOG(3) << "Created a timer for " << timeout.time();
-
- // Add the timer.
- synchronized (timeouts) {
- if (timeouts->size() == 0 ||
- timer.timeout().time() < timeouts->begin()->first) {
- // Need to interrupt the loop to update/set timer repeat.
- (*timeouts)[timer.timeout().time()].push_back(timer);
- update_timer = true;
- ev_async_send(loop, &async_watcher);
- } else {
- // Timer repeat is adequate, just add the timeout.
- CHECK(timeouts->size() >= 1);
- (*timeouts)[timer.timeout().time()].push_back(timer);
- }
- }
-
- return timer;
-}
-
-
-bool Timer::cancel(const Timer& timer)
-{
- bool canceled = false;
- synchronized (timeouts) {
- // Check if the timeout is still pending, and if so, erase it. In
- // addition, erase an empty list if we just removed the last
- // timeout.
- // TODO(benh): If two timers are created with the same timeout,
- // this will erase *both*. Fix this!
- Time time = timer.timeout().time();
- if (timeouts->count(time) > 0) {
- canceled = true;
- (*timeouts)[time].remove(timer);
- if ((*timeouts)[time].empty()) {
- timeouts->erase(time);
- }
- }
- }
-
- return canceled;
-}
-
-
-ProcessBase::ProcessBase(const string& id)
-{
- process::initialize();
-
- state = ProcessBase::BOTTOM;
-
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&m, &attr);
- pthread_mutexattr_destroy(&attr);
-
- refs = 0;
-
- pid.id = id != "" ? id : ID::generate();
- pid.ip = __ip__;
- pid.port = __port__;
-
- // If using a manual clock, try and set current time of process
- // using happens before relationship between creator and createe!
- if (Clock::paused()) {
- synchronized (timeouts) {
- if (Clock::paused()) {
- clock::currents->erase(this); // In case the address is reused!
- if (__process__ != NULL) {
- Clock::order(__process__, this);
- } else {
- Clock::update(this, Clock::now());
- }
- }
- }
- }
-}
-
-
-ProcessBase::~ProcessBase() {}
-
-
-void ProcessBase::enqueue(Event* event, bool inject)
-{
- CHECK(event != NULL);
-
- lock();
- {
- if (state != TERMINATING && state != TERMINATED) {
- if (!inject) {
- events.push_back(event);
- } else {
- events.push_front(event);
- }
-
- if (state == BLOCKED) {
- state = READY;
- process_manager->enqueue(this);
- }
-
- CHECK(state == BOTTOM ||
- state == READY ||
- state == RUNNING);
- } else {
- delete event;
- }
- }
- unlock();
-}
-
-
-void ProcessBase::inject(const UPID& from, const string& name, const char* data, size_t length)
-{
- if (!from)
- return;
-
- Message* message = encode(from, pid, name, string(data, length));
-
- enqueue(new MessageEvent(message), true);
-}
-
-
-void ProcessBase::send(const UPID& to, const string& name, const char* data, size_t length)
-{
- if (!to) {
- return;
- }
-
- // Encode and transport outgoing message.
- transport(encode(pid, to, name, string(data, length)), this);
-}
-
-
-void ProcessBase::visit(const MessageEvent& event)
-{
- if (handlers.message.count(event.message->name) > 0) {
- handlers.message[event.message->name](
- event.message->from,
- event.message->body);
- } else if (delegates.count(event.message->name) > 0) {
- VLOG(1) << "Delegating message '" << event.message->name
- << "' to " << delegates[event.message->name];
- Message* message = new Message(*event.message);
- message->to = delegates[event.message->name];
- transport(message, this);
- }
-}
-
-
-void ProcessBase::visit(const DispatchEvent& event)
-{
- (*event.f)(this);
-}
-
-
-void ProcessBase::visit(const HttpEvent& event)
-{
- VLOG(1) << "Handling HTTP event for process '" << pid.id << "'"
- << " with path: '" << event.request->path << "'";
-
- CHECK(event.request->path.find('/') == 0); // See ProcessManager::handle.
-
- // Split the path by '/'.
- vector<string> tokens = strings::tokenize(event.request->path, "/");
- CHECK(tokens.size() >= 1);
- CHECK(tokens[0] == pid.id);
-
- const string& name = tokens.size() > 1 ? tokens[1] : "";
-
- if (handlers.http.count(name) > 0) {
- // Create the promise to link with whatever gets returned, as well
- // as a future to wait for the response.
- std::tr1::shared_ptr<Promise<Response> > promise(
- new Promise<Response>());
-
- Future<Response>* future = new Future<Response>(promise->future());
-
- // Get the HttpProxy pid for this socket.
- PID<HttpProxy> proxy = socket_manager->proxy(event.socket);
-
- // Let the HttpProxy know about this request (via the future).
- dispatch(proxy, &HttpProxy::handle, future, *event.request);
-
- // Now call the handler and associate the response with the promise.
- promise->associate(handlers.http[name](*event.request));
- } else if (assets.count(name) > 0) {
- OK response;
- response.type = Response::PATH;
- response.path = assets[name].path;
-
- // Construct the final path by appending remaining tokens.
- for (int i = 2; i < tokens.size(); i++) {
- response.path += "/" + tokens[i];
- }
-
- // Try and determine the Content-Type from an extension.
- Try<string> basename = os::basename(response.path);
- if (!basename.isError()) {
- size_t index = basename.get().find_last_of('.');
- if (index != string::npos) {
- string extension = basename.get().substr(index);
- if (assets[name].types.count(extension) > 0) {
- response.headers["Content-Type"] = assets[name].types[extension];
- }
- }
- }
-
- // TODO(benh): Use "text/plain" for assets that don't have an
- // extension or we don't have a mapping for? It might be better to
- // just let the browser guess (or do it's own default).
-
- // Get the HttpProxy pid for this socket.
- PID<HttpProxy> proxy = socket_manager->proxy(event.socket);
-
- // Enqueue the response with the HttpProxy so that it respects the
- // order of requests to account for HTTP/1.1 pipelining.
- dispatch(proxy, &HttpProxy::enqueue, response, *event.request);
- } else {
- VLOG(1) << "Returning '404 Not Found' for '" << event.request->path << "'";
-
- // Get the HttpProxy pid for this socket.
- PID<HttpProxy> proxy = socket_manager->proxy(event.socket);
-
- // Enqueue the response with the HttpProxy so that it respects the
- // order of requests to account for HTTP/1.1 pipelining.
- dispatch(proxy, &HttpProxy::enqueue, NotFound(), *event.request);
- }
-}
-
-
-void ProcessBase::visit(const ExitedEvent& event)
-{
- exited(event.pid);
-}
-
-
-void ProcessBase::visit(const TerminateEvent& event)
-{
- finalize();
-}
-
-
-UPID ProcessBase::link(const UPID& to)
-{
- if (!to) {
- return to;
- }
-
- process_manager->link(this, to);
-
- return to;
-}
-
-
-UPID spawn(ProcessBase* process, bool manage)
-{
- process::initialize();
-
- if (process != NULL) {
- // If using a manual clock, try and set current time of process
- // using happens before relationship between spawner and spawnee!
- if (Clock::paused()) {
- synchronized (timeouts) {
- if (Clock::paused()) {
- if (__process__ != NULL) {
- Clock::order(__process__, process);
- } else {
- Clock::update(process, Clock::now());
- }
- }
- }
- }
-
- return process_manager->spawn(process, manage);
- } else {
- return UPID();
- }
-}
-
-
-void terminate(const UPID& pid, bool inject)
-{
- process_manager->terminate(pid, inject, __process__);
-}
-
-
-class WaitWaiter : public Process<WaitWaiter>
-{
-public:
- WaitWaiter(const UPID& _pid, const Duration& _duration, bool* _waited)
- : ProcessBase(ID::generate("__waiter__")),
- pid(_pid),
- duration(_duration),
- waited(_waited) {}
-
- virtual void initialize()
- {
- VLOG(3) << "Running waiter process for " << pid;
- link(pid);
- delay(duration, self(), &WaitWaiter::timeout);
- }
-
-private:
- virtual void exited(const UPID&)
- {
- VLOG(3) << "Waiter process waited for " << pid;
- *waited = true;
- terminate(self());
- }
-
- void timeout()
- {
- VLOG(3) << "Waiter process timed out waiting for " << pid;
- *waited = false;
- terminate(self());
- }
-
-private:
- const UPID pid;
- const Duration duration;
- bool* const waited;
-};
-
-
-bool wait(const UPID& pid, const Duration& duration)
-{
- process::initialize();
-
- if (!pid) {
- return false;
- }
-
- // This could result in a deadlock if some code decides to wait on a
- // process that has invoked that code!
- if (__process__ != NULL && __process__->self() == pid) {
- std::cerr << "\n**** DEADLOCK DETECTED! ****\nYou are waiting on process "
- << pid << " that it is currently executing." << std::endl;
- }
-
- if (duration == Seconds(-1)) {
- return process_manager->wait(pid);
- }
-
- bool waited = false;
-
- WaitWaiter waiter(pid, duration, &waited);
- spawn(waiter);
- wait(waiter);
-
- return waited;
-}
-
-
-void filter(Filter *filter)
-{
- process::initialize();
-
- synchronized (filterer) {
- filterer
<TRUNCATED>
[06/35] Updated libprocess to use '3rdparty' instead of 'third_party'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/format.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/format.hpp b/third_party/libprocess/3rdparty/stout/include/stout/format.hpp
new file mode 100644
index 0000000..71b5986
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/format.hpp
@@ -0,0 +1,343 @@
+#ifndef __STOUT_FORMAT_HPP__
+#define __STOUT_FORMAT_HPP__
+
+#include <stdarg.h> // For 'va_list', 'va_start', 'va_end'.
+#include <stdio.h> // For 'vasprintf'.
+
+#include <string>
+
+#include <tr1/type_traits> // For 'is_pod'.
+
+#include "error.hpp"
+#include "try.hpp"
+#include "stringify.hpp"
+
+
+// The 'strings::format' functions produces strings based on the
+// printf family of functions. Except, unlike the printf family of
+// functions, the 'strings::format' routines attempt to "stringify"
+// any arguments that are not POD types (i.e., "plain old data":
+// primitives, pointers, certain structs/classes and unions,
+// etc). This enables passing structs/classes to 'strings::format'
+// provided there is a definition/specialization of 'ostream::operator
+// <<' available for that type. Note that the '%s' format specifier is
+// expected for each argument that gets stringified. A specialization
+// for std::string is also provided so that std::string::c_str is not
+// necessary (but again, '%s' is expected as the format specifier).
+
+namespace strings {
+namespace internal {
+
+Try<std::string> format(const std::string& fmt, va_list args);
+Try<std::string> format(const std::string& fmt, ...);
+
+template <typename T, bool b>
+struct stringify;
+
+} // namespace internal {
+
+
+#if __cplusplus >= 201103L
+template <typename ...T>
+Try<std::string> format(const std::string& s, const T& ...t)
+{
+ return internal::format(
+ s,
+ internal::stringify<T, !std::is_pod<T>::value>(t).get()...);
+}
+#else
+template <typename T1>
+Try<std::string> format(const std::string& s,
+ const T1& t1)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get());
+}
+
+
+template <typename T1,
+ typename T2>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T1>::value>(t2).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6,
+ typename T7>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6,
+ const T7& t7)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
+ internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6,
+ typename T7,
+ typename T8>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6,
+ const T7& t7,
+ const T8& t8)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
+ internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
+ internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6,
+ typename T7,
+ typename T8,
+ typename T9>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6,
+ const T7& t7,
+ const T8& t8,
+ const T9& t9)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
+ internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
+ internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get(),
+ internal::stringify<T9, !std::tr1::is_pod<T9>::value>(t9).get());
+}
+
+
+template <typename T1,
+ typename T2,
+ typename T3,
+ typename T4,
+ typename T5,
+ typename T6,
+ typename T7,
+ typename T8,
+ typename T9,
+ typename T10>
+Try<std::string> format(const std::string& s,
+ const T1& t1,
+ const T2& t2,
+ const T3& t3,
+ const T4& t4,
+ const T5& t5,
+ const T6& t6,
+ const T7& t7,
+ const T8& t8,
+ const T9& t9,
+ const T10& t10)
+{
+ return internal::format(
+ s,
+ internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
+ internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
+ internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
+ internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
+ internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
+ internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
+ internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
+ internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get(),
+ internal::stringify<T9, !std::tr1::is_pod<T9>::value>(t9).get(),
+ internal::stringify<T10, !std::tr1::is_pod<T10>::value>(t10).get());
+}
+#endif // __cplusplus >= 201103L
+
+
+namespace internal {
+
+inline Try<std::string> format(const std::string& fmt, va_list args)
+{
+ char* temp;
+ if (vasprintf(&temp, fmt.c_str(), args) == -1) {
+ // Note that temp is undefined, so we do not need to call free.
+ return Error("Failed to format '" + fmt + "' (possibly out of memory)");
+ }
+ std::string result(temp);
+ free(temp);
+ return result;
+}
+
+
+inline Try<std::string> format(const std::string& fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ const Try<std::string>& result = format(fmt, args);
+ va_end(args);
+ return result;
+}
+
+
+template <typename T>
+struct stringify<T, false>
+{
+ stringify(const T& _t) : t(_t) {}
+ const T& get() { return t; }
+ const T& t;
+};
+
+
+template <typename T>
+struct stringify<T, true>
+{
+ stringify(const T& _t) : s(::stringify(_t)) {}
+ const char* get() { return s.c_str(); }
+
+ // NOTE: We need to do the copy here, because the temporary returned by
+ // ::stringify() doesn't outlive the get() call inside strings::format().
+ // TODO(vinod): Figure out a fix for using const ref here.
+ const std::string s;
+};
+
+
+template <>
+struct stringify<std::string, true>
+{
+ stringify(const std::string& _s) : s(_s) {}
+ const char* get() { return s.c_str(); }
+ const std::string& s;
+};
+
+} // namespace internal {
+} // namespace strings {
+
+#endif // __STOUT_FORMAT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/fs.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/fs.hpp b/third_party/libprocess/3rdparty/stout/include/stout/fs.hpp
new file mode 100644
index 0000000..c1a05b5
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/fs.hpp
@@ -0,0 +1,53 @@
+#ifndef __STOUT_FS_HPP__
+#define __STOUT_FS_HPP__
+
+#include <unistd.h> // For symlink.
+
+#include <sys/statvfs.h>
+
+#include <string>
+
+#include "bytes.hpp"
+#include "error.hpp"
+#include "nothing.hpp"
+#include "try.hpp"
+
+// TODO(bmahler): Migrate the appropriate 'os' namespace funtions here.
+namespace fs {
+
+// Returns the total available disk size in bytes.
+inline Try<Bytes> available(const std::string& path = "/")
+{
+ struct statvfs buf;
+ if (::statvfs(path.c_str(), &buf) < 0) {
+ return ErrnoError();
+ }
+ return Bytes(buf.f_bavail * buf.f_frsize);
+}
+
+
+// Returns relative disk usage of the file system that the given path
+// is mounted at.
+inline Try<double> usage(const std::string& path = "/")
+{
+ struct statvfs buf;
+ if (statvfs(path.c_str(), &buf) < 0) {
+ return ErrnoError("Error invoking statvfs on '" + path + "'");
+ }
+ return (double) (buf.f_blocks - buf.f_bfree) / buf.f_blocks;
+}
+
+
+inline Try<Nothing> symlink(
+ const std::string& original,
+ const std::string& link)
+{
+ if (::symlink(original.c_str(), link.c_str()) < 0) {
+ return ErrnoError();
+ }
+ return Nothing();
+}
+
+} // namespace fs {
+
+#endif // __STOUT_FS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/gtest.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/gtest.hpp b/third_party/libprocess/3rdparty/stout/include/stout/gtest.hpp
new file mode 100644
index 0000000..3c34124
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/gtest.hpp
@@ -0,0 +1,122 @@
+#ifndef __STOUT_GTEST_HPP__
+#define __STOUT_GTEST_HPP__
+
+#include <gtest/gtest.h>
+
+#include <string>
+
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+#include <stout/try.hpp>
+
+
+template <typename T>
+::testing::AssertionResult AssertSome(
+ const char* expr,
+ const Option<T>& actual)
+{
+ if (actual.isNone()) {
+ return ::testing::AssertionFailure()
+ << expr << " is NONE";
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T>
+::testing::AssertionResult AssertSome(
+ const char* expr,
+ const Try<T>& actual)
+{
+ if (actual.isError()) {
+ return ::testing::AssertionFailure()
+ << expr << ": " << actual.error();
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T>
+::testing::AssertionResult AssertSome(
+ const char* expr,
+ const Result<T>& actual)
+{
+ if (actual.isNone()) {
+ return ::testing::AssertionFailure()
+ << expr << " is NONE";
+ } else if (actual.isError()) {
+ return ::testing::AssertionFailure()
+ << expr << ": " << actual.error();
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T1, typename T2>
+::testing::AssertionResult AssertSomeEq(
+ const char* expectedExpr,
+ const char* actualExpr,
+ const T1& expected,
+ const T2& actual) // Duck typing!
+{
+ const ::testing::AssertionResult result = AssertSome(actualExpr, actual);
+
+ if (result) {
+ if (expected == actual.get()) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Value of: (" << actualExpr << ").get()\n"
+ << " Actual: " << ::testing::PrintToString(actual.get()) << "\n"
+ << "Expected: " << expectedExpr << "\n"
+ << "Which is: " << ::testing::PrintToString(expected);
+ }
+ }
+
+ return result;
+}
+
+
+#define ASSERT_SOME(actual) \
+ ASSERT_PRED_FORMAT1(AssertSome, actual)
+
+
+#define EXPECT_SOME(actual) \
+ EXPECT_PRED_FORMAT1(AssertSome, actual)
+
+
+#define ASSERT_SOME_EQ(expected, actual) \
+ ASSERT_PRED_FORMAT2(AssertSomeEq, expected, actual)
+
+
+#define EXPECT_SOME_EQ(expected, actual) \
+ EXPECT_PRED_FORMAT2(AssertSomeEq, expected, actual)
+
+
+#define ASSERT_SOME_TRUE(actual) \
+ ASSERT_PRED_FORMAT2(AssertSomeEq, true, actual)
+
+
+#define EXPECT_SOME_TRUE(actual) \
+ EXPECT_PRED_FORMAT2(AssertSomeEq, true, actual)
+
+
+#define ASSERT_SOME_FALSE(actual) \
+ ASSERT_PRED_FORMAT2(AssertSomeEq, false, actual)
+
+
+#define EXPECT_SOME_FALSE(actual) \
+ EXPECT_PRED_FORMAT2(AssertSomeEq, false, actual)
+
+
+#define ASSERT_ERROR(actual) \
+ ASSERT_TRUE(actual.isError())
+
+
+#define EXPECT_ERROR(actual) \
+ EXPECT_TRUE(actual.isError())
+
+#endif // __STOUT_GTEST_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/gzip.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/gzip.hpp b/third_party/libprocess/3rdparty/stout/include/stout/gzip.hpp
new file mode 100644
index 0000000..ef36f1b
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/gzip.hpp
@@ -0,0 +1,149 @@
+#ifndef __STOUT_GZIP_HPP__
+#define __STOUT_GZIP_HPP__
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include <string>
+
+#include "error.hpp"
+#include "try.hpp"
+
+// Compression utilities.
+// TODO(bmahler): Provide streaming compression / decompression as well.
+namespace gzip {
+
+// We use a 16KB buffer with zlib compression / decompression.
+#define GZIP_BUFFER_SIZE 16384
+
+// Returns a gzip compressed version of the provided string.
+// The compression level should be within the range [-1, 9].
+// See zlib.h:
+// #define Z_NO_COMPRESSION 0
+// #define Z_BEST_SPEED 1
+// #define Z_BEST_COMPRESSION 9
+// #define Z_DEFAULT_COMPRESSION (-1)
+inline Try<std::string> compress(
+ const std::string& decompressed,
+#ifdef HAVE_LIBZ
+ int level = Z_DEFAULT_COMPRESSION)
+#else
+ int level = -1)
+#endif
+{
+#ifndef HAVE_LIBZ
+ return Error("libz is not available");
+#else
+ // Verify the level is within range.
+ if (!(level == Z_DEFAULT_COMPRESSION ||
+ (level >= Z_NO_COMPRESSION && level <= Z_BEST_COMPRESSION))) {
+ return Error("Invalid compression level: " + level);
+ }
+
+ z_stream_s stream;
+ stream.next_in =
+ const_cast<Bytef*>(reinterpret_cast<const Bytef*>(decompressed.data()));
+ stream.avail_in = decompressed.length();
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ int code = deflateInit2(
+ &stream,
+ level, // Compression level.
+ Z_DEFLATED, // Compression method.
+ MAX_WBITS + 16, // Zlib magic for gzip compression / decompression.
+ 8, // Default memLevel value.
+ Z_DEFAULT_STRATEGY);
+
+ if (code != Z_OK) {
+ return Error("Failed to initialize zlib: " + std::string(stream.msg));
+ }
+
+ // Build up the compressed result.
+ Bytef buffer[GZIP_BUFFER_SIZE];
+ std::string result = "";
+ do {
+ stream.next_out = buffer;
+ stream.avail_out = GZIP_BUFFER_SIZE;
+ code = deflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+ if (code != Z_OK && code != Z_STREAM_END) {
+ Error error(std::string(stream.msg));
+ deflateEnd(&stream);
+ return error;
+ }
+
+ // Consume output and reset the buffer.
+ result.append(
+ reinterpret_cast<char*>(buffer),
+ GZIP_BUFFER_SIZE - stream.avail_out);
+ stream.next_out = buffer;
+ stream.avail_out = GZIP_BUFFER_SIZE;
+ } while (code != Z_STREAM_END);
+
+ code = deflateEnd(&stream);
+ if (code != Z_OK) {
+ return Error("Failed to clean up zlib: " + std::string(stream.msg));
+ }
+ return result;
+#endif // HAVE_LIBZ
+}
+
+
+// Returns a gzip decompressed version of the provided string.
+inline Try<std::string> decompress(const std::string& compressed)
+{
+#ifndef HAVE_LIBZ
+ return Error("libz is not available");
+#else
+ z_stream_s stream;
+ stream.next_in =
+ const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
+ stream.avail_in = compressed.length();
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ int code = inflateInit2(
+ &stream,
+ MAX_WBITS + 16); // Zlib magic for gzip compression / decompression.
+
+ if (code != Z_OK) {
+ return Error("Failed to initialize zlib: " + std::string(stream.msg));
+ }
+
+ // Build up the decompressed result.
+ Bytef buffer[GZIP_BUFFER_SIZE];
+ std::string result = "";
+ do {
+ stream.next_out = buffer;
+ stream.avail_out = GZIP_BUFFER_SIZE;
+ code = inflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+ if (code != Z_OK && code != Z_STREAM_END) {
+ Error error(std::string(stream.msg));
+ inflateEnd(&stream);
+ return error;
+ }
+
+ // Consume output and reset the buffer.
+ result.append(
+ reinterpret_cast<char*>(buffer),
+ GZIP_BUFFER_SIZE - stream.avail_out);
+ stream.next_out = buffer;
+ stream.avail_out = GZIP_BUFFER_SIZE;
+ } while (code != Z_STREAM_END);
+
+ code = inflateEnd(&stream);
+ if (code != Z_OK) {
+ return Error("Failed to clean up zlib: " + std::string(stream.msg));
+ }
+ return result;
+#endif // HAVE_LIBZ
+}
+
+} // namespace gzip {
+
+#endif // __STOUT_GZIP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/hashmap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/hashmap.hpp b/third_party/libprocess/3rdparty/stout/include/stout/hashmap.hpp
new file mode 100644
index 0000000..796cb50
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/hashmap.hpp
@@ -0,0 +1,102 @@
+#ifndef __STOUT_HASHMAP_HPP__
+#define __STOUT_HASHMAP_HPP__
+
+#include <boost/get_pointer.hpp>
+#include <boost/unordered_map.hpp>
+
+#include "hashset.hpp"
+#include "foreach.hpp"
+#include "none.hpp"
+#include "option.hpp"
+
+
+// Provides a hash map via Boost's 'unordered_map'. For most intensive
+// purposes this could be accomplished with a templated typedef, but
+// those don't exist (until C++-11). Also, doing it this way allows us
+// to add functionality, or better naming of existing functionality,
+// etc.
+
+template <typename Key, typename Value>
+class hashmap : public boost::unordered_map<Key, Value>
+{
+public:
+ // An explicit default constructor is needed so
+ // 'const hashmap<T> map;' is not an error.
+ hashmap() {}
+
+ // Checks whether this map contains a binding for a key.
+ bool contains(const Key& key) const
+ {
+ return boost::unordered_map<Key, Value>::count(key) > 0;
+ }
+
+ // Checks whether there exists a bound value in this map.
+ bool containsValue(const Value& v) const
+ {
+ foreachvalue (const Value& value, *this) {
+ if (value == v) {
+ return true;
+ }
+ }
+ }
+
+ // Returns an Option for the binding to the key.
+ Option<Value> get(const Key& key) const
+ {
+ typedef typename boost::unordered_map<Key, Value>::const_iterator
+ const_iterator;
+ const_iterator it = boost::unordered_map<Key, Value>::find(key);
+ if (it == boost::unordered_map<Key, Value>::end()) {
+ return None();
+ }
+ return it->second;
+ }
+
+ // Returns the set of keys in this map.
+ hashset<Key> keys() const
+ {
+ hashset<Key> result;
+ foreachkey (const Key& key, *this) {
+ result.insert(key);
+ }
+ return result;
+ }
+
+ // Returns the set of values in this map.
+ hashset<Value> values() const
+ {
+ hashset<Value> result;
+ foreachvalue (const Value& value, *this) {
+ result.insert(value);
+ }
+ return result;
+ }
+
+ // Checks whether there exists a value in this map that returns the
+ // a result equal to 'r' when the specified method is invoked.
+ template <typename R, typename T>
+ bool existsValue(R (T::*method)(), R r) const
+ {
+ foreachvalue (const Value& value, *this) {
+ const T* t = boost::get_pointer(value);
+ if (t->*method() == r) {
+ return true;
+ }
+ }
+ }
+
+ // Checks whether there exists a value in this map whose specified
+ // member is equal to 'r'.
+ template <typename R, typename T>
+ bool existsValue(R (T::*member), R r) const
+ {
+ foreachvalue (const Value& value, *this) {
+ const T* t = boost::get_pointer(value);
+ if (t->*member == r) {
+ return true;
+ }
+ }
+ }
+};
+
+#endif // __STOUT_HASHMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/hashset.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/hashset.hpp b/third_party/libprocess/3rdparty/stout/include/stout/hashset.hpp
new file mode 100644
index 0000000..f584545
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/hashset.hpp
@@ -0,0 +1,57 @@
+#ifndef __STOUT_HASHSET_HPP__
+#define __STOUT_HASHSET_HPP__
+
+#include <boost/get_pointer.hpp>
+#include <boost/unordered_set.hpp>
+
+#include "foreach.hpp"
+
+
+// Provides a hash set via Boost's 'unordered_set'. For most intensive
+// purposes this could be accomplished with a templated typedef, but
+// those don't exist (until C++-11). Also, doing it this way allows us
+// to add functionality, or better naming of existing functionality,
+// etc.
+
+template <typename Elem>
+class hashset : public boost::unordered_set<Elem>
+{
+public:
+ // An explicit default constructor is needed so
+ // 'const hashset<T> map;' is not an error.
+ hashset() {}
+
+ // Checks whether this map contains a binding for a key.
+ bool contains(const Elem& elem) const
+ {
+ return boost::unordered_set<Elem>::count(elem) > 0;
+ }
+
+ // Checks whether there exists a value in this set that returns the
+ // a result equal to 'r' when the specified method is invoked.
+ template <typename R, typename T>
+ bool exists(R (T::*method)(), R r) const
+ {
+ foreach (const Elem& elem, *this) {
+ const T* t = boost::get_pointer(elem);
+ if (t->*method() == r) {
+ return true;
+ }
+ }
+ }
+
+ // Checks whether there exists an element in this set whose
+ // specified member is equal to 'r'.
+ template <typename R, typename T>
+ bool exists(R (T::*member), R r) const
+ {
+ foreach (const Elem& elem, *this) {
+ const T* t = boost::get_pointer(elem);
+ if (t->*member == r) {
+ return true;
+ }
+ }
+ }
+};
+
+#endif // __STOUT_HASHSET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/json.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/json.hpp b/third_party/libprocess/3rdparty/stout/include/stout/json.hpp
new file mode 100644
index 0000000..e2cd4f2
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/json.hpp
@@ -0,0 +1,202 @@
+#ifndef __STOUT_JSON__
+#define __STOUT_JSON__
+
+#include <iomanip>
+#include <iostream>
+#include <list>
+#include <map>
+#include <string>
+
+#include <boost/variant.hpp>
+
+#include <stout/foreach.hpp>
+
+// TODO(jsirois): Implement parsing that constructs JSON objects.
+
+
+namespace JSON {
+
+// Implementation of the JavaScript Object Notation (JSON) grammar
+// using boost::variant. We explicitly define each "type" of the
+// grammar, including 'true' (json::True), 'false' (json::False), and
+// 'null' (json::Null), for clarity and also because boost::variant
+// "picks" the wrong type when we try and use std::string, long (or
+// int), double (or float), and bool all in the same variant (while it
+// does work with explicit casts, it seemed bad style to force people
+// to put those casts in place). We could have avoided using
+// json::String or json::Number and just used std::string and double
+// respectively, but we choose to include them for completeness
+// (although, this does pay a 2x cost when compiling thanks to all the
+// extra template instantiations).
+
+struct String;
+struct Number;
+struct Object;
+struct Array;
+struct True;
+struct False;
+struct Null;
+
+
+typedef boost::variant<boost::recursive_wrapper<String>,
+ boost::recursive_wrapper<Number>,
+ boost::recursive_wrapper<Object>,
+ boost::recursive_wrapper<Array>,
+ boost::recursive_wrapper<True>,
+ boost::recursive_wrapper<False>,
+ boost::recursive_wrapper<Null> > Value;
+
+
+struct String
+{
+ String() {}
+ String(const char* _value) : value(_value) {}
+ String(const std::string& _value) : value(_value) {}
+ std::string value;
+};
+
+
+struct Number
+{
+ Number() {}
+ Number(double _value) : value(_value) {}
+ double value;
+};
+
+
+struct Object
+{
+ std::map<std::string, Value> values;
+};
+
+
+struct Array
+{
+ std::list<Value> values;
+};
+
+
+struct True {};
+
+
+struct False {};
+
+
+struct Null {};
+
+
+// Implementation of rendering JSON objects built above using standard
+// C++ output streams. The visitor pattern is used thanks to to build
+// a "renderer" with boost::static_visitor and two top-level render
+// routines are provided for rendering JSON objects and arrays.
+
+struct Renderer : boost::static_visitor<>
+{
+ Renderer(std::ostream& _out) : out(_out) {}
+
+ void operator () (const String& string) const
+ {
+ // TODO(benh): This escaping DOES NOT handle unicode, it encodes as ASCII.
+ // See RFC4627 for the JSON string specificiation.
+ out << "\"";
+ foreach (unsigned char c, string.value) {
+ switch (c) {
+ case '"': out << "\\\""; break;
+ case '\\': out << "\\\\"; break;
+ case '/': out << "\\/"; break;
+ case '\b': out << "\\b"; break;
+ case '\f': out << "\\f"; break;
+ case '\n': out << "\\n"; break;
+ case '\r': out << "\\r"; break;
+ case '\t': out << "\\t"; break;
+ default:
+ // See RFC4627 for these ranges.
+ if ((c >= 0x20 && c <= 0x21) ||
+ (c >= 0x23 && c <= 0x5B) ||
+ (c >= 0x5D && c < 0x7F)) {
+ out << c;
+ } else {
+ // NOTE: We also escape all bytes > 0x7F since they imply more than
+ // 1 byte in UTF-8. This is why we don't escape UTF-8 properly.
+ // See RFC4627 for the escaping format: \uXXXX (X is a hex digit).
+ // Each byte here will be of the form: \u00XX (this is why we need
+ // setw and the cast to unsigned int).
+ out << "\\u" << std::setfill('0') << std::setw(4)
+ << std::hex << std::uppercase << (unsigned int) c;
+ }
+ break;
+ }
+ }
+ out << "\"";
+ }
+
+ void operator () (const Number& number) const
+ {
+ out.precision(10);
+ out << number.value;
+ }
+
+ void operator () (const Object& object) const
+ {
+ out << "{";
+ std::map<std::string, Value>::const_iterator iterator;
+ iterator = object.values.begin();
+ while (iterator != object.values.end()) {
+ out << "\"" << (*iterator).first << "\":";
+ boost::apply_visitor(Renderer(out), (*iterator).second);
+ if (++iterator != object.values.end()) {
+ out << ",";
+ }
+ }
+ out << "}";
+ }
+
+ void operator () (const Array& array) const
+ {
+ out << "[";
+ std::list<Value>::const_iterator iterator;
+ iterator = array.values.begin();
+ while (iterator != array.values.end()) {
+ boost::apply_visitor(Renderer(out), *iterator);
+ if (++iterator != array.values.end()) {
+ out << ",";
+ }
+ }
+ out << "]";
+ }
+
+ void operator () (const True&) const
+ {
+ out << "true";
+ }
+
+ void operator () (const False&) const
+ {
+ out << "false";
+ }
+
+ void operator () (const Null&) const
+ {
+ out << "null";
+ }
+
+private:
+ std::ostream& out;
+};
+
+
+inline void render(std::ostream& out, const Value& value)
+{
+ boost::apply_visitor(Renderer(out), value);
+}
+
+
+inline std::ostream& operator<<(std::ostream& out, const JSON::Value& value)
+{
+ JSON::render(out, value);
+ return out;
+}
+
+} // namespace JSON {
+
+#endif // __STOUT_JSON__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/lambda.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/lambda.hpp b/third_party/libprocess/3rdparty/stout/include/stout/lambda.hpp
new file mode 100644
index 0000000..d493353
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/lambda.hpp
@@ -0,0 +1,14 @@
+#ifndef __STOUT_LAMBDA_HPP__
+#define __STOUT_LAMBDA_HPP__
+
+#include <tr1/functional>
+
+namespace lambda {
+
+using std::tr1::bind;
+using std::tr1::function;
+using namespace std::tr1::placeholders;
+
+} // namespace lambda {
+
+#endif // __STOUT_LAMBDA_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/multihashmap.hpp b/third_party/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
new file mode 100644
index 0000000..10e49dc
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/multihashmap.hpp
@@ -0,0 +1,109 @@
+#ifndef __STOUT_MULTIHASHMAP_HPP__
+#define __STOUT_MULTIHASHMAP_HPP__
+
+#include <algorithm> // For find.
+#include <list>
+#include <set>
+#include <utility>
+
+#include <boost/unordered_map.hpp>
+
+
+// Implementation of a hash multimap via Boost's 'unordered_multimap'
+// but with a better interface. The rationale for creating this is
+// that the std::multimap interface is painful to use (requires lots
+// of iterator garbage, as well as the use of 'equal_range' which
+// makes for cluttered code).
+template <typename K, typename V>
+class multihashmap : public boost::unordered_multimap<K, V>
+{
+public:
+ void put(const K& key, const V& value);
+ std::list<V> get(const K& key) const;
+ std::set<K> keys() const;
+ bool remove(const K& key);
+ bool remove(const K& key, const V& value);
+ bool contains(const K& key) const;
+ bool contains(const K& key, const V& value) const;
+};
+
+
+template <typename K, typename V>
+void multihashmap<K, V>::put(const K& key, const V& value)
+{
+ boost::unordered_multimap<K, V>::insert(std::pair<K, V>(key, value));
+}
+
+
+template <typename K, typename V>
+std::list<V> multihashmap<K, V>::get(const K& key) const
+{
+ std::list<V> values; // Values to return.
+
+ std::pair<typename boost::unordered_multimap<K, V>::const_iterator,
+ typename boost::unordered_multimap<K, V>::const_iterator> range;
+
+ range = boost::unordered_multimap<K, V>::equal_range(key);
+
+ typename boost::unordered_multimap<K, V>::const_iterator i;
+ for (i = range.first; i != range.second; ++i) {
+ values.push_back(i->second);
+ }
+
+ return values;
+}
+
+
+template <typename K, typename V>
+std::set<K> multihashmap<K, V>::keys() const
+{
+ std::set<K> keys;
+ foreachkey (const K& key, *this) {
+ keys.insert(key);
+ }
+ return keys;
+}
+
+
+template <typename K, typename V>
+bool multihashmap<K, V>::remove(const K& key)
+{
+ return boost::unordered_multimap<K, V>::erase(key) > 0;
+}
+
+
+template <typename K, typename V>
+bool multihashmap<K, V>::remove(const K& key, const V& value)
+{
+ std::pair<typename boost::unordered_multimap<K, V>::iterator,
+ typename boost::unordered_multimap<K, V>::iterator> range;
+
+ range = boost::unordered_multimap<K, V>::equal_range(key);
+
+ typename boost::unordered_multimap<K, V>::iterator i;
+ for (i = range.first; i != range.second; ++i) {
+ if (i->second == value) {
+ boost::unordered_multimap<K, V>::erase(i);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+template <typename K, typename V>
+bool multihashmap<K, V>::contains(const K& key) const
+{
+ return multihashmap<K, V>::count(key) > 0;
+}
+
+
+template <typename K, typename V>
+bool multihashmap<K, V>::contains(const K& key, const V& value) const
+{
+ const std::list<V>& values = get(key);
+ return std::find(values.begin(), values.end(), value) != values.end();
+}
+
+#endif // __STOUT_MULTIHASHMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/multimap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/multimap.hpp b/third_party/libprocess/3rdparty/stout/include/stout/multimap.hpp
new file mode 100644
index 0000000..187ad79
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/multimap.hpp
@@ -0,0 +1,107 @@
+#ifndef __STOUT_MULTIMAP_HPP__
+#define __STOUT_MULTIMAP_HPP__
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <set>
+#include <utility>
+
+// Implementation of a multimap via std::multimap but with a better
+// interface. The rationale for creating this is that the
+// std::multimap interface is painful to use (requires lots of
+// iterator garbage, as well as the use of 'equal_range' which makes
+// for cluttered code).
+template <typename K, typename V>
+class Multimap : public std::multimap<K, V>
+{
+public:
+ void put(const K& key, const V& value);
+ std::list<V> get(const K& key) const;
+ std::set<K> keys() const;
+ bool remove(const K& key);
+ bool remove(const K& key, const V& value);
+ bool contains(const K& key) const;
+ bool contains(const K& key, const V& value) const;
+};
+
+
+template <typename K, typename V>
+void Multimap<K, V>::put(const K& key, const V& value)
+{
+ std::multimap<K, V>::insert(std::pair<K, V>(key, value));
+}
+
+
+template <typename K, typename V>
+std::list<V> Multimap<K, V>::get(const K& key) const
+{
+ std::list<V> values; // Values to return.
+
+ std::pair<typename std::multimap<K, V>::const_iterator,
+ typename std::multimap<K, V>::const_iterator> range;
+
+ range = std::multimap<K, V>::equal_range(key);
+
+ typename std::multimap<K, V>::const_iterator i;
+ for (i = range.first; i != range.second; ++i) {
+ values.push_back(i->second);
+ }
+
+ return values;
+}
+
+
+template <typename K, typename V>
+std::set<K> Multimap<K, V>::keys() const
+{
+ std::set<K> keys;
+ foreachkey (const K& key, *this) {
+ keys.insert(key);
+ }
+ return keys;
+}
+
+
+template <typename K, typename V>
+bool Multimap<K, V>::remove(const K& key)
+{
+ return std::multimap<K, V>::erase(key) > 0;
+}
+
+
+template <typename K, typename V>
+bool Multimap<K, V>::remove(const K& key, const V& value)
+{
+ std::pair<typename std::multimap<K, V>::iterator,
+ typename std::multimap<K, V>::iterator> range;
+
+ range = std::multimap<K, V>::equal_range(key);
+
+ typename std::multimap<K, V>::iterator i;
+ for (i = range.first; i != range.second; ++i) {
+ if (i->second == value) {
+ std::multimap<K, V>::erase(i);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+template <typename K, typename V>
+bool Multimap<K, V>::contains(const K& key) const
+{
+ return std::multimap<K, V>::count(key) > 0;
+}
+
+
+template <typename K, typename V>
+bool Multimap<K, V>::contains(const K& key, const V& value) const
+{
+ const std::list<V>& values = get(key);
+ return std::find(values.begin(), values.end(), value) != values.end();
+}
+
+#endif // __STOUT_MULTIMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/net.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/net.hpp b/third_party/libprocess/3rdparty/stout/include/stout/net.hpp
new file mode 100644
index 0000000..1c5f88a
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/net.hpp
@@ -0,0 +1,102 @@
+#ifndef __STOUT_NET_HPP__
+#define __STOUT_NET_HPP__
+
+#include <netdb.h>
+#include <stdio.h>
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#ifdef HAVE_LIBCURL
+#include <curl/curl.h>
+#endif
+
+#include <string>
+
+#include "error.hpp"
+#include "os.hpp"
+#include "try.hpp"
+
+
+// Network utilities.
+namespace net {
+
+// Returns the HTTP response code resulting from attempting to download the
+// specified HTTP or FTP URL into a file at the specified path.
+inline Try<int> download(const std::string& url, const std::string& path)
+{
+#ifndef HAVE_LIBCURL
+ return Error("libcurl is not available");
+#else
+ Try<int> fd = os::open(
+ path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
+
+ if (fd.isError()) {
+ return Error(fd.error());
+ }
+
+ curl_global_init(CURL_GLOBAL_ALL);
+ CURL* curl = curl_easy_init();
+
+ if (curl == NULL) {
+ curl_easy_cleanup(curl);
+ os::close(fd.get());
+ return Error("Failed to initialize libcurl");
+ }
+
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
+
+ FILE* file = fdopen(fd.get(), "w");
+ if (file == NULL) {
+ return ErrnoError("Failed to open file handle of '" + path + "'");
+ }
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
+
+ CURLcode curlErrorCode = curl_easy_perform(curl);
+ if (curlErrorCode != 0) {
+ curl_easy_cleanup(curl);
+ fclose(file);
+ return Error(curl_easy_strerror(curlErrorCode));
+ }
+
+ long code;
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
+ curl_easy_cleanup(curl);
+
+ if (fclose(file) != 0) {
+ return ErrnoError("Failed to close file handle of '" + path + "'");
+ }
+
+ return Try<int>::some(code);
+#endif // HAVE_LIBCURL
+}
+
+// Returns a Try of the hostname for the provided IP. If the hostname cannot
+// be resolved, then a string version of the IP address is returned.
+inline Try<std::string> getHostname(uint32_t ip)
+{
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = ip;
+
+ char hostname[MAXHOSTNAMELEN];
+ if (getnameinfo(
+ (sockaddr*)&addr,
+ sizeof(addr),
+ hostname,
+ MAXHOSTNAMELEN,
+ NULL,
+ 0,
+ 0) != 0) {
+ return ErrnoError();
+ }
+
+ return std::string(hostname);
+}
+
+} // namespace net {
+
+#endif // __STOUT_NET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/none.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/none.hpp b/third_party/libprocess/3rdparty/stout/include/stout/none.hpp
new file mode 100644
index 0000000..ea8e0f5
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/none.hpp
@@ -0,0 +1,56 @@
+#ifndef __STOUT_NONE_HPP__
+#define __STOUT_NONE_HPP__
+
+#include "option.hpp"
+#include "result.hpp"
+
+// A "none" type that is implicitly convertible to an Option<T> and
+// Result<T> for any T (effectively "syntactic sugar" to make code
+// more readable). The implementation uses cast operators to perform
+// the conversions instead of adding constructors to Option/Result
+// directly. Performance shouldn't be an issue given that an instance
+// of None has no virtual functions and no fields.
+
+class None
+{
+public:
+ template <typename T>
+ operator Option<T> () const
+ {
+ return Option<T>::none();
+ }
+
+ // Give the compiler some help for nested Option<T>. For example,
+ // enable converting None to a Try<Option<T>>. Note that this will
+ // bind to the innermost Option<T>.
+ template <template <typename> class S, typename T>
+ operator S<Option<T> > () const
+ {
+ return S<Option<T> >(Option<T>::none());
+ }
+
+ template <typename T>
+ operator Result<T> () const
+ {
+ return Result<T>::none();
+ }
+
+ // Give the compiler some help for nested Result<T>. For example,
+ // enable converting None to a Try<Result<T>>. Note that this will
+ // bind to the innermost Result<T>.
+ template <template <typename> class S, typename T>
+ operator S<Result<T> > () const
+ {
+ return S<Result<T> >(Result<T>::none());
+ }
+
+ // Give the compiler some more help to disambiguate the above cast
+ // operators from Result<Option<T>>.
+ template <typename T>
+ operator Result<Option<T> > () const
+ {
+ return Result<Option<T> >::none();
+ }
+};
+
+#endif // __STOUT_NONE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/nothing.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/nothing.hpp b/third_party/libprocess/3rdparty/stout/include/stout/nothing.hpp
new file mode 100644
index 0000000..c11a010
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/nothing.hpp
@@ -0,0 +1,6 @@
+#ifndef __NOTHING_HPP__
+#define __NOTHING_HPP__
+
+struct Nothing {};
+
+#endif // __NOTHING_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/numify.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/numify.hpp b/third_party/libprocess/3rdparty/stout/include/stout/numify.hpp
new file mode 100644
index 0000000..d23e238
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/numify.hpp
@@ -0,0 +1,40 @@
+#ifndef __STOUT_NUMIFY_HPP__
+#define __STOUT_NUMIFY_HPP__
+
+#include <string>
+
+#include <boost/lexical_cast.hpp>
+
+#include "error.hpp"
+#include "none.hpp"
+#include "option.hpp"
+#include "result.hpp"
+#include "try.hpp"
+
+template <typename T>
+Try<T> numify(const std::string& s)
+{
+ try {
+ return boost::lexical_cast<T>(s);
+ } catch (const boost::bad_lexical_cast&) {
+ return Error("Failed to convert '" + s + "' to number");
+ }
+}
+
+
+template <typename T>
+Result<T> numify(const Option<std::string>& s)
+{
+ if (s.isSome()) {
+ Try<T> t = numify<T>(s.get());
+ if (t.isSome()) {
+ return t.get();
+ } else if (t.isError()) {
+ return Error(t.error());
+ }
+ }
+
+ return None();
+}
+
+#endif // __STOUT_NUMIFY_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/option.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/option.hpp b/third_party/libprocess/3rdparty/stout/include/stout/option.hpp
new file mode 100644
index 0000000..f991ae8
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/option.hpp
@@ -0,0 +1,85 @@
+#ifndef __STOUT_OPTION_HPP__
+#define __STOUT_OPTION_HPP__
+
+#include <assert.h>
+
+template <typename T>
+class Option
+{
+public:
+ static Option<T> none()
+ {
+ return Option<T>(NONE);
+ }
+
+ static Option<T> some(const T& t)
+ {
+ return Option<T>(SOME, new T(t));
+ }
+
+ Option() : state(NONE), t(NULL) {}
+
+ Option(const T& _t) : state(SOME), t(new T(_t)) {}
+
+ Option(const Option<T>& that)
+ {
+ state = that.state;
+ if (that.t != NULL) {
+ t = new T(*that.t);
+ } else {
+ t = NULL;
+ }
+ }
+
+ ~Option()
+ {
+ delete t;
+ }
+
+ Option<T>& operator = (const Option<T>& that)
+ {
+ if (this != &that) {
+ delete t;
+ state = that.state;
+ if (that.t != NULL) {
+ t = new T(*that.t);
+ } else {
+ t = NULL;
+ }
+ }
+
+ return *this;
+ }
+
+ bool operator == (const Option<T>& that) const
+ {
+ return (state == NONE && that.state == NONE) ||
+ (state == SOME && that.state == SOME && *t == *that.t);
+ }
+
+ bool operator != (const Option<T>& that) const
+ {
+ return !operator == (that);
+ }
+
+ bool isSome() const { return state == SOME; }
+ bool isNone() const { return state == NONE; }
+
+ T get() const { assert(state == SOME); return *t; }
+
+ T get(const T& _t) const { return state == NONE ? _t : *t; }
+
+private:
+ enum State {
+ SOME,
+ NONE,
+ };
+
+ Option(State _state, T* _t = NULL)
+ : state(_state), t(_t) {}
+
+ State state;
+ T* t;
+};
+
+#endif // __STOUT_OPTION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/os.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/os.hpp b/third_party/libprocess/3rdparty/stout/include/stout/os.hpp
new file mode 100644
index 0000000..28a08cc
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/os.hpp
@@ -0,0 +1,1081 @@
+#ifndef __STOUT_OS_HPP__
+#define __STOUT_OS_HPP__
+
+#ifdef __APPLE__
+#include <crt_externs.h> // For _NSGetEnviron().
+#endif
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <glob.h>
+#include <libgen.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <glog/logging.h>
+
+#ifdef __linux__
+#include <linux/version.h>
+#endif
+
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+#endif
+#ifdef __linux__
+#include <sys/sysinfo.h>
+#endif
+#include <sys/types.h>
+#include <sys/utsname.h>
+
+#include <list>
+#include <set>
+#include <sstream>
+#include <string>
+
+#include "bytes.hpp"
+#include "duration.hpp"
+#include "error.hpp"
+#include "foreach.hpp"
+#include "none.hpp"
+#include "nothing.hpp"
+#include "path.hpp"
+#include "result.hpp"
+#include "strings.hpp"
+#include "try.hpp"
+
+#ifdef __APPLE__
+// Assigning the result pointer to ret silences an unused var warning.
+#define gethostbyname2_r(name, af, ret, buf, buflen, result, h_errnop) \
+ ({ (void)ret; *(result) = gethostbyname2(name, af); 0; })
+#endif // __APPLE__
+
+// Need to declare 'environ' pointer for non OS X platforms.
+#ifndef __APPLE__
+extern char** environ;
+#endif
+
+namespace os {
+
+inline char** environ()
+{
+ // Accessing the list of environment variables is platform-specific.
+ // On OS X, the 'environ' symbol isn't visible to shared libraries,
+ // so we must use the _NSGetEnviron() function (see 'man environ' on
+ // OS X). On other platforms, it's fine to access 'environ' from
+ // shared libraries.
+#ifdef __APPLE__
+ return *_NSGetEnviron();
+#endif
+ return ::environ;
+}
+
+
+// Checks if the specified key is in the environment variables.
+inline bool hasenv(const std::string& key)
+{
+ char* value = ::getenv(key.c_str());
+
+ return value != NULL;
+}
+
+// Looks in the environment variables for the specified key and
+// returns a string representation of it's value. If 'expected' is
+// true (default) and no environment variable matching key is found,
+// this function will exit the process.
+inline std::string getenv(const std::string& key, bool expected = true)
+{
+ char* value = ::getenv(key.c_str());
+
+ if (expected && value == NULL) {
+ LOG(FATAL) << "Expecting '" << key << "' in environment variables";
+ }
+
+ if (value != NULL) {
+ return std::string(value);
+ }
+
+ return std::string();
+}
+
+
+// Sets the value associated with the specified key in the set of
+// environment variables.
+inline void setenv(const std::string& key,
+ const std::string& value,
+ bool overwrite = true)
+{
+ ::setenv(key.c_str(), value.c_str(), overwrite ? 1 : 0);
+}
+
+
+// Unsets the value associated with the specified key in the set of
+// environment variables.
+inline void unsetenv(const std::string& key)
+{
+ ::unsetenv(key.c_str());
+}
+
+
+inline Try<bool> access(const std::string& path, int how)
+{
+ if (::access(path.c_str(), how) < 0) {
+ if (errno == EACCES) {
+ return false;
+ } else {
+ return ErrnoError();
+ }
+ }
+ return true;
+}
+
+
+inline Try<int> open(const std::string& path, int oflag, mode_t mode = 0)
+{
+ int fd = ::open(path.c_str(), oflag, mode);
+
+ if (fd < 0) {
+ return ErrnoError();
+ }
+
+ return fd;
+}
+
+
+inline Try<Nothing> close(int fd)
+{
+ if (::close(fd) != 0) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+
+inline Try<Nothing> cloexec(int fd)
+{
+ int flags = ::fcntl(fd, F_GETFD);
+
+ if (flags == -1) {
+ return ErrnoError();
+ }
+
+ if (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+
+inline Try<Nothing> nonblock(int fd)
+{
+ int flags = ::fcntl(fd, F_GETFL);
+
+ if (flags == -1) {
+ return ErrnoError();
+ }
+
+ if (::fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+
+inline Try<bool> isNonblock(int fd)
+{
+ int flags = ::fcntl(fd, F_GETFL);
+
+ if (flags == -1) {
+ return ErrnoError();
+ }
+
+ return (flags & O_NONBLOCK) != 0;
+}
+
+
+inline Try<Nothing> touch(const std::string& path)
+{
+ Try<int> fd =
+ open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
+
+ if (fd.isError()) {
+ return Error("Failed to open file '" + path + "'");
+ }
+
+ // TODO(benh): Is opening/closing sufficient to have the same
+ // semantics as the touch utility (i.e., doesn't the utility change
+ // the modified date)?
+ return close(fd.get());
+}
+
+
+// Creates a temporary file using the specified path template. The
+// template may be any path with _6_ `Xs' appended to it, for example
+// /tmp/temp.XXXXXX. The trailing `Xs' are replaced with a unique
+// alphanumeric combination.
+inline Try<std::string> mktemp(const std::string& path = "/tmp/XXXXXX")
+{
+ char* temp = new char[path.size() + 1];
+ int fd = ::mkstemp(::strcpy(temp, path.c_str()));
+
+ if (fd < 0) {
+ delete temp;
+ return ErrnoError();
+ }
+
+ // We ignore the return value of close(). This is because users
+ // calling this function are interested in the return value of
+ // mkstemp(). Also an unsuccessful close() doesn't affect the file.
+ os::close(fd);
+
+ std::string result(temp);
+ delete temp;
+ return result;
+}
+
+
+// Write out the string to the file at the current fd position.
+inline Try<Nothing> write(int fd, const std::string& message)
+{
+ size_t offset = 0;
+
+ while (offset < message.length()) {
+ ssize_t length =
+ ::write(fd, message.data() + offset, message.length() - offset);
+
+ if (length < 0) {
+ // TODO(benh): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
+ if (errno == EINTR) {
+ continue;
+ }
+ return ErrnoError();
+ }
+
+ offset += length;
+ }
+
+ 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 std::string& 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 ErrnoError("Failed to open file '" + path + "'");
+ }
+
+ Try<Nothing> result = write(fd.get(), message);
+
+ // 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;
+}
+
+
+// Reads 'size' bytes from a file from its current offset.
+// If EOF is encountered before reading size bytes, then the offset
+// is restored and none is returned.
+inline Result<std::string> read(int fd, size_t size)
+{
+ // Save the current offset.
+ off_t current = lseek(fd, 0, SEEK_CUR);
+ if (current == -1) {
+ return ErrnoError("Failed to lseek to SEEK_CUR");
+ }
+
+ char* buffer = new char[size];
+ size_t offset = 0;
+
+ while (offset < size) {
+ ssize_t length = ::read(fd, buffer + offset, size - offset);
+
+ if (length < 0) {
+ // TODO(bmahler): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
+ if (errno == EINTR) {
+ continue;
+ }
+ // Attempt to restore the original offset.
+ lseek(fd, current, SEEK_SET);
+ return ErrnoError();
+ } else if (length == 0) {
+ // Reached EOF before expected! Restore the offset.
+ lseek(fd, current, SEEK_SET);
+ return None();
+ }
+
+ offset += length;
+ }
+
+ return std::string(buffer, size);
+}
+
+
+// Returns the contents of the file starting from its current offset.
+// If an error occurs, this will attempt to recover the file offset.
+inline Try<std::string> read(int fd)
+{
+ // Save the current offset.
+ off_t current = lseek(fd, 0, SEEK_CUR);
+ if (current == -1) {
+ return ErrnoError("Failed to lseek to SEEK_CUR");
+ }
+
+ // Get the size of the file from the offset.
+ off_t size = lseek(fd, current, SEEK_END);
+ if (size == -1) {
+ return ErrnoError("Failed to lseek to SEEK_END");
+ }
+
+ // Restore the offset.
+ if (lseek(fd, current, SEEK_SET) == -1) {
+ return ErrnoError("Failed to lseek with SEEK_SET");
+ }
+
+ Result<std::string> result = read(fd, size);
+ if (result.isNone()) {
+ // Hit EOF before reading size bytes.
+ return Error("The file size was modified while reading");
+ } else if (result.isError()) {
+ return Error(result.error());
+ }
+
+ return result.get();
+}
+
+
+// A wrapper function that wraps the above read() with
+// open and closing the file.
+inline Try<std::string> 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 + "'");
+ }
+
+ Try<std::string> result = read(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;
+}
+
+
+inline Try<Nothing> rm(const std::string& path)
+{
+ if (::remove(path.c_str()) != 0) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+
+inline Try<std::string> basename(const std::string& path)
+{
+ char* temp = new char[path.size() + 1];
+ char* result = ::basename(::strcpy(temp, path.c_str()));
+ if (result == NULL) {
+ delete temp;
+ return ErrnoError();
+ }
+
+ std::string s(result);
+ delete temp;
+ return s;
+}
+
+
+inline Try<std::string> dirname(const std::string& path)
+{
+ char* temp = new char[path.size() + 1];
+ char* result = ::dirname(::strcpy(temp, path.c_str()));
+ if (result == NULL) {
+ delete temp;
+ return ErrnoError();
+ }
+
+ std::string s(result);
+ delete temp;
+ return s;
+}
+
+
+inline Try<std::string> realpath(const std::string& path)
+{
+ char temp[PATH_MAX];
+ if (::realpath(path.c_str(), temp) == NULL) {
+ return ErrnoError();
+ }
+ return std::string(temp);
+}
+
+
+inline bool isdir(const std::string& path)
+{
+ struct stat s;
+
+ if (::stat(path.c_str(), &s) < 0) {
+ return false;
+ }
+ return S_ISDIR(s.st_mode);
+}
+
+
+inline bool isfile(const std::string& path)
+{
+ struct stat s;
+
+ if (::stat(path.c_str(), &s) < 0) {
+ return false;
+ }
+ return S_ISREG(s.st_mode);
+}
+
+
+inline bool islink(const std::string& path)
+{
+ struct stat s;
+
+ if (::lstat(path.c_str(), &s) < 0) {
+ return false;
+ }
+ return S_ISLNK(s.st_mode);
+}
+
+
+inline bool exists(const std::string& path)
+{
+ struct stat s;
+
+ if (::lstat(path.c_str(), &s) < 0) {
+ return false;
+ }
+ return true;
+}
+
+
+// TODO(benh): Put this in the 'paths' or 'files' or 'fs' namespace.
+inline Try<long> mtime(const std::string& path)
+{
+ struct stat s;
+
+ if (::lstat(path.c_str(), &s) < 0) {
+ return ErrnoError("Error invoking stat for '" + path + "'");
+ }
+
+ return s.st_mtime;
+}
+
+
+inline Try<Nothing> mkdir(const std::string& directory, bool recursive = true)
+{
+ if (!recursive) {
+ if (::mkdir(directory.c_str(), 0755) < 0) {
+ return ErrnoError();
+ }
+ } else {
+ std::vector<std::string> tokens = strings::tokenize(directory, "/");
+ std::string path = "";
+
+ // We got an absolute path, so keep the leading slash.
+ if (directory.find_first_of("/") == 0) {
+ path = "/";
+ }
+
+ foreach (const std::string& token, tokens) {
+ path += token;
+ if (::mkdir(path.c_str(), 0755) < 0 && errno != EEXIST) {
+ return ErrnoError();
+ }
+ path += "/";
+ }
+ }
+
+ return Nothing();
+}
+
+// Creates a temporary directory using the specified path
+// template. The template may be any path with _6_ `Xs' appended to
+// it, for example /tmp/temp.XXXXXX. The trailing `Xs' are replaced
+// with a unique alphanumeric combination.
+inline Try<std::string> mkdtemp(const std::string& path = "/tmp/XXXXXX")
+{
+ char* temp = new char[path.size() + 1];
+ if (::mkdtemp(::strcpy(temp, path.c_str())) != NULL) {
+ std::string result(temp);
+ delete temp;
+ return result;
+ } else {
+ delete temp;
+ return ErrnoError();
+ }
+}
+
+// By default, recursively deletes a directory akin to: 'rm -r'. If the
+// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
+// Note that this function expects an absolute path.
+inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
+{
+ if (!recursive) {
+ if (::rmdir(directory.c_str()) < 0) {
+ return ErrnoError();
+ }
+ } else {
+ char* paths[] = {const_cast<char*>(directory.c_str()), NULL};
+
+ FTS* tree = fts_open(paths, FTS_NOCHDIR, NULL);
+ if (tree == NULL) {
+ return ErrnoError();
+ }
+
+ FTSENT* node;
+ while ((node = fts_read(tree)) != NULL) {
+ switch (node->fts_info) {
+ case FTS_DP:
+ if (::rmdir(node->fts_path) < 0 && errno != ENOENT) {
+ return ErrnoError();
+ }
+ break;
+ case FTS_F:
+ case FTS_SL:
+ if (::unlink(node->fts_path) < 0 && errno != ENOENT) {
+ return ErrnoError();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (errno != 0) {
+ return ErrnoError();
+ }
+
+ if (fts_close(tree) < 0) {
+ return ErrnoError();
+ }
+ }
+
+ return Nothing();
+}
+
+
+inline int system(const std::string& command)
+{
+ return ::system(command.c_str());
+}
+
+
+// TODO(bmahler): Clean these bool functions to return Try<Nothing>.
+// Changes the specified path's user and group ownership to that of
+// the specified user..
+inline Try<Nothing> chown(
+ const std::string& user,
+ const std::string& path,
+ bool recursive = true)
+{
+ passwd* passwd;
+ if ((passwd = ::getpwnam(user.c_str())) == NULL) {
+ return ErrnoError("Failed to get user information for '" + user + "'");
+ }
+
+ if (recursive) {
+ // TODO(bmahler): Consider walking the file tree instead. We would need
+ // to be careful to not miss dotfiles.
+ std::string command = "chown -R " + stringify(passwd->pw_uid) + ':' +
+ stringify(passwd->pw_gid) + " '" + path + "'";
+
+ int status = os::system(command);
+ if (status != 0) {
+ return ErrnoError(
+ "Failed to execute '" + command +
+ "' (exit status: " + stringify(status) + ")");
+ }
+ } else {
+ if (::chown(path.c_str(), passwd->pw_uid, passwd->pw_gid) < 0) {
+ return ErrnoError();
+ }
+ }
+
+ return Nothing();
+}
+
+
+inline bool chmod(const std::string& path, int mode)
+{
+ if (::chmod(path.c_str(), mode) < 0) {
+ PLOG(ERROR) << "Failed to changed the mode of the path '" << path << "'";
+ return false;
+ }
+
+ return true;
+}
+
+
+inline bool chdir(const std::string& directory)
+{
+ if (::chdir(directory.c_str()) < 0) {
+ PLOG(ERROR) << "Failed to change directory";
+ return false;
+ }
+
+ return true;
+}
+
+
+inline bool su(const std::string& user)
+{
+ passwd* passwd;
+ if ((passwd = ::getpwnam(user.c_str())) == NULL) {
+ PLOG(ERROR) << "Failed to get user information for '"
+ << user << "', getpwnam";
+ return false;
+ }
+
+ if (::setgid(passwd->pw_gid) < 0) {
+ PLOG(ERROR) << "Failed to set group id, setgid";
+ return false;
+ }
+
+ if (::setuid(passwd->pw_uid) < 0) {
+ PLOG(ERROR) << "Failed to set user id, setuid";
+ return false;
+ }
+
+ return true;
+}
+
+
+inline std::string getcwd()
+{
+ size_t size = 100;
+
+ while (true) {
+ char* temp = new char[size];
+ if (::getcwd(temp, size) == temp) {
+ std::string result(temp);
+ delete[] temp;
+ return result;
+ } else {
+ if (errno != ERANGE) {
+ delete[] temp;
+ return std::string();
+ }
+ size *= 2;
+ delete[] temp;
+ }
+ }
+
+ return std::string();
+}
+
+
+// TODO(bmahler): Wrap with a Try.
+inline std::list<std::string> ls(const std::string& directory)
+{
+ std::list<std::string> result;
+
+ DIR* dir = opendir(directory.c_str());
+
+ if (dir == NULL) {
+ return std::list<std::string>();
+ }
+
+ // Calculate the size for a "directory entry".
+ long name_max = fpathconf(dirfd(dir), _PC_NAME_MAX);
+
+ // If we don't get a valid size, check NAME_MAX, but fall back on
+ // 255 in the worst case ... Danger, Will Robinson!
+ if (name_max == -1) {
+ name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+ }
+
+ size_t name_end =
+ (size_t) offsetof(dirent, d_name) + name_max + 1;
+
+ size_t size = (name_end > sizeof(dirent)
+ ? name_end
+ : sizeof(dirent));
+
+ dirent* temp = (dirent*) malloc(size);
+
+ if (temp == NULL) {
+ free(temp);
+ closedir(dir);
+ return std::list<std::string>();
+ }
+
+ struct dirent* entry;
+
+ int error;
+
+ while ((error = readdir_r(dir, temp, &entry)) == 0 && entry != NULL) {
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+ continue;
+ }
+ result.push_back(entry->d_name);
+ }
+
+ free(temp);
+ closedir(dir);
+
+ if (error != 0) {
+ return std::list<std::string>();
+ }
+
+ return result;
+}
+
+
+// Return the list of file paths that match the given pattern by recursively
+// searching the given directory. A match is successful if the pattern is a
+// substring of the file name.
+// NOTE: Directory path should not end with '/'.
+// NOTE: Symbolic links are not followed.
+// TODO(vinod): Support regular expressions for pattern.
+// TODO(vinod): Consider using ftw or a non-recursive approach.
+inline Try<std::list<std::string> > find(
+ const std::string& directory,
+ const std::string& pattern)
+{
+ std::list<std::string> results;
+
+ if (!isdir(directory)) {
+ return Error("'" + directory + "' is not a directory");
+ }
+
+ foreach (const std::string& entry, ls(directory)) {
+ std::string path = path::join(directory, entry);
+ // If it's a directory, recurse.
+ if (isdir(path) && !islink(path)) {
+ Try<std::list<std::string> > matches = find(path, pattern);
+ if (matches.isError()) {
+ return matches;
+ }
+ foreach (const std::string& match, matches.get()) {
+ results.push_back(match);
+ }
+ } else {
+ if (entry.find(pattern) != std::string::npos) {
+ results.push_back(path); // Matched the file pattern!
+ }
+ }
+ }
+
+ return results;
+}
+
+
+inline std::string user()
+{
+ passwd* passwd;
+ if ((passwd = getpwuid(getuid())) == NULL) {
+ LOG(FATAL) << "Failed to get username information";
+ }
+
+ return passwd->pw_name;
+}
+
+
+inline Try<std::string> hostname()
+{
+ char host[512];
+
+ if (gethostname(host, sizeof(host)) < 0) {
+ return ErrnoError();
+ }
+
+ // Allocate temporary buffer for gethostbyname2_r.
+ size_t length = 1024;
+ char* temp = new char[length];
+
+ struct hostent he, *hep = NULL;
+ int result = 0;
+ int herrno = 0;
+
+ while ((result = gethostbyname2_r(host, AF_INET, &he, temp,
+ length, &hep, &herrno)) == ERANGE) {
+ // Enlarge the buffer.
+ delete[] temp;
+ length *= 2;
+ temp = new char[length];
+ }
+
+ if (result != 0 || hep == NULL) {
+ delete[] temp;
+ return Error(hstrerror(herrno));
+ }
+
+ std::string hostname = hep->h_name;
+ delete[] temp;
+ return Try<std::string>::some(hostname);
+}
+
+
+// Runs a shell command formatted with varargs and return the return value
+// of the command. Optionally, the output is returned via an argument.
+// TODO(vinod): Pass an istream object that can provide input to the command.
+inline Try<int> shell(std::ostream* os, const std::string& fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ const Try<std::string>& cmdline = strings::internal::format(fmt, args);
+
+ va_end(args);
+
+ if (cmdline.isError()) {
+ return Error(cmdline.error());
+ }
+
+ FILE* file;
+
+ if ((file = popen(cmdline.get().c_str(), "r")) == NULL) {
+ return Error("Failed to run '" + cmdline.get() + "'");
+ }
+
+ char line[1024];
+ // NOTE(vinod): Ideally the if and while loops should be interchanged. But
+ // we get a broken pipe error if we don't read the output and simply close.
+ while (fgets(line, sizeof(line), file) != NULL) {
+ if (os != NULL) {
+ *os << line ;
+ }
+ }
+
+ if (ferror(file) != 0) {
+ ErrnoError error("Error reading output of '" + cmdline.get() + "'");
+ pclose(file); // Ignoring result since we already have an error.
+ return error;
+ }
+
+ int status;
+ if ((status = pclose(file)) == -1) {
+ return Error("Failed to get status of '" + cmdline.get() + "'");
+ }
+
+ return status;
+}
+
+
+// Suspends execution for the given duration.
+inline Try<Nothing> sleep(const Duration& duration)
+{
+ timespec remaining;
+ remaining.tv_sec = static_cast<long>(duration.secs());
+ remaining.tv_nsec =
+ static_cast<long>((duration - Seconds(remaining.tv_sec)).ns());
+
+ while (nanosleep(&remaining, &remaining) == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ return ErrnoError();
+ }
+ }
+
+ return Nothing();
+}
+
+
+// Creates a tar 'archive' with gzip compression, of the given 'path'.
+inline Try<Nothing> tar(const std::string& path, const std::string& archive)
+{
+ Try<int> status =
+ shell(NULL, "tar -czf %s %s", archive.c_str(), path.c_str());
+
+ if (status.isError()) {
+ return Error("Failed to archive " + path + ": " + status.error());
+ } else if (status.get() != 0) {
+ return Error("Non-zero exit status when archiving " + path +
+ ": " + stringify(status.get()));
+ }
+
+ return Nothing();
+}
+
+
+// Returns the list of files that match the given (shell) pattern.
+inline Try<std::list<std::string> > glob(const std::string& pattern)
+{
+ glob_t g;
+ int status = ::glob(pattern.c_str(), GLOB_NOSORT, NULL, &g);
+
+ std::list<std::string> result;
+
+ if (status != 0) {
+ if (status == GLOB_NOMATCH) {
+ return result; // Empty list.
+ } else {
+ return ErrnoError();
+ }
+ }
+
+ for (size_t i = 0; i < g.gl_pathc; ++i) {
+ result.push_back(g.gl_pathv[i]);
+ }
+
+ globfree(&g); // Best-effort free of dynamically allocated memory.
+
+ return result;
+}
+
+
+// Returns the total number of cpus (cores).
+inline Try<long> cpus()
+{
+ long cpus = sysconf(_SC_NPROCESSORS_ONLN);
+
+ if (cpus < 0) {
+ return ErrnoError();
+ }
+ return cpus;
+}
+
+
+// Returns the total size of main memory.
+inline Try<Bytes> memory()
+{
+#ifdef __linux__
+ struct sysinfo info;
+ if (sysinfo(&info) != 0) {
+ return ErrnoError();
+ }
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23)
+ return Bytes(info.totalram * info.mem_unit);
+# else
+ return Bytes(info.totalram);
+# endif
+#elif defined __APPLE__
+ const size_t NAME_SIZE = 2;
+ int name[NAME_SIZE];
+ name[0] = CTL_HW;
+ name[1] = HW_MEMSIZE;
+
+ int64_t memory;
+ size_t length = sizeof(memory);
+
+ if (sysctl(name, NAME_SIZE, &memory, &length, NULL, 0) < 0) {
+ return ErrnoError("Failed to get sysctl of HW_MEMSIZE");
+ }
+ return Bytes(memory);
+#else
+ return Error("Cannot determine the size of main memory");
+#endif
+}
+
+
+// The structure returned by uname describing the currently running system.
+struct UTSInfo
+{
+ std::string sysname; // Operating system name (e.g. Linux).
+ std::string nodename; // Network name of this machine.
+ std::string release; // Release level of the operating system.
+ std::string version; // Version level of the operating system.
+ std::string machine; // Machine hardware platform.
+};
+
+
+// Return the system information.
+inline Try<UTSInfo> uname()
+{
+ struct utsname name;
+
+ if (::uname(&name) < 0) {
+ return ErrnoError();
+ }
+
+ UTSInfo info;
+ info.sysname = name.sysname;
+ info.nodename = name.nodename;
+ info.release = name.release;
+ info.version = name.version;
+ info.machine = name.machine;
+ return info;
+}
+
+
+// Return the operating system name (e.g. Linux).
+inline Try<std::string> sysname()
+{
+ Try<UTSInfo> info = uname();
+ if (info.isError()) {
+ return Error(info.error());
+ }
+
+ return info.get().sysname;
+}
+
+
+// The OS release level.
+struct Release
+{
+ int version;
+ int major;
+ int minor;
+};
+
+
+// Return the OS release numbers.
+inline Try<Release> release()
+{
+ Try<UTSInfo> info = uname();
+ if (info.isError()) {
+ return Error(info.error());
+ }
+
+ Release r;
+ if (::sscanf(
+ info.get().release.c_str(),
+ "%d.%d.%d",
+ &r.version,
+ &r.major,
+ &r.minor) != 3) {
+ return Error("Failed to parse: " + info.get().release);
+ }
+
+ return r;
+}
+
+
+inline Try<bool> alive(pid_t pid)
+{
+ CHECK(pid > 0);
+
+ if (::kill(pid, 0) == 0) {
+ return true;
+ }
+
+ if (errno == ESRCH) {
+ return false;
+ }
+
+ return Try<bool>::error(strerror(errno));
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/owned.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/owned.hpp b/third_party/libprocess/3rdparty/stout/include/stout/owned.hpp
new file mode 100644
index 0000000..3433f50
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/owned.hpp
@@ -0,0 +1,20 @@
+#ifndef __STOUT_OWNED_HPP__
+#define __STOUT_OWNED_HPP__
+
+#include <boost/shared_ptr.hpp>
+
+// Represents a uniquely owned pointer.
+//
+// TODO(bmahler): For now, Owned only provides shared_ptr semantics.
+// When we make the switch to C++11, we will change to provide
+// unique_ptr semantics. Consequently, each usage of Owned that
+// invoked a copy will have to be adjusted to use move semantics.
+template <typename T>
+class Owned : public boost::shared_ptr<T>
+{
+public:
+ Owned(T* t) : boost::shared_ptr<T>(t) {}
+};
+
+
+#endif // __STOUT_OWNED_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/path.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/path.hpp b/third_party/libprocess/3rdparty/stout/include/stout/path.hpp
new file mode 100644
index 0000000..fda4e04
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/path.hpp
@@ -0,0 +1,76 @@
+#ifndef __STOUT_PATH_HPP__
+#define __STOUT_PATH_HPP__
+
+#include <string>
+#include <vector>
+
+#include "strings.hpp"
+
+namespace path {
+
+inline std::string join(const std::string& path1, const std::string& path2)
+{
+ return
+ strings::remove(path1, "/", strings::SUFFIX) + "/" +
+ strings::remove(path2, "/", strings::PREFIX);
+}
+
+
+inline std::string join(
+ const std::string& path1,
+ const std::string& path2,
+ const std::string& path3)
+{
+ return join(path1, join(path2, path3));
+}
+
+
+inline std::string join(
+ const std::string& path1,
+ const std::string& path2,
+ const std::string& path3,
+ const std::string& path4)
+{
+ return join(path1, join(path2, path3, path4));
+}
+
+
+inline std::string join(
+ const std::string& path1,
+ const std::string& path2,
+ const std::string& path3,
+ const std::string& path4,
+ const std::string& path5)
+{
+ return join(path1, join(path2, join(path3, join(path4, path5))));
+}
+
+
+inline std::string join(
+ const std::string& path1,
+ const std::string& path2,
+ const std::string& path3,
+ const std::string& path4,
+ const std::string& path5,
+ const std::string& path6)
+{
+ return join(path1, join(path2, path3, path4, path5, path6));
+}
+
+
+inline std::string join(const std::vector<std::string>& paths)
+{
+ if (paths.empty()) {
+ return "";
+ }
+
+ std::string result = paths[0];
+ for (size_t i = 1; i < paths.size(); ++i) {
+ result = join(result, paths[i]);
+ }
+ return result;
+}
+
+} // namespace path {
+
+#endif // __STOUT_PATH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/preprocessor.hpp b/third_party/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
new file mode 100644
index 0000000..466e16f
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/preprocessor.hpp
@@ -0,0 +1,29 @@
+#ifndef __PROCESS_PREPROCESSOR_HPP__
+#define __PROCESS_PREPROCESSOR_HPP__
+
+#include <boost/preprocessor/cat.hpp>
+
+#include <boost/preprocessor/arithmetic/inc.hpp>
+
+#include <boost/preprocessor/facilities/intercept.hpp>
+
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+// Provides aliases to a bunch of preprocessor macros useful for
+// creating template definitions that have varying number of
+// parameters (should be removable with C++-11 variadic templates).
+
+#define CAT BOOST_PP_CAT
+#define INC BOOST_PP_INC
+#define INTERCEPT BOOST_PP_INTERCEPT
+#define ENUM_PARAMS BOOST_PP_ENUM_PARAMS
+#define ENUM_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS
+#define ENUM_TRAILING_PARAMS BOOST_PP_ENUM_TRAILING_PARAMS
+#define REPEAT BOOST_PP_REPEAT
+#define REPEAT_FROM_TO BOOST_PP_REPEAT_FROM_TO
+
+#endif // __PROCESS_PREPROCESSOR_HPP__
[32/35] git commit: Added 'ThreadLocal' to stout/thread.hpp.
Posted by be...@apache.org.
Added 'ThreadLocal' to stout/thread.hpp.
Review: https://reviews.apache.org/r/11474
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/bb1c3534
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/bb1c3534
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/bb1c3534
Branch: refs/heads/master
Commit: bb1c3534e7ec678ef88173a99afe6a5c6465cc1c
Parents: 5307934
Author: Benjamin Hindman <be...@twitter.com>
Authored: Mon May 27 12:21:48 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:20:25 2013 -0700
----------------------------------------------------------------------
3rdparty/libprocess/3rdparty/stout/Makefile.am | 2 +
.../3rdparty/stout/include/stout/thread.hpp | 49 +++++++++++++++
.../3rdparty/stout/tests/thread_tests.cpp | 26 ++++++++
3 files changed, 77 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bb1c3534/3rdparty/libprocess/3rdparty/stout/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/Makefile.am b/3rdparty/libprocess/3rdparty/stout/Makefile.am
index 4fdee2c..84062a0 100644
--- a/3rdparty/libprocess/3rdparty/stout/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/Makefile.am
@@ -43,6 +43,7 @@ EXTRA_DIST = \
include/stout/stopwatch.hpp \
include/stout/stringify.hpp \
include/stout/strings.hpp \
+ include/stout/thread.hpp \
include/stout/try.hpp \
include/stout/utils.hpp \
include/stout/uuid.hpp \
@@ -59,4 +60,5 @@ EXTRA_DIST = \
tests/os_tests.cpp \
tests/proc_tests.cpp \
tests/strings_tests.cpp \
+ tests/thread_tests.cpp \
tests/uuid_tests.cpp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bb1c3534/3rdparty/libprocess/3rdparty/stout/include/stout/thread.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/thread.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/thread.hpp
new file mode 100644
index 0000000..c5dbe79
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/thread.hpp
@@ -0,0 +1,49 @@
+#ifndef __STOUT_THREAD_HPP__
+#define __STOUT_THREAD_HPP__
+
+#include <pthread.h>
+#include <stdio.h> // For perror.
+#include <stdlib.h> // For abort.
+
+template <typename T>
+struct ThreadLocal
+{
+ ThreadLocal()
+ {
+ if (pthread_key_create(&key, NULL) != 0) {
+ perror("Failed to create thread local, pthread_key_create");
+ abort();
+ }
+ }
+
+ ThreadLocal<T>& operator = (T* t)
+ {
+ if (pthread_setspecific(key, t) != 0) {
+ perror("Failed to set thread local, pthread_setspecific");
+ abort();
+ }
+ return *this;
+ }
+
+ operator T* () const
+ {
+ return reinterpret_cast<T*>(pthread_getspecific(key));
+ }
+
+ T* operator -> () const
+ {
+ return reinterpret_cast<T*>(pthread_getspecific(key));
+ }
+
+private:
+ // Not expecting any other operators to be used (and the rest?).
+ bool operator * (const ThreadLocal<T>&) const;
+ bool operator == (const ThreadLocal<T>&) const;
+ bool operator != (const ThreadLocal<T>&) const;
+ bool operator < (const ThreadLocal<T>&) const;
+ bool operator > (const ThreadLocal<T>&) const;
+
+ pthread_key_t key;
+};
+
+#endif // __STOUT_THREAD_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bb1c3534/3rdparty/libprocess/3rdparty/stout/tests/thread_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/thread_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/thread_tests.cpp
new file mode 100644
index 0000000..7519b12
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/tests/thread_tests.cpp
@@ -0,0 +1,26 @@
+#include <gtest/gtest.h>
+
+#include <string>
+
+#include <stout/thread.hpp>
+
+TEST(Thread, local)
+{
+ ThreadLocal<std::string>* _s_ = new ThreadLocal<std::string>();
+
+ std::string* s = new std::string();
+
+ ASSERT_TRUE(*(_s_) == NULL);
+
+ (*_s_) = s;
+
+ ASSERT_TRUE(*(_s_) == s);
+ ASSERT_FALSE(*(_s_) == NULL);
+
+ (*_s_) = NULL;
+
+ ASSERT_TRUE(*(_s_) == NULL);
+
+ delete s;
+ delete _s_;
+}
[28/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
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__
[02/35] Updated libprocess to use '3rdparty' instead of 'third_party'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/proc.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/proc.hpp b/third_party/libprocess/third_party/stout/include/stout/proc.hpp
deleted file mode 100644
index b59735f..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/proc.hpp
+++ /dev/null
@@ -1,478 +0,0 @@
-/**
- * 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/bc531d3c/third_party/libprocess/third_party/stout/include/stout/protobuf.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/protobuf.hpp b/third_party/libprocess/third_party/stout/include/stout/protobuf.hpp
deleted file mode 100644
index eb79e7b..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/protobuf.hpp
+++ /dev/null
@@ -1,159 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/include/stout/result.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/result.hpp b/third_party/libprocess/third_party/stout/include/stout/result.hpp
deleted file mode 100644
index f918f86..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/result.hpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/include/stout/stopwatch.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/stopwatch.hpp b/third_party/libprocess/third_party/stout/include/stout/stopwatch.hpp
deleted file mode 100644
index bcff8c6..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/stopwatch.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/include/stout/stringify.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/stringify.hpp b/third_party/libprocess/third_party/stout/include/stout/stringify.hpp
deleted file mode 100644
index 136316d..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/stringify.hpp
+++ /dev/null
@@ -1,124 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/include/stout/strings.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/strings.hpp b/third_party/libprocess/third_party/stout/include/stout/strings.hpp
deleted file mode 100644
index ed14106..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/strings.hpp
+++ /dev/null
@@ -1,263 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/include/stout/try.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/try.hpp b/third_party/libprocess/third_party/stout/include/stout/try.hpp
deleted file mode 100644
index 787bffd..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/try.hpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/include/stout/utils.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/utils.hpp b/third_party/libprocess/third_party/stout/include/stout/utils.hpp
deleted file mode 100644
index 0f4bba2..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/utils.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/include/stout/uuid.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/uuid.hpp b/third_party/libprocess/third_party/stout/include/stout/uuid.hpp
deleted file mode 100644
index c6c290d..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/uuid.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/install-sh
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/install-sh b/third_party/libprocess/third_party/stout/install-sh
deleted file mode 100755
index 6781b98..0000000
--- a/third_party/libprocess/third_party/stout/install-sh
+++ /dev/null
@@ -1,520 +0,0 @@
-#!/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/bc531d3c/third_party/libprocess/third_party/stout/m4/acx_pthread.m4
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/m4/acx_pthread.m4 b/third_party/libprocess/third_party/stout/m4/acx_pthread.m4
deleted file mode 100644
index 2cf20de..0000000
--- a/third_party/libprocess/third_party/stout/m4/acx_pthread.m4
+++ /dev/null
@@ -1,363 +0,0 @@
-# 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/bc531d3c/third_party/libprocess/third_party/stout/tests/bytes_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/bytes_tests.cpp b/third_party/libprocess/third_party/stout/tests/bytes_tests.cpp
deleted file mode 100644
index 18b2474..0000000
--- a/third_party/libprocess/third_party/stout/tests/bytes_tests.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/duration_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/duration_tests.cpp b/third_party/libprocess/third_party/stout/tests/duration_tests.cpp
deleted file mode 100644
index e0910d4..0000000
--- a/third_party/libprocess/third_party/stout/tests/duration_tests.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/error_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/error_tests.cpp b/third_party/libprocess/third_party/stout/tests/error_tests.cpp
deleted file mode 100644
index 75e365e..0000000
--- a/third_party/libprocess/third_party/stout/tests/error_tests.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/flags_tests.cpp b/third_party/libprocess/third_party/stout/tests/flags_tests.cpp
deleted file mode 100644
index 2809280..0000000
--- a/third_party/libprocess/third_party/stout/tests/flags_tests.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/gzip_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/gzip_tests.cpp b/third_party/libprocess/third_party/stout/tests/gzip_tests.cpp
deleted file mode 100644
index 13296d8..0000000
--- a/third_party/libprocess/third_party/stout/tests/gzip_tests.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/hashset_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/hashset_tests.cpp b/third_party/libprocess/third_party/stout/tests/hashset_tests.cpp
deleted file mode 100644
index 72f65c4..0000000
--- a/third_party/libprocess/third_party/stout/tests/hashset_tests.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/json_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/json_tests.cpp b/third_party/libprocess/third_party/stout/tests/json_tests.cpp
deleted file mode 100644
index c582d70..0000000
--- a/third_party/libprocess/third_party/stout/tests/json_tests.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/main.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/main.cpp b/third_party/libprocess/third_party/stout/tests/main.cpp
deleted file mode 100644
index 0f1e9cb..0000000
--- a/third_party/libprocess/third_party/stout/tests/main.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/multimap_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/multimap_tests.cpp b/third_party/libprocess/third_party/stout/tests/multimap_tests.cpp
deleted file mode 100644
index 79e7200..0000000
--- a/third_party/libprocess/third_party/stout/tests/multimap_tests.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-#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/bc531d3c/third_party/libprocess/third_party/stout/tests/none_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/tests/none_tests.cpp b/third_party/libprocess/third_party/stout/tests/none_tests.cpp
deleted file mode 100644
index 38d25bb..0000000
--- a/third_party/libprocess/third_party/stout/tests/none_tests.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#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());
-}
[23/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/statistics.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/statistics.cpp b/3rdparty/libprocess/src/statistics.cpp
new file mode 100644
index 0000000..d8f5ad1
--- /dev/null
+++ b/3rdparty/libprocess/src/statistics.cpp
@@ -0,0 +1,508 @@
+#include <glog/logging.h>
+
+#include <algorithm>
+#include <list>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <process/clock.hpp>
+#include <process/delay.hpp>
+#include <process/dispatch.hpp>
+#include <process/future.hpp>
+#include <process/http.hpp>
+#include <process/process.hpp>
+#include <process/statistics.hpp>
+#include <process/time.hpp>
+
+#include <stout/error.hpp>
+#include <stout/duration.hpp>
+#include <stout/foreach.hpp>
+#include <stout/hashmap.hpp>
+#include <stout/hashset.hpp>
+#include <stout/json.hpp>
+#include <stout/none.hpp>
+#include <stout/numify.hpp>
+#include <stout/option.hpp>
+#include <stout/stringify.hpp>
+#include <stout/strings.hpp>
+
+using namespace process;
+using namespace process::http;
+
+using std::list;
+using std::map;
+using std::string;
+using std::vector;
+
+namespace process {
+
+// This is initialized by process::initialize().
+Statistics* statistics = NULL;
+
+// TODO(bmahler): Move time series related logic into this struct.
+// TODO(bmahler): Investigate using google's btree implementation.
+// This provides better insertion and lookup performance for large
+// containers. This _should_ also provide significant memory
+// savings, especially since:
+// 1. Our insertion order will mostly be in sorted order.
+// 2. Our keys (Seconds) have efficient comparison operators.
+// See: http://code.google.com/p/cpp-btree/
+// http://code.google.com/p/cpp-btree/wiki/UsageInstructions
+struct TimeSeries
+{
+ TimeSeries() : values(), archived(false) {}
+
+ // We use a map instead of a hashmap to store the values because
+ // that way we can retrieve a series in sorted order efficiently.
+ map<Time, double> values;
+ bool archived;
+};
+
+
+class StatisticsProcess : public Process<StatisticsProcess>
+{
+public:
+ StatisticsProcess(const Duration& _window)
+ : ProcessBase("statistics"),
+ window(_window) {}
+
+ virtual ~StatisticsProcess() {}
+
+ // Statistics implementation.
+ map<Time, double> timeseries(
+ const string& context,
+ const string& name,
+ const Option<Time>& start,
+ const Option<Time>& stop);
+
+ Option<double> get(const string& context, const string& name);
+
+ map<string, double> get(const string& context);
+
+ Try<Nothing> meter(
+ const string& context,
+ const string& name,
+ const Owned<meters::Meter>& meter);
+
+ void set(
+ const string& context,
+ const string& name,
+ double value,
+ const Time& time);
+
+ void archive(const string& context, const string& name);
+
+ void increment(const string& context, const string& name);
+
+ void decrement(const string& context, const string& name);
+
+protected:
+ virtual void initialize()
+ {
+ route("/snapshot.json", &StatisticsProcess::snapshot);
+ route("/series.json", &StatisticsProcess::series);
+
+ // Schedule the first truncation.
+ delay(STATISTICS_TRUNCATION_INTERVAL, self(), &StatisticsProcess::truncate);
+ }
+
+private:
+ // Removes values for the specified statistic that occurred outside
+ // the time series window.
+ // NOTE: We always ensure there is at least 1 value left for a statistic,
+ // unless it is archived!
+ // Returns true iff the time series is empty.
+ bool truncate(const string& context, const string& name);
+
+ // Removes values for all statistics that occurred outside the time
+ // series window.
+ // NOTE: Runs periodically every STATISTICS_TRUNCATION_INTERVAL.
+ // NOTE: We always ensure there is at least 1 value left for a statistic,
+ // unless it is archived.
+ void truncate();
+
+ // Returns the a snapshot of all statistics in JSON.
+ Future<Response> snapshot(const Request& request);
+
+ // Returns the time series of a statistic in JSON.
+ Future<Response> series(const Request& request);
+
+ const Duration window;
+
+ // This maps from {context: {name: TimeSeries } }.
+ hashmap<string, hashmap<string, TimeSeries> > statistics;
+
+ // Each statistic can have many meters.
+ // This maps from {context: {name: [meters] } }.
+ hashmap<string, hashmap<string, list<Owned<meters::Meter> > > > meters;
+};
+
+
+Try<Nothing> StatisticsProcess::meter(
+ const string& context,
+ const string& name,
+ const Owned<meters::Meter>& meter)
+{
+ if (meter->name == name) {
+ return Error("Meter name must not match the statistic name");
+ }
+
+ // Check for a duplicate meter.
+ foreachkey (const string& context, meters) {
+ foreachkey (const string& name, meters[context]) {
+ foreach (Owned<meters::Meter>& existing, meters[context][name]) {
+ if (meter->name == existing->name) {
+ return Error("Meter name matched existing meter name");
+ }
+ }
+ }
+ }
+
+ // Add the meter.
+ meters[context][name].push_back(meter);
+
+ return Nothing();
+}
+
+
+map<Time, double> StatisticsProcess::timeseries(
+ const string& context,
+ const string& name,
+ const Option<Time>& start,
+ const Option<Time>& stop)
+{
+ if (!statistics.contains(context) || !statistics[context].contains(name)) {
+ return map<Time, double>();
+ }
+
+ const std::map<Time, double>& values =
+ statistics[context].find(name)->second.values;
+
+ map<Time, double>::const_iterator lower = values.lower_bound(start.isSome()
+ ? start.get() : Time::EPOCH);
+
+ map<Time, double>::const_iterator upper = values.upper_bound(stop.isSome()
+ ? stop.get() : Time::MAX);
+
+ return map<Time, double>(lower, upper);
+}
+
+
+Option<double> StatisticsProcess::get(const string& context, const string& name)
+{
+ if (!statistics.contains(context) ||
+ !statistics[context].contains(name) ||
+ statistics[context][name].values.empty()) {
+ return Option<double>::none();
+ } else {
+ return statistics[context][name].values.rbegin()->second;
+ }
+}
+
+
+map<string, double> StatisticsProcess::get(const string& context)
+{
+ map<string, double> results;
+
+ if (!statistics.contains(context)) {
+ return results;
+ }
+
+ foreachkey (const string& name, statistics[context]) {
+ const map<Time, double>& values = statistics[context][name].values;
+
+ if (!values.empty()) {
+ results[name] = values.rbegin()->second;
+ }
+ }
+
+ return results;
+}
+
+
+void StatisticsProcess::set(
+ const string& context,
+ const string& name,
+ double value,
+ const Time& time)
+{
+ statistics[context][name].values[time] = value; // Update the raw value.
+ statistics[context][name].archived = false; // Unarchive.
+
+ truncate(context, name);
+
+ // Update the metered values, if necessary.
+ if (meters.contains(context) && meters[context].contains(name)) {
+ foreach (Owned<meters::Meter>& meter, meters[context][name]) {
+ const Option<double>& update = meter->update(time, value);
+ statistics[context][meter->name].archived = false; // Unarchive.
+
+ if (update.isSome()) {
+ statistics[context][meter->name].values[time] = update.get();
+ truncate(context, meter->name);
+ }
+ }
+ }
+}
+
+
+void StatisticsProcess::archive(const string& context, const string& name)
+{
+ // Exclude the statistic from the snapshot.
+ statistics[context][name].archived = true;
+
+ // Remove any meters as well.
+ if (meters.contains(context) && meters[context].contains(name)) {
+ foreach (const Owned<meters::Meter>& meter, meters[context][name]) {
+ statistics[context][meter->name].archived = true;
+ }
+ meters[context].erase(name);
+ }
+}
+
+
+void StatisticsProcess::increment(const string& context, const string& name)
+{
+ double value = 0.0;
+ if (!statistics[context][name].values.empty()) {
+ value = statistics[context][name].values.rbegin()->second;
+ }
+ set(context, name, value + 1.0, Clock::now());
+}
+
+
+void StatisticsProcess::decrement(const string& context, const string& name)
+{
+ double value = 0.0;
+ if (!statistics[context][name].values.empty()) {
+ value = statistics[context][name].values.rbegin()->second;
+ }
+ set(context, name, value - 1.0, Clock::now());
+}
+
+
+bool StatisticsProcess::truncate(const string& context, const string& name)
+{
+ CHECK(statistics.contains(context));
+ CHECK(statistics[context].contains(name));
+
+ if (statistics[context][name].values.empty()) {
+ return true; // No truncation is needed, the time series is already empty.
+ }
+
+ map<Time, double>::iterator start =
+ statistics[context][name].values.begin();
+
+ while ((Clock::now() - start->first) > window) {
+ // Always keep at least one value for a statistic, unless it's archived!
+ if (statistics[context][name].values.size() == 1) {
+ if (statistics[context][name].archived) {
+ statistics[context][name].values.clear();
+ }
+ break;
+ }
+
+ statistics[context][name].values.erase(start);
+ start = statistics[context][name].values.begin();
+ }
+
+ return statistics[context][name].values.empty();
+}
+
+
+void StatisticsProcess::truncate()
+{
+ hashmap<string, hashset<string> > empties;
+
+ foreachkey (const string& context, statistics) {
+ foreachkey (const string& name, statistics[context]) {
+ // Keep track of the emptied timeseries.
+ if (truncate(context, name)) {
+ empties[context].insert(name);
+ }
+ }
+ }
+
+ // Remove the empty timeseries.
+ foreachkey (const string& context, empties) {
+ foreach (const string& name, empties[context]) {
+ statistics[context].erase(name);
+ }
+ }
+
+ delay(STATISTICS_TRUNCATION_INTERVAL, self(), &StatisticsProcess::truncate);
+}
+
+
+Future<Response> StatisticsProcess::snapshot(const Request& request)
+{
+ JSON::Array array;
+
+ Option<string> queryContext = request.query.get("context");
+ Option<string> queryName = request.query.get("name");
+
+ foreachkey (const string& context, statistics) {
+ foreachkey (const string& name, statistics[context]) {
+ // Exclude archived and empty time series.
+ if (statistics[context][name].archived ||
+ statistics[context][name].values.empty()) {
+ continue;
+ }
+
+ // Skip statistics that don't match the query, if present.
+ if (queryContext.isSome() && queryContext.get() != context) {
+ continue;
+ } else if (queryName.isSome() && queryName.get() != name) {
+ continue;
+ }
+
+ JSON::Object object;
+ object.values["context"] = context;
+ object.values["name"] = name;
+ object.values["time"] =
+ statistics[context][name].values.rbegin()->first.secs();
+ object.values["value"] =
+ statistics[context][name].values.rbegin()->second;
+ array.values.push_back(object);
+ }
+ }
+
+ return OK(array, request.query.get("jsonp"));
+}
+
+
+Future<Response> StatisticsProcess::series(const Request& request)
+{
+ Option<string> context = request.query.get("context");
+ Option<string> name = request.query.get("name");
+
+ if (!context.isSome()) {
+ return BadRequest("Expected 'context=val' in query.\n");
+ } else if (!name.isSome()) {
+ return BadRequest("Expected 'name=val' in query.\n");
+ }
+
+ Option<Time> start = None();
+ Option<Time> stop = None();
+
+ if (request.query.get("start").isSome()) {
+ Try<double> result = numify<double>(request.query.get("start").get());
+ if (result.isError()) {
+ return BadRequest("Failed to parse 'start': " + result.error());
+ }
+
+ Try<Time> start_ = Time::create(result.get());
+ if (start_.isError()) {
+ return BadRequest("Failed to parse 'start': " + start_.error());
+ }
+ start = start_.get();
+ }
+
+ if (request.query.get("stop").isSome()) {
+ Try<double> result = numify<double>(request.query.get("stop").get());
+ if (result.isError()) {
+ return BadRequest("Failed to parse 'stop': " + result.error());
+ }
+
+ Try<Time> stop_ = Time::create(result.get());
+ if (stop_.isError()) {
+ return BadRequest("Failed to parse 'stop': " + stop_.error());
+ }
+ stop = stop_.get();
+ }
+
+ JSON::Array array;
+
+ const map<Time, double>& values =
+ timeseries(context.get(), name.get(), start, stop);
+
+ foreachpair (const Time& s, double value, values) {
+ JSON::Object object;
+ object.values["time"] = s.secs();
+ object.values["value"] = value;
+ array.values.push_back(object);
+ }
+
+ return OK(array, request.query.get("jsonp"));
+}
+
+
+Statistics::Statistics(const Duration& window)
+{
+ process = new StatisticsProcess(window);
+ spawn(process);
+}
+
+
+Statistics::~Statistics()
+{
+ terminate(process);
+ wait(process);
+}
+
+
+Future<map<Time, double> > Statistics::timeseries(
+ const string& context,
+ const string& name,
+ const Option<Time>& start,
+ const Option<Time>& stop)
+{
+ return dispatch(
+ process, &StatisticsProcess::timeseries, context, name, start, stop);
+}
+
+
+Future<Option<double> > Statistics::get(
+ const string& context,
+ const string& name)
+{
+ return dispatch(process, &StatisticsProcess::get, context, name);
+}
+
+
+Future<map<string, double> > Statistics::get(const string& context)
+{
+ return dispatch(process, &StatisticsProcess::get, context);
+}
+
+
+Future<Try<Nothing> > Statistics::meter(
+ const string& context,
+ const string& name,
+ Owned<meters::Meter> meter)
+{
+
+ return dispatch(process, &StatisticsProcess::meter, context, name, meter);
+}
+
+
+void Statistics::set(
+ const string& context,
+ const string& name,
+ double value,
+ const Time& time)
+{
+ dispatch(process, &StatisticsProcess::set, context, name, value, time);
+}
+
+
+void Statistics::archive(const string& context, const string& name)
+{
+ dispatch(process, &StatisticsProcess::archive, context, name);
+}
+
+
+void Statistics::increment(const string& context, const string& name)
+{
+ dispatch(process, &StatisticsProcess::increment, context, name);
+}
+
+
+void Statistics::decrement(const string& context, const string& name)
+{
+ dispatch(process, &StatisticsProcess::decrement, context, name);
+}
+
+} // namespace process {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/synchronized.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/synchronized.cpp b/3rdparty/libprocess/src/synchronized.cpp
new file mode 100644
index 0000000..79b0849
--- /dev/null
+++ b/3rdparty/libprocess/src/synchronized.cpp
@@ -0,0 +1,66 @@
+#include "synchronized.hpp"
+
+using std::string;
+
+
+static string s1;
+static synchronizable(s1);
+
+static string s2;
+static synchronizable(s2) = SYNCHRONIZED_INITIALIZER;
+
+static string s3;
+static synchronizable(s3) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
+
+
+void bar()
+{
+ synchronized(s3) {
+
+ }
+}
+
+
+void foo()
+{
+ synchronized(s3) {
+ bar();
+ }
+}
+
+
+class Foo
+{
+public:
+ Foo()
+ {
+ synchronizer(s) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
+ }
+
+ void foo()
+ {
+ synchronized(s) {
+ synchronized(s) {
+
+ }
+ }
+ }
+
+private:
+ string s;
+ synchronizable(s);
+};
+
+
+int main(int argc, char **argv)
+{
+ synchronizer(s1) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
+ //synchronizer(s2) = SYNCHRONIZED_INITIALIZER;
+
+ //foo();
+
+ Foo f;
+ f.foo();
+
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/synchronized.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/synchronized.hpp b/3rdparty/libprocess/src/synchronized.hpp
new file mode 100644
index 0000000..7e0efe2
--- /dev/null
+++ b/3rdparty/libprocess/src/synchronized.hpp
@@ -0,0 +1,104 @@
+#include <pthread.h>
+
+#include <iostream>
+
+
+class Synchronizable
+{
+public:
+ Synchronizable()
+ : initialized(false) {}
+
+ explicit Synchronizable(int _type)
+ : type(_type), initialized(false)
+ {
+ initialize();
+ }
+
+ Synchronizable(const Synchronizable &that)
+ {
+ type = that.type;
+ initialize();
+ }
+
+ Synchronizable & operator = (const Synchronizable &that)
+ {
+ type = that.type;
+ initialize();
+ return *this;
+ }
+
+ void acquire()
+ {
+ if (!initialized) {
+ std::cerr << "synchronizable not initialized" << std::endl;
+ abort();
+ }
+ pthread_mutex_lock(&mutex);
+ }
+
+ void release()
+ {
+ if (!initialized) {
+ std::cerr << "synchronizable not initialized" << std::endl;
+ abort();
+ }
+ pthread_mutex_unlock(&mutex);
+ }
+
+private:
+ void initialize()
+ {
+ if (!initialized) {
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, type);
+ pthread_mutex_init(&mutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+ initialized = true;
+ } else {
+ std::cerr << "synchronizable already initialized" << std::endl;
+ abort();
+ }
+ }
+
+ int type;
+ bool initialized;
+ pthread_mutex_t mutex;
+};
+
+
+class Synchronized
+{
+public:
+ Synchronized(Synchronizable *_synchronizable)
+ : synchronizable(_synchronizable)
+ {
+ synchronizable->acquire();
+ }
+
+ ~Synchronized()
+ {
+ synchronizable->release();
+ }
+
+ operator bool () { return true; }
+
+private:
+ Synchronizable *synchronizable;
+};
+
+
+#define synchronized(s) \
+ if (Synchronized __synchronized ## s = Synchronized(&__synchronizable_ ## s))
+
+#define synchronizable(s) \
+ Synchronizable __synchronizable_ ## s
+
+#define synchronizer(s) \
+ (__synchronizable_ ## s)
+
+
+#define SYNCHRONIZED_INITIALIZER Synchronizable(PTHREAD_MUTEX_NORMAL)
+#define SYNCHRONIZED_INITIALIZER_DEBUG Synchronizable(PTHREAD_MUTEX_ERRORCHECK)
+#define SYNCHRONIZED_INITIALIZER_RECURSIVE Synchronizable(PTHREAD_MUTEX_RECURSIVE)
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/test-master.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/test-master.cpp b/3rdparty/libprocess/src/test-master.cpp
new file mode 100644
index 0000000..23c6e1d
--- /dev/null
+++ b/3rdparty/libprocess/src/test-master.cpp
@@ -0,0 +1,62 @@
+#include <io.hpp>
+#include <tuple.hpp>
+
+#include <string>
+
+#include "test.hpp"
+
+using std::string;
+
+
+using namespace process::tuple;
+
+
+class Master : public Tuple<Process>
+{
+private:
+ int id;
+
+protected:
+ void operator () ()
+ {
+ do {
+ switch (receive()) {
+ case REGISTER: {
+ Out::println("Master received REGISTER");
+
+ string name;
+ unpack<REGISTER>(name);
+
+ Out::println("Registered slave: %s", name.c_str());
+
+ send(from(), pack<OKAY>(id++));
+ break;
+ }
+ case UNREGISTER: {
+ Out::println("Master received UNREGISTER");
+
+ int slave_id;
+ unpack<UNREGISTER>(slave_id);
+
+ Out::println("Unregistered slave id: %d", slave_id);
+
+ send(from(), pack<OKAY>(0));
+ break;
+ }
+ default:
+ Out::println("UNKNOWN MESSAGE RECEIVED");
+ }
+ } while (true);
+ }
+
+public:
+ Master() : id(0) {}
+};
+
+
+int main(int argc, char **argv)
+{
+ PID master = Process::spawn(new Master());
+ Out::println("master: %s", string(master).c_str());
+ Process::wait(master);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/test-slave.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/test-slave.cpp b/3rdparty/libprocess/src/test-slave.cpp
new file mode 100644
index 0000000..fe08ce8
--- /dev/null
+++ b/3rdparty/libprocess/src/test-slave.cpp
@@ -0,0 +1,61 @@
+#include <test.hpp>
+
+using namespace process::record;
+
+class Slave : public RecordProcess
+{
+private:
+ PID master;
+ int id;
+
+protected:
+ void operator () ()
+ {
+ send(master, pack<REGISTER>("c3po"));
+
+ switch (receive()) {
+ case OKAY: {
+ std::cout << "slave registered" << std::endl;
+ unpack<OKAY>(id);
+ std::cout << "slave id: " << id << std::endl;
+ break;
+ }
+ default:
+ std::cout << "slave failed to register" << std::endl;
+ break;
+ }
+
+ send(master, pack<UNREGISTER>(id));
+
+ switch (receive()) {
+ case OKAY:
+ std::cout << "slave unregistered" << std::endl;
+ break;
+ default:
+ std::cout << "slave failed to unregister" << std::endl;
+ break;
+ }
+
+ link(master);
+ switch (receive()) {
+ case PROCESS_EXIT:
+ std::cout << "master exited" << std::endl;
+ break;
+ default:
+ std::cout << "unexpected message" << std::endl;
+ break;
+ }
+ }
+
+public:
+ Slave(const PID &_master) : master(_master) {}
+};
+
+
+int main(int argc, char **argv)
+{
+ PID master = make_pid(argv[1]);
+ PID slave = Process::spawn(new Slave(master));
+ std::cout << "slave is at " << slave << std::endl;
+ Process::wait(slave);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/tests/decoder_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/decoder_tests.cpp b/3rdparty/libprocess/src/tests/decoder_tests.cpp
new file mode 100644
index 0000000..04ca3ff
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/decoder_tests.cpp
@@ -0,0 +1,128 @@
+#include <gmock/gmock.h>
+
+#include <deque>
+#include <string>
+
+#include <process/socket.hpp>
+
+#include <stout/gtest.hpp>
+
+#include "decoder.hpp"
+
+using namespace process;
+using namespace process::http;
+
+using std::deque;
+using std::string;
+
+
+TEST(Decoder, Request)
+{
+ DataDecoder decoder = DataDecoder(Socket());
+
+ const string& data =
+ "GET /path/file.json?key1=value1&key2=value2#fragment HTTP/1.1\r\n"
+ "Host: localhost\r\n"
+ "Connection: close\r\n"
+ "Accept-Encoding: compress, gzip\r\n"
+ "\r\n";
+
+ deque<Request*> requests = decoder.decode(data.data(), data.length());
+ ASSERT_FALSE(decoder.failed());
+ ASSERT_EQ(1, requests.size());
+
+ Request* request = requests[0];
+ EXPECT_EQ("GET", request->method);
+ EXPECT_EQ("/path/file.json", request->path);
+ EXPECT_EQ("/path/file.json?key1=value1&key2=value2#fragment", request->url);
+ EXPECT_EQ("fragment", request->fragment);
+ EXPECT_TRUE(request->body.empty());
+ EXPECT_FALSE(request->keepAlive);
+
+ EXPECT_EQ(3, request->headers.size());
+ EXPECT_SOME_EQ("localhost", request->headers.get("Host"));
+ EXPECT_SOME_EQ("close", request->headers.get("Connection"));
+ EXPECT_SOME_EQ("compress, gzip", request->headers.get("Accept-Encoding"));
+
+ EXPECT_EQ(2, request->query.size());
+ EXPECT_SOME_EQ("value1", request->query.get("key1"));
+ EXPECT_SOME_EQ("value2", request->query.get("key2"));
+
+ delete request;
+}
+
+
+TEST(Decoder, RequestHeaderContinuation)
+{
+ DataDecoder decoder = DataDecoder(Socket());
+
+ const string& data =
+ "GET /path/file.json HTTP/1.1\r\n"
+ "Host: localhost\r\n"
+ "Connection: close\r\n"
+ "Accept-Encoding: compress,"
+ " gzip\r\n"
+ "\r\n";
+
+ deque<Request*> requests = decoder.decode(data.data(), data.length());
+ ASSERT_FALSE(decoder.failed());
+ ASSERT_EQ(1, requests.size());
+
+ Request* request = requests[0];
+ EXPECT_SOME_EQ("compress, gzip",
+ request->headers.get("Accept-Encoding"));
+ delete request;
+}
+
+
+// This is expected to fail for now, see my TODO(bmahler) on http::Request.
+TEST(Decoder, DISABLED_RequestHeaderCaseInsensitive)
+{
+ DataDecoder decoder = DataDecoder(Socket());
+
+ const string& data =
+ "GET /path/file.json HTTP/1.1\r\n"
+ "Host: localhost\r\n"
+ "cOnnECtioN: close\r\n"
+ "accept-ENCODING: compress, gzip\r\n"
+ "\r\n";
+
+ deque<Request*> requests = decoder.decode(data.data(), data.length());
+ ASSERT_FALSE(decoder.failed());
+ ASSERT_EQ(1, requests.size());
+
+ Request* request = requests[0];
+ EXPECT_FALSE(request->keepAlive);
+
+ EXPECT_SOME_EQ("compress, gzip", request->headers.get("Accept-Encoding"));
+
+ delete request;
+}
+
+
+TEST(Decoder, Response)
+{
+ ResponseDecoder decoder;
+
+ const string& data =
+ "HTTP/1.1 200 OK\r\n"
+ "Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"
+ "Content-Type: text/plain\r\n"
+ "Content-Length: 2\r\n"
+ "\r\n"
+ "hi";
+
+ deque<Response*> requests = decoder.decode(data.data(), data.length());
+ ASSERT_FALSE(decoder.failed());
+ ASSERT_EQ(1, requests.size());
+
+ Response* response = requests[0];
+
+ EXPECT_EQ("200 OK", response->status);
+ EXPECT_EQ(Response::BODY, response->type);
+ EXPECT_EQ("hi", response->body);
+
+ EXPECT_EQ(3, response->headers.size());
+
+ delete response;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/tests/encoder_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/encoder_tests.cpp b/3rdparty/libprocess/src/tests/encoder_tests.cpp
new file mode 100644
index 0000000..fccb865
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/encoder_tests.cpp
@@ -0,0 +1,92 @@
+#include <gmock/gmock.h>
+
+#include <deque>
+#include <string>
+#include <vector>
+
+#include <process/http.hpp>
+#include <process/socket.hpp>
+
+#include <stout/gtest.hpp>
+
+#include "encoder.hpp"
+#include "decoder.hpp"
+
+using namespace process;
+using namespace process::http;
+
+using std::deque;
+using std::string;
+using std::vector;
+
+
+TEST(Encoder, Response)
+{
+ Request request;
+ const OK& response("body");
+
+ // Encode the response.
+ const string& encoded = HttpResponseEncoder::encode(response, request);
+
+ // Now decode it back, and verify the encoding was correct.
+ ResponseDecoder decoder;
+ deque<Response*> responses = decoder.decode(encoded.data(), encoded.length());
+ ASSERT_FALSE(decoder.failed());
+ ASSERT_EQ(1, responses.size());
+
+ Response* decoded = responses[0];
+ EXPECT_EQ("200 OK", decoded->status);
+ EXPECT_EQ("body", decoded->body);
+
+ // Encoding should have inserted the 'Date' and 'Content-Length' headers.
+ EXPECT_EQ(2, decoded->headers.size());
+ EXPECT_TRUE(decoded->headers.contains("Date"));
+ EXPECT_SOME_EQ(
+ stringify(response.body.size()),
+ decoded->headers.get("Content-Length"));
+}
+
+
+TEST(Encoder, AcceptableEncodings)
+{
+ // Create requests that do not accept gzip encoding.
+ vector<Request> requests(7);
+ requests[0].headers["Accept-Encoding"] = "gzip;q=0.0,*";
+ requests[1].headers["Accept-Encoding"] = "compress";
+ requests[2].headers["Accept-Encoding"] = "compress, gzip;q=0.0";
+ requests[3].headers["Accept-Encoding"] = "*, gzip;q=0.0";
+ requests[4].headers["Accept-Encoding"] = "*;q=0.0, compress";
+ requests[5].headers["Accept-Encoding"] = "\n compress";
+ requests[6].headers["Accept-Encoding"] = "compress,\tgzip;q=0.0";
+
+ foreach (const Request& request, requests) {
+ EXPECT_FALSE(request.accepts("gzip"))
+ << "Gzip encoding is unacceptable for 'Accept-Encoding: "
+ << request.headers.get("Accept-Encoding").get() << "'";
+ }
+
+ // Create requests that accept gzip encoding.
+ vector<Request> gzipRequests(12);
+
+ // Using q values.
+ gzipRequests[0].headers["Accept-Encoding"] = "gzip;q=0.1,*";
+ gzipRequests[1].headers["Accept-Encoding"] = "compress, gzip;q=0.1";
+ gzipRequests[2].headers["Accept-Encoding"] = "*, gzip;q=0.5";
+ gzipRequests[3].headers["Accept-Encoding"] = "*;q=0.9, compress";
+ gzipRequests[4].headers["Accept-Encoding"] = "compress,\tgzip;q=0.1";
+
+ // No q values.
+ gzipRequests[5].headers["Accept-Encoding"] = "gzip";
+ gzipRequests[6].headers["Accept-Encoding"] = "compress, gzip";
+ gzipRequests[7].headers["Accept-Encoding"] = "*";
+ gzipRequests[8].headers["Accept-Encoding"] = "*, compress";
+ gzipRequests[9].headers["Accept-Encoding"] = "\n gzip";
+ gzipRequests[10].headers["Accept-Encoding"] = "compress,\tgzip";
+ gzipRequests[11].headers["Accept-Encoding"] = "gzip";
+
+ foreach (const Request& gzipRequest, gzipRequests) {
+ EXPECT_TRUE(gzipRequest.accepts("gzip"))
+ << "Gzip encoding is acceptable for 'Accept-Encoding: "
+ << gzipRequest.headers.get("Accept-Encoding").get() << "'";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/tests/http_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/http_tests.cpp b/3rdparty/libprocess/src/tests/http_tests.cpp
new file mode 100644
index 0000000..f677267
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/http_tests.cpp
@@ -0,0 +1,133 @@
+#include <arpa/inet.h>
+
+#include <gmock/gmock.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <string>
+
+#include <process/future.hpp>
+#include <process/gmock.hpp>
+#include <process/gtest.hpp>
+#include <process/http.hpp>
+#include <process/io.hpp>
+
+#include <stout/gtest.hpp>
+#include <stout/nothing.hpp>
+#include <stout/os.hpp>
+
+#include "encoder.hpp"
+
+using namespace process;
+
+using testing::_;
+using testing::Assign;
+using testing::DoAll;
+using testing::Return;
+
+
+class HttpProcess : public Process<HttpProcess>
+{
+public:
+ HttpProcess()
+ {
+ route("/body", &HttpProcess::body);
+ route("/pipe", &HttpProcess::pipe);
+ }
+
+ MOCK_METHOD1(body, Future<http::Response>(const http::Request&));
+ MOCK_METHOD1(pipe, Future<http::Response>(const http::Request&));
+};
+
+
+TEST(HTTP, Endpoints)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ HttpProcess process;
+
+ spawn(process);
+
+ // First hit '/body' (using explicit sockets and HTTP/1.0).
+ int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+
+ ASSERT_LE(0, s);
+
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = PF_INET;
+ addr.sin_port = htons(process.self().port);
+ addr.sin_addr.s_addr = process.self().ip;
+
+ ASSERT_EQ(0, connect(s, (sockaddr*) &addr, sizeof(addr)));
+
+ std::ostringstream out;
+ out << "GET /" << process.self().id << "/body"
+ << " HTTP/1.0\r\n"
+ << "Connection: Keep-Alive\r\n"
+ << "\r\n";
+
+ const std::string& data = out.str();
+
+ EXPECT_CALL(process, body(_))
+ .WillOnce(Return(http::OK()));
+
+ ASSERT_SOME(os::write(s, data));
+
+ std::string response = "HTTP/1.1 200 OK";
+
+ char temp[response.size()];
+ ASSERT_LT(0, ::read(s, temp, response.size()));
+ ASSERT_EQ(response, std::string(temp, response.size()));
+
+ ASSERT_EQ(0, close(s));
+
+ // Now hit '/pipe' (by using http::get).
+ int pipes[2];
+ ASSERT_NE(-1, ::pipe(pipes));
+
+ http::OK ok;
+ ok.type = http::Response::PIPE;
+ ok.pipe = pipes[0];
+
+ Future<Nothing> pipe;
+ EXPECT_CALL(process, pipe(_))
+ .WillOnce(DoAll(FutureSatisfy(&pipe),
+ Return(ok)));
+
+ Future<http::Response> future = http::get(process.self(), "pipe");
+
+ AWAIT_READY(pipe);
+
+ ASSERT_SOME(os::write(pipes[1], "Hello World\n"));
+ ASSERT_SOME(os::close(pipes[1]));
+
+ AWAIT_READY(future);
+ ASSERT_EQ(http::statuses[200], future.get().status);
+ ASSERT_EQ("chunked", future.get().headers["Transfer-Encoding"]);
+ ASSERT_EQ("Hello World\n", future.get().body);
+
+ terminate(process);
+ wait(process);
+}
+
+
+TEST(HTTP, Encode)
+{
+ std::string unencoded = "a$&+,/:;=?@ \"<>#%{}|\\^~[]`\x19\x80\xFF";
+ unencoded += std::string("\x00", 1); // Add a null byte to the end.
+
+ std::string encoded = http::encode(unencoded);
+
+ EXPECT_EQ("a%24%26%2B%2C%2F%3A%3B%3D%3F%40%20%22%3C%3E%23"
+ "%25%7B%7D%7C%5C%5E%7E%5B%5D%60%19%80%FF%00",
+ encoded);
+
+ EXPECT_SOME_EQ(unencoded, http::decode(encoded));
+
+ EXPECT_ERROR(http::decode("%"));
+ EXPECT_ERROR(http::decode("%1"));
+ EXPECT_ERROR(http::decode("%;1"));
+ EXPECT_ERROR(http::decode("%1;"));
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/tests/io_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/io_tests.cpp b/3rdparty/libprocess/src/tests/io_tests.cpp
new file mode 100644
index 0000000..288fa83
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/io_tests.cpp
@@ -0,0 +1,162 @@
+#include <gmock/gmock.h>
+
+#include <string>
+
+#include <process/future.hpp>
+#include <process/gtest.hpp>
+#include <process/io.hpp>
+
+#include <stout/gtest.hpp>
+#include <stout/os.hpp>
+
+#include "encoder.hpp"
+
+using namespace process;
+
+using std::string;
+
+
+TEST(IO, Poll)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ int pipes[2];
+ pipe(pipes);
+
+ Future<short> future = io::poll(pipes[0], io::READ);
+
+ EXPECT_FALSE(future.isReady());
+
+ ASSERT_EQ(3, write(pipes[1], "hi", 3));
+
+ AWAIT_EXPECT_EQ(io::READ, future);
+
+ close(pipes[0]);
+ close(pipes[1]);
+}
+
+
+TEST(IO, Read)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ int pipes[2];
+ char data[3];
+
+ // Create a blocking pipe.
+ ASSERT_NE(-1, ::pipe(pipes));
+
+ // Test on a blocking file descriptor.
+ AWAIT_EXPECT_FAILED(io::read(pipes[0], data, 3));
+
+ close(pipes[0]);
+ close(pipes[1]);
+
+ // Test on a closed file descriptor.
+ AWAIT_EXPECT_FAILED(io::read(pipes[0], data, 3));
+
+ // Create a nonblocking pipe.
+ ASSERT_NE(-1, ::pipe(pipes));
+ ASSERT_SOME(os::nonblock(pipes[0]));
+ ASSERT_SOME(os::nonblock(pipes[1]));
+
+ // Test reading nothing.
+ AWAIT_EXPECT_FAILED(io::read(pipes[0], data, 0));
+
+ // Test successful read.
+ Future<size_t> future = io::read(pipes[0], data, 3);
+ ASSERT_FALSE(future.isReady());
+
+ ASSERT_EQ(2, write(pipes[1], "hi", 2));
+
+ AWAIT_ASSERT_EQ(2u, future);
+ EXPECT_EQ('h', data[0]);
+ EXPECT_EQ('i', data[1]);
+
+ // Test cancellation.
+ future = io::read(pipes[0], data, 1);
+ ASSERT_FALSE(future.isReady());
+
+ future.discard();
+
+ ASSERT_EQ(3, write(pipes[1], "omg", 3));
+
+ AWAIT_ASSERT_EQ(3u, io::read(pipes[0], data, 3));
+ EXPECT_EQ('o', data[0]);
+ EXPECT_EQ('m', data[1]);
+ EXPECT_EQ('g', data[2]);
+
+ // Test read EOF.
+ future = io::read(pipes[0], data, 3);
+ ASSERT_FALSE(future.isReady());
+
+ close(pipes[1]);
+
+ AWAIT_ASSERT_EQ(0u, future);
+
+ close(pipes[0]);
+}
+
+
+TEST(IO, BufferedRead)
+{
+ // 128 Bytes.
+ string data =
+ "This data is much larger than BUFFERED_READ_SIZE, which means it will "
+ "trigger multiple buffered async reads as a result.........";
+ ASSERT_EQ(128u, data.size());
+
+ // Keep doubling the data size until we're guaranteed to trigger at least
+ // 3 buffered async reads.
+ while (data.length() < 3 * io::BUFFERED_READ_SIZE) {
+ data.append(data);
+ }
+
+ // First read from a file.
+ ASSERT_SOME(os::write("file", data));
+
+ Try<int> fd = os::open("file", O_RDONLY);
+ ASSERT_SOME(fd);
+
+ // Read from blocking fd.
+ AWAIT_EXPECT_FAILED(io::read(fd.get()));
+
+ // Read from non-blocking fd.
+ ASSERT_TRUE(os::nonblock(fd.get()).isSome());
+ AWAIT_EXPECT_EQ(data, io::read(fd.get()));
+
+ os::close(fd.get());
+
+ // Now read from pipes.
+ int pipes[2];
+
+ // Create a blocking pipe.
+ ASSERT_NE(-1, ::pipe(pipes));
+
+ // Test on a blocking pipe.
+ AWAIT_EXPECT_FAILED(io::read(pipes[0]));
+
+ close(pipes[0]);
+ close(pipes[1]);
+
+ // Test on a closed pipe.
+ AWAIT_EXPECT_FAILED(io::read(pipes[0]));
+
+ // Create a nonblocking pipe for reading.
+ ASSERT_NE(-1, ::pipe(pipes));
+ ASSERT_SOME(os::nonblock(pipes[0]));
+
+ // Test a successful read from the pipe.
+ Future<string> future = io::read(pipes[0]);
+
+ // At first, the future will not be ready until we write to and
+ // close the pipe.
+ ASSERT_FALSE(future.isReady());
+
+ ASSERT_SOME(os::write(pipes[1], data));
+ close(pipes[1]);
+
+ AWAIT_EXPECT_EQ(data, future);
+
+ close(pipes[0]);
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/main.cpp b/3rdparty/libprocess/src/tests/main.cpp
new file mode 100644
index 0000000..6c672b4
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/main.cpp
@@ -0,0 +1,25 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <process/gmock.hpp>
+#include <process/gtest.hpp>
+#include <process/process.hpp>
+
+int main(int argc, char** argv)
+{
+ // Initialize Google Mock/Test.
+ testing::InitGoogleMock(&argc, argv);
+
+ // Initialize libprocess.
+ process::initialize();
+
+ // Add the libprocess test event listeners.
+ ::testing::TestEventListeners& listeners =
+ ::testing::UnitTest::GetInstance()->listeners();
+
+ listeners.Append(process::ClockTestEventListener::instance());
+ listeners.Append(process::FilterTestEventListener::instance());
+
+ return RUN_ALL_TESTS();
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/tests/process_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/process_tests.cpp b/3rdparty/libprocess/src/tests/process_tests.cpp
new file mode 100644
index 0000000..dc5c671
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/process_tests.cpp
@@ -0,0 +1,1143 @@
+#include <arpa/inet.h>
+
+#include <gmock/gmock.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <string>
+#include <sstream>
+
+#include <process/async.hpp>
+#include <process/collect.hpp>
+#include <process/clock.hpp>
+#include <process/defer.hpp>
+#include <process/delay.hpp>
+#include <process/dispatch.hpp>
+#include <process/executor.hpp>
+#include <process/filter.hpp>
+#include <process/future.hpp>
+#include <process/gc.hpp>
+#include <process/gmock.hpp>
+#include <process/gtest.hpp>
+#include <process/process.hpp>
+#include <process/run.hpp>
+#include <process/thread.hpp>
+#include <process/time.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/nothing.hpp>
+#include <stout/os.hpp>
+#include <stout/stringify.hpp>
+
+#include "encoder.hpp"
+
+using namespace process;
+
+using testing::_;
+using testing::Assign;
+using testing::DoAll;
+using testing::Return;
+using testing::ReturnArg;
+
+// TODO(bmahler): Move tests into their own files as appropriate.
+
+TEST(Process, thread)
+{
+ ThreadLocal<ProcessBase>* _process_ = new ThreadLocal<ProcessBase>();
+
+ ProcessBase* process = new ProcessBase();
+
+ ASSERT_TRUE(*(_process_) == NULL);
+
+ (*_process_) = process;
+
+ ASSERT_TRUE(*(_process_) == process);
+ ASSERT_FALSE(*(_process_) == NULL);
+
+ (*_process_) = NULL;
+
+ ASSERT_TRUE(*(_process_) == NULL);
+
+ delete process;
+ delete _process_;
+}
+
+
+TEST(Process, event)
+{
+ Event* event = new TerminateEvent(UPID());
+ EXPECT_FALSE(event->is<MessageEvent>());
+ EXPECT_FALSE(event->is<ExitedEvent>());
+ EXPECT_TRUE(event->is<TerminateEvent>());
+ delete event;
+}
+
+
+TEST(Process, future)
+{
+ Promise<bool> promise;
+ promise.set(true);
+ ASSERT_TRUE(promise.future().isReady());
+ EXPECT_TRUE(promise.future().get());
+}
+
+
+TEST(Process, associate)
+{
+ Promise<bool> promise1;
+ Future<bool> future1(true);
+ promise1.associate(future1);
+ ASSERT_TRUE(promise1.future().isReady());
+ EXPECT_TRUE(promise1.future().get());
+
+ Promise<bool> promise2;
+ Future<bool> future2;
+ promise2.associate(future2);
+ future2.discard();
+ ASSERT_TRUE(promise2.future().isDiscarded());
+
+ Promise<bool> promise3;
+ Promise<bool> promise4;
+ promise3.associate(promise4.future());
+ promise4.fail("associate");
+ ASSERT_TRUE(promise3.future().isFailed());
+ EXPECT_EQ("associate", promise3.future().failure());
+}
+
+
+void onAny(const Future<bool>& future, bool* b)
+{
+ ASSERT_TRUE(future.isReady());
+ *b = future.get();
+}
+
+
+TEST(Process, onAny)
+{
+ bool b = false;
+ Future<bool>(true)
+ .onAny(std::tr1::bind(&onAny, std::tr1::placeholders::_1, &b));
+ EXPECT_TRUE(b);
+}
+
+
+Future<std::string> itoa1(int* const& i)
+{
+ std::ostringstream out;
+ out << *i;
+ return out.str();
+}
+
+
+std::string itoa2(int* const& i)
+{
+ std::ostringstream out;
+ out << *i;
+ return out.str();
+}
+
+
+TEST(Process, then)
+{
+ Promise<int*> promise;
+
+ int i = 42;
+
+ promise.set(&i);
+
+ Future<std::string> future = promise.future()
+ .then(std::tr1::bind(&itoa1, std::tr1::placeholders::_1));
+
+ ASSERT_TRUE(future.isReady());
+ EXPECT_EQ("42", future.get());
+
+ future = promise.future()
+ .then(std::tr1::bind(&itoa2, std::tr1::placeholders::_1));
+
+ ASSERT_TRUE(future.isReady());
+ EXPECT_EQ("42", future.get());
+}
+
+
+Future<bool> readyFuture()
+{
+ return true;
+}
+
+
+Future<bool> failedFuture()
+{
+ return Future<bool>::failed("The value is not positive (or zero)");
+}
+
+
+Future<bool> pendingFuture(Future<bool>* future)
+{
+ return *future; // Keep it pending.
+}
+
+
+Future<std::string> second(const bool& b)
+{
+ return b ? std::string("true") : std::string("false");
+}
+
+
+Future<std::string> third(const std::string& s)
+{
+ return s;
+}
+
+
+TEST(Process, chain)
+{
+ Promise<int*> promise;
+
+ Future<std::string> s = readyFuture()
+ .then(std::tr1::bind(&second, std::tr1::placeholders::_1))
+ .then(std::tr1::bind(&third, std::tr1::placeholders::_1));
+
+ s.await();
+
+ ASSERT_TRUE(s.isReady());
+ EXPECT_EQ("true", s.get());
+
+ s = failedFuture()
+ .then(std::tr1::bind(&second, std::tr1::placeholders::_1))
+ .then(std::tr1::bind(&third, std::tr1::placeholders::_1));
+
+ s.await();
+
+ ASSERT_TRUE(s.isFailed());
+
+ Future<bool> future;
+
+ s = pendingFuture(&future)
+ .then(std::tr1::bind(&second, std::tr1::placeholders::_1))
+ .then(std::tr1::bind(&third, std::tr1::placeholders::_1));
+
+ ASSERT_TRUE(s.isPending());
+ ASSERT_TRUE(future.isPending());
+
+ s.discard();
+
+ future.await();
+
+ ASSERT_TRUE(future.isDiscarded());
+}
+
+
+class SpawnProcess : public Process<SpawnProcess>
+{
+public:
+ MOCK_METHOD0(initialize, void(void));
+ MOCK_METHOD0(finalize, void(void));
+};
+
+
+TEST(Process, spawn)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ SpawnProcess process;
+
+ EXPECT_CALL(process, initialize())
+ .Times(1);
+
+ EXPECT_CALL(process, finalize())
+ .Times(1);
+
+ PID<SpawnProcess> pid = spawn(process);
+
+ ASSERT_FALSE(!pid);
+
+ ASSERT_FALSE(wait(pid, Seconds(0)));
+
+ terminate(pid);
+ wait(pid);
+}
+
+
+class DispatchProcess : public Process<DispatchProcess>
+{
+public:
+ MOCK_METHOD0(func0, void(void));
+ MOCK_METHOD1(func1, bool(bool));
+ MOCK_METHOD1(func2, Future<bool>(bool));
+ MOCK_METHOD1(func3, int(int));
+ MOCK_METHOD2(func4, Future<bool>(bool, int));
+};
+
+
+TEST(Process, dispatch)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ DispatchProcess process;
+
+ EXPECT_CALL(process, func0())
+ .Times(1);
+
+ EXPECT_CALL(process, func1(_))
+ .WillOnce(ReturnArg<0>());
+
+ EXPECT_CALL(process, func2(_))
+ .WillOnce(ReturnArg<0>());
+
+ PID<DispatchProcess> pid = spawn(&process);
+
+ ASSERT_FALSE(!pid);
+
+ dispatch(pid, &DispatchProcess::func0);
+
+ Future<bool> future;
+
+ future = dispatch(pid, &DispatchProcess::func1, true);
+
+ EXPECT_TRUE(future.get());
+
+ future = dispatch(pid, &DispatchProcess::func2, true);
+
+ EXPECT_TRUE(future.get());
+
+ terminate(pid);
+ wait(pid);
+}
+
+
+TEST(Process, defer1)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ DispatchProcess process;
+
+ EXPECT_CALL(process, func0())
+ .Times(1);
+
+ EXPECT_CALL(process, func1(_))
+ .WillOnce(ReturnArg<0>());
+
+ EXPECT_CALL(process, func2(_))
+ .WillOnce(ReturnArg<0>());
+
+ EXPECT_CALL(process, func4(_, _))
+ .WillRepeatedly(ReturnArg<0>());
+
+ PID<DispatchProcess> pid = spawn(&process);
+
+ ASSERT_FALSE(!pid);
+
+ {
+ Deferred<void(void)> func0 =
+ defer(pid, &DispatchProcess::func0);
+ func0();
+ }
+
+ Future<bool> future;
+
+ {
+ Deferred<Future<bool>(void)> func1 =
+ defer(pid, &DispatchProcess::func1, true);
+ future = func1();
+ EXPECT_TRUE(future.get());
+ }
+
+ {
+ Deferred<Future<bool>(void)> func2 =
+ defer(pid, &DispatchProcess::func2, true);
+ future = func2();
+ EXPECT_TRUE(future.get());
+ }
+
+ {
+ Deferred<Future<bool>(void)> func4 =
+ defer(pid, &DispatchProcess::func4, true, 42);
+ future = func4();
+ EXPECT_TRUE(future.get());
+ }
+
+ {
+ Deferred<Future<bool>(bool)> func4 =
+ defer(pid, &DispatchProcess::func4, std::tr1::placeholders::_1, 42);
+ future = func4(false);
+ EXPECT_FALSE(future.get());
+ }
+
+ {
+ Deferred<Future<bool>(int)> func4 =
+ defer(pid, &DispatchProcess::func4, true, std::tr1::placeholders::_1);
+ future = func4(42);
+ EXPECT_TRUE(future.get());
+ }
+
+ // Only take const &!
+
+ terminate(pid);
+ wait(pid);
+}
+
+
+class DeferProcess : public Process<DeferProcess>
+{
+public:
+ Future<std::string> func1(const Future<int>& f)
+ {
+ return f.then(defer(self(), &Self::_func1, std::tr1::placeholders::_1));
+ }
+
+ Future<std::string> func2(const Future<int>& f)
+ {
+ return f.then(defer(self(), &Self::_func2));
+ }
+
+private:
+ Future<std::string> _func1(int i)
+ {
+ return stringify(i);
+ }
+
+ Future<std::string> _func2()
+ {
+ return std::string("42");
+ }
+};
+
+
+TEST(Process, defer2)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ DeferProcess process;
+
+ PID<DeferProcess> pid = spawn(process);
+
+ Future<std::string> f = dispatch(pid, &DeferProcess::func1, 41);
+
+ f.await();
+
+ ASSERT_TRUE(f.isReady());
+ EXPECT_EQ("41", f.get());
+
+ f = dispatch(pid, &DeferProcess::func2, 41);
+
+ f.await();
+
+ ASSERT_TRUE(f.isReady());
+ EXPECT_EQ("42", f.get());
+
+ terminate(pid);
+ wait(pid);
+}
+
+
+template <typename T>
+void set(T* t1, const T& t2)
+{
+ *t1 = t2;
+}
+
+
+TEST(Process, defer3)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ volatile bool bool1 = false;
+ volatile bool bool2 = false;
+
+ Deferred<void(bool)> set1 =
+ defer(std::tr1::function<void(bool)>(
+ std::tr1::bind(&set<volatile bool>,
+ &bool1,
+ std::tr1::placeholders::_1)));
+
+ set1(true);
+
+ Deferred<void(bool)> set2 =
+ defer(std::tr1::function<void(bool)>(
+ std::tr1::bind(&set<volatile bool>,
+ &bool2,
+ std::tr1::placeholders::_1)));
+
+ set2(true);
+
+ while (!bool1);
+ while (!bool2);
+}
+
+
+class HandlersProcess : public Process<HandlersProcess>
+{
+public:
+ HandlersProcess()
+ {
+ install("func", &HandlersProcess::func);
+ }
+
+ MOCK_METHOD2(func, void(const UPID&, const std::string&));
+};
+
+
+TEST(Process, handlers)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ HandlersProcess process;
+
+ EXPECT_CALL(process, func(_, _))
+ .Times(1);
+
+ PID<HandlersProcess> pid = spawn(&process);
+
+ ASSERT_FALSE(!pid);
+
+ post(pid, "func");
+
+ terminate(pid, false);
+ wait(pid);
+}
+
+
+// Tests EXPECT_MESSAGE and EXPECT_DISPATCH and in particular that an
+// event can get dropped before being processed.
+TEST(Process, expect)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ HandlersProcess process;
+
+ EXPECT_CALL(process, func(_, _))
+ .Times(0);
+
+ PID<HandlersProcess> pid = spawn(&process);
+
+ ASSERT_FALSE(!pid);
+
+ Future<Message> message = DROP_MESSAGE("func", _, _);
+
+ post(pid, "func");
+
+ AWAIT_EXPECT_READY(message);
+
+ Future<Nothing> func = DROP_DISPATCH(pid, &HandlersProcess::func);
+
+ dispatch(pid, &HandlersProcess::func, pid, "");
+
+ AWAIT_EXPECT_READY(func);
+
+ terminate(pid, false);
+ wait(pid);
+}
+
+
+// Tests the FutureArg<N> action.
+TEST(Process, action)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ HandlersProcess process;
+
+ PID<HandlersProcess> pid = spawn(&process);
+
+ ASSERT_FALSE(!pid);
+
+ Future<std::string> future1;
+ Future<Nothing> future2;
+ EXPECT_CALL(process, func(_, _))
+ .WillOnce(FutureArg<1>(&future1))
+ .WillOnce(FutureSatisfy(&future2));
+
+ dispatch(pid, &HandlersProcess::func, pid, "hello world");
+
+ AWAIT_EXPECT_EQ("hello world", future1);
+
+ EXPECT_TRUE(future2.isPending());
+
+ dispatch(pid, &HandlersProcess::func, pid, "hello world");
+
+ AWAIT_EXPECT_READY(future2);
+
+ terminate(pid, false);
+ wait(pid);
+}
+
+
+class BaseProcess : public Process<BaseProcess>
+{
+public:
+ virtual void func() = 0;
+ MOCK_METHOD0(foo, void());
+};
+
+
+class DerivedProcess : public BaseProcess
+{
+public:
+ DerivedProcess() {}
+ MOCK_METHOD0(func, void());
+};
+
+
+TEST(Process, inheritance)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ DerivedProcess process;
+
+ EXPECT_CALL(process, func())
+ .Times(2);
+
+ EXPECT_CALL(process, foo())
+ .Times(1);
+
+ PID<DerivedProcess> pid1 = spawn(&process);
+
+ ASSERT_FALSE(!pid1);
+
+ dispatch(pid1, &DerivedProcess::func);
+
+ PID<BaseProcess> pid2(process);
+ PID<BaseProcess> pid3 = pid1;
+
+ ASSERT_EQ(pid2, pid3);
+
+ dispatch(pid3, &BaseProcess::func);
+ dispatch(pid3, &BaseProcess::foo);
+
+ terminate(pid1, false);
+ wait(pid1);
+}
+
+
+TEST(Process, thunk)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ struct Thunk
+ {
+ static int run(int i)
+ {
+ return i;
+ }
+
+ static int run(int i, int j)
+ {
+ return run(i + j);
+ }
+ };
+
+ int result = run(&Thunk::run, 21, 21).get();
+
+ EXPECT_EQ(42, result);
+}
+
+
+class DelegatorProcess : public Process<DelegatorProcess>
+{
+public:
+ DelegatorProcess(const UPID& delegatee)
+ {
+ delegate("func", delegatee);
+ }
+};
+
+
+class DelegateeProcess : public Process<DelegateeProcess>
+{
+public:
+ DelegateeProcess()
+ {
+ install("func", &DelegateeProcess::func);
+ }
+
+ MOCK_METHOD2(func, void(const UPID&, const std::string&));
+};
+
+
+TEST(Process, delegate)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ DelegateeProcess delegatee;
+ DelegatorProcess delegator(delegatee.self());
+
+ EXPECT_CALL(delegatee, func(_, _))
+ .Times(1);
+
+ spawn(&delegator);
+ spawn(&delegatee);
+
+ post(delegator.self(), "func");
+
+ terminate(delegator, false);
+ wait(delegator);
+
+ terminate(delegatee, false);
+ wait(delegatee);
+}
+
+
+class TimeoutProcess : public Process<TimeoutProcess>
+{
+public:
+ MOCK_METHOD0(timeout, void());
+};
+
+
+TEST(Process, delay)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ Clock::pause();
+
+ volatile bool timeoutCalled = false;
+
+ TimeoutProcess process;
+
+ EXPECT_CALL(process, timeout())
+ .WillOnce(Assign(&timeoutCalled, true));
+
+ spawn(process);
+
+ delay(Seconds(5), process.self(), &TimeoutProcess::timeout);
+
+ Clock::advance(Seconds(5));
+
+ while (!timeoutCalled);
+
+ terminate(process);
+ wait(process);
+
+ Clock::resume();
+}
+
+
+class OrderProcess : public Process<OrderProcess>
+{
+public:
+ void order(const PID<TimeoutProcess>& pid)
+ {
+ // TODO(benh): Add a test which uses 'send' instead of dispatch.
+ dispatch(pid, &TimeoutProcess::timeout);
+ }
+};
+
+
+TEST(Process, order)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ Clock::pause();
+
+ TimeoutProcess process1;
+
+ volatile bool timeoutCalled = false;
+
+ EXPECT_CALL(process1, timeout())
+ .WillOnce(Assign(&timeoutCalled, true));
+
+ spawn(process1);
+
+ Time now = Clock::now(&process1);
+
+ Seconds seconds(1);
+
+ Clock::advance(Seconds(1));
+
+ EXPECT_EQ(now, Clock::now(&process1));
+
+ OrderProcess process2;
+ spawn(process2);
+
+ dispatch(process2, &OrderProcess::order, process1.self());
+
+ while (!timeoutCalled);
+
+ EXPECT_EQ(now + seconds, Clock::now(&process1));
+
+ terminate(process1);
+ wait(process1);
+
+ terminate(process2);
+ wait(process2);
+
+ Clock::resume();
+}
+
+
+class DonateProcess : public Process<DonateProcess>
+{
+public:
+ void donate()
+ {
+ DonateProcess process;
+ spawn(process);
+ terminate(process);
+ wait(process);
+ }
+};
+
+
+TEST(Process, donate)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ DonateProcess process;
+ spawn(process);
+
+ dispatch(process, &DonateProcess::donate);
+
+ terminate(process, false);
+ wait(process);
+}
+
+
+class ExitedProcess : public Process<ExitedProcess>
+{
+public:
+ ExitedProcess(const UPID& pid) { link(pid); }
+
+ MOCK_METHOD1(exited, void(const UPID&));
+};
+
+
+TEST(Process, exited)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ UPID pid = spawn(new ProcessBase(), true);
+
+ ExitedProcess process(pid);
+
+ volatile bool exitedCalled = false;
+
+ EXPECT_CALL(process, exited(pid))
+ .WillOnce(Assign(&exitedCalled, true));
+
+ spawn(process);
+
+ terminate(pid);
+
+ while (!exitedCalled);
+
+ terminate(process);
+ wait(process);
+}
+
+
+TEST(Process, select)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ Promise<int> promise1;
+ Promise<int> promise2;
+ Promise<int> promise3;
+ Promise<int> promise4;
+
+ std::set<Future<int> > futures;
+ futures.insert(promise1.future());
+ futures.insert(promise2.future());
+ futures.insert(promise3.future());
+ futures.insert(promise4.future());
+
+ promise1.set(42);
+
+ Future<Future<int> > future = select(futures);
+
+ EXPECT_TRUE(future.await());
+ EXPECT_TRUE(future.isReady());
+ EXPECT_TRUE(future.get().isReady());
+ EXPECT_EQ(42, future.get().get());
+}
+
+
+TEST(Process, collect)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ Promise<int> promise1;
+ Promise<int> promise2;
+ Promise<int> promise3;
+ Promise<int> promise4;
+
+ std::list<Future<int> > futures;
+ futures.push_back(promise1.future());
+ futures.push_back(promise2.future());
+ futures.push_back(promise3.future());
+ futures.push_back(promise4.future());
+
+ promise1.set(1);
+ promise2.set(2);
+ promise3.set(3);
+ promise4.set(4);
+
+ Future<std::list<int> > future = collect(futures);
+
+ EXPECT_TRUE(future.await());
+ EXPECT_TRUE(future.isReady());
+
+ std::list<int> values;
+ values.push_back(1);
+ values.push_back(2);
+ values.push_back(3);
+ values.push_back(4);
+
+ EXPECT_EQ(values, future.get());
+}
+
+
+class SettleProcess : public Process<SettleProcess>
+{
+public:
+ SettleProcess() : calledDispatch(false) {}
+
+ virtual void initialize()
+ {
+ os::sleep(Milliseconds(10));
+ delay(Seconds(0), self(), &SettleProcess::afterDelay);
+ }
+
+ void afterDelay()
+ {
+ dispatch(self(), &SettleProcess::afterDispatch);
+ os::sleep(Milliseconds(10));
+ TimeoutProcess timeoutProcess;
+ spawn(timeoutProcess);
+ terminate(timeoutProcess);
+ wait(timeoutProcess);
+ }
+
+ void afterDispatch()
+ {
+ os::sleep(Milliseconds(10));
+ calledDispatch = true;
+ }
+
+ volatile bool calledDispatch;
+};
+
+
+TEST(Process, settle)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ Clock::pause();
+ SettleProcess process;
+ spawn(process);
+ Clock::settle();
+ ASSERT_TRUE(process.calledDispatch);
+ terminate(process);
+ wait(process);
+ Clock::resume();
+}
+
+
+TEST(Process, pid)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ TimeoutProcess process;
+
+ PID<TimeoutProcess> pid = process;
+}
+
+
+class Listener1 : public Process<Listener1>
+{
+public:
+ virtual void event1() = 0;
+};
+
+
+class Listener2 : public Process<Listener2>
+{
+public:
+ virtual void event2() = 0;
+};
+
+
+class MultipleListenerProcess
+ : public Process<MultipleListenerProcess>,
+ public Listener1,
+ public Listener2
+{
+public:
+ MOCK_METHOD0(event1, void());
+ MOCK_METHOD0(event2, void());
+};
+
+
+TEST(Process, listener)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ MultipleListenerProcess process;
+
+ EXPECT_CALL(process, event1())
+ .Times(1);
+
+ EXPECT_CALL(process, event2())
+ .Times(1);
+
+ spawn(process);
+
+ dispatch(PID<Listener1>(process), &Listener1::event1);
+ dispatch(PID<Listener2>(process), &Listener2::event2);
+
+ terminate(process, false);
+ wait(process);
+}
+
+
+class EventReceiver
+{
+public:
+ MOCK_METHOD1(event1, void(int));
+ MOCK_METHOD1(event2, void(const std::string&));
+};
+
+
+TEST(Process, executor)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ volatile bool event1Called = false;
+ volatile bool event2Called = false;
+
+ EventReceiver receiver;
+
+ EXPECT_CALL(receiver, event1(42))
+ .WillOnce(Assign(&event1Called, true));
+
+ EXPECT_CALL(receiver, event2("event2"))
+ .WillOnce(Assign(&event2Called, true));
+
+ Executor executor;
+
+ Deferred<void(int)> event1 =
+ executor.defer(std::tr1::bind(&EventReceiver::event1,
+ &receiver,
+ std::tr1::placeholders::_1));
+
+ event1(42);
+
+ Deferred<void(const std::string&)> event2 =
+ executor.defer(std::tr1::bind(&EventReceiver::event2,
+ &receiver,
+ std::tr1::placeholders::_1));
+
+ event2("event2");
+
+ while (!event1Called);
+ while (!event2Called);
+}
+
+
+class RemoteProcess : public Process<RemoteProcess>
+{
+public:
+ RemoteProcess()
+ {
+ install("handler", &RemoteProcess::handler);
+ }
+
+ MOCK_METHOD2(handler, void(const UPID&, const std::string&));
+};
+
+
+TEST(Process, remote)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ RemoteProcess process;
+
+ volatile bool handlerCalled = false;
+
+ EXPECT_CALL(process, handler(_, _))
+ .WillOnce(Assign(&handlerCalled, true));
+
+ spawn(process);
+
+ int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+
+ ASSERT_LE(0, s);
+
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = PF_INET;
+ addr.sin_port = htons(process.self().port);
+ addr.sin_addr.s_addr = process.self().ip;
+
+ ASSERT_EQ(0, connect(s, (sockaddr*) &addr, sizeof(addr)));
+
+ Message message;
+ message.name = "handler";
+ message.from = UPID();
+ message.to = process.self();
+
+ const std::string& data = MessageEncoder::encode(&message);
+
+ ASSERT_EQ(data.size(), write(s, data.data(), data.size()));
+
+ ASSERT_EQ(0, close(s));
+
+ while (!handlerCalled);
+
+ terminate(process);
+ wait(process);
+}
+
+
+int foo()
+{
+ return 1;
+}
+
+int foo1(int a)
+{
+ return a;
+}
+
+
+int foo2(int a, int b)
+{
+ return a + b;
+}
+
+
+int foo3(int a, int b, int c)
+{
+ return a + b + c;
+}
+
+
+int foo4(int a, int b, int c, int d)
+{
+ return a + b + c + d;
+}
+
+
+void bar(int a)
+{
+ return;
+}
+
+
+TEST(Process, async)
+{
+ ASSERT_TRUE(GTEST_IS_THREADSAFE);
+
+ // Non-void functions with different no.of args.
+ EXPECT_EQ(1, async(&foo).get());
+ EXPECT_EQ(10, async(&foo1, 10).get());
+ EXPECT_EQ(30, async(&foo2, 10, 20).get());
+ EXPECT_EQ(60, async(&foo3, 10, 20, 30).get());
+ EXPECT_EQ(100, async(&foo4, 10, 20, 30, 40).get());
+
+ // Non-void function with a complex arg.
+ int i = 42;
+ EXPECT_EQ("42", async(&itoa2, &i).get());
+
+ // Non-void function that returns a future.
+ EXPECT_EQ("42", async(&itoa1, &i).get().get());
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/tests/statistics_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/statistics_tests.cpp b/3rdparty/libprocess/src/tests/statistics_tests.cpp
new file mode 100644
index 0000000..8695f45
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/statistics_tests.cpp
@@ -0,0 +1,184 @@
+#include <gmock/gmock.h>
+
+#include <map>
+
+#include <process/clock.hpp>
+#include <process/future.hpp>
+#include <process/gtest.hpp>
+#include <process/statistics.hpp>
+#include <process/time.hpp>
+
+#include <stout/duration.hpp>
+
+using namespace process;
+
+using std::map;
+
+
+TEST(Statistics, set)
+{
+ Statistics statistics(Days(1));
+
+ // Set one using Clock::now() implicitly.
+ statistics.set("test", "statistic", 3.0);
+
+ // Set one using Clock::now() explicitly.
+ Time now = Clock::now();
+ statistics.set("test", "statistic", 4.0, now);
+
+ Future<map<Time, double> > values =
+ statistics.timeseries("test", "statistic");
+
+ AWAIT_ASSERT_READY(values);
+
+ EXPECT_EQ(2, values.get().size());
+
+ EXPECT_GE(Clock::now(), values.get().begin()->first);
+ EXPECT_DOUBLE_EQ(3.0, values.get().begin()->second);
+
+ EXPECT_EQ(1, values.get().count(now));
+ EXPECT_DOUBLE_EQ(4.0, values.get()[now]);
+}
+
+
+TEST(Statistics, truncate)
+{
+ Clock::pause();
+
+ Statistics statistics(Days(1));
+
+ statistics.set("test", "statistic", 3.0);
+
+ Future<map<Time, double> > values =
+ statistics.timeseries("test", "statistic");
+
+ AWAIT_ASSERT_READY(values);
+
+ EXPECT_EQ(1, values.get().size());
+ EXPECT_GE(Clock::now(), values.get().begin()->first);
+ EXPECT_DOUBLE_EQ(3.0, values.get().begin()->second);
+
+ Clock::advance(Days(1) + Seconds(1));
+ Clock::settle();
+
+ statistics.increment("test", "statistic");
+
+ values = statistics.timeseries("test", "statistic");
+
+ AWAIT_ASSERT_READY(values);
+
+ EXPECT_EQ(1, values.get().size());
+ EXPECT_GE(Clock::now(), values.get().begin()->first);
+ EXPECT_DOUBLE_EQ(4.0, values.get().begin()->second);
+
+ Clock::resume();
+}
+
+
+TEST(Statistics, meter) {
+ Statistics statistics(Days(1));
+
+ // Set up a meter, and ensure it captures the expected time rate.
+ Future<Try<Nothing> > meter =
+ statistics.meter("test", "statistic", new meters::TimeRate("metered"));
+
+ AWAIT_ASSERT_READY(meter);
+
+ ASSERT_TRUE(meter.get().isSome());
+
+ Time now = Clock::now();
+ statistics.set("test", "statistic", 1.0, now);
+ statistics.set("test", "statistic", 2.0, Time(now + Seconds(1)));
+ statistics.set("test", "statistic", 4.0, Time(now + Seconds(2)));
+
+ // Check the raw statistic values.
+ Future<map<Time, double> > values =
+ statistics.timeseries("test", "statistic");
+
+ AWAIT_ASSERT_READY(values);
+
+ EXPECT_EQ(3, values.get().size());
+ EXPECT_EQ(1, values.get().count(now));
+ EXPECT_EQ(1, values.get().count(Time(now + Seconds(1))));
+ EXPECT_EQ(1, values.get().count(Time(now + Seconds(2))));
+
+ EXPECT_EQ(1.0, values.get()[now]);
+ EXPECT_EQ(2.0, values.get()[Time(now + Seconds(1))]);
+ EXPECT_EQ(4.0, values.get()[Time(now + Seconds(2))]);
+
+ // Now check the metered values.
+ values = statistics.timeseries("test", "metered");
+
+ AWAIT_ASSERT_READY(values);
+
+ EXPECT_EQ(2, values.get().size());
+ EXPECT_EQ(1, values.get().count(Time(now + Seconds(1))));
+ EXPECT_EQ(1, values.get().count(Time(now + Seconds(2))));
+
+ EXPECT_EQ(0., values.get()[now]);
+ EXPECT_EQ(1.0, values.get()[Time(now + Seconds(1))]); // 100%.
+ EXPECT_EQ(2.0, values.get()[Time(now + Seconds(2))]); // 200%.
+}
+
+
+TEST(Statistics, archive)
+{
+ Clock::pause();
+
+ Statistics statistics(Seconds(10));
+
+ // Create a meter and a statistic for archival.
+ // Set up a meter, and ensure it captures the expected time rate.
+ Future<Try<Nothing> > meter =
+ statistics.meter("test", "statistic", new meters::TimeRate("metered"));
+
+ AWAIT_ASSERT_READY(meter);
+
+ ASSERT_TRUE(meter.get().isSome());
+
+ Time now = Clock::now();
+ statistics.set("test", "statistic", 1.0, now);
+ statistics.set("test", "statistic", 2.0, Time(now + Seconds(1)));
+
+ // Archive and ensure the following:
+ // 1. The statistic will no longer be part of the snapshot.
+ // 2. Any meters associated with this statistic will be removed.
+ // 3. However, the time series will be retained until the window expiration.
+ statistics.archive("test", "statistic");
+
+ // TODO(bmahler): Wait for JSON parsing to verify number 1.
+
+ // Ensure the raw time series is present.
+ Future<map<Time, double> > values =
+ statistics.timeseries("test", "statistic");
+ AWAIT_ASSERT_READY(values);
+ EXPECT_FALSE(values.get().empty());
+
+ // Ensure the metered timeseries is present.
+ values = statistics.timeseries("test", "metered");
+ AWAIT_ASSERT_READY(values);
+ EXPECT_FALSE(values.get().empty());
+
+ // Expire the window and ensure the statistics were removed.
+ Clock::advance(STATISTICS_TRUNCATION_INTERVAL);
+ Clock::settle();
+
+ // Ensure the raw statistics are gone.
+ values = statistics.timeseries("test", "statistic");
+ AWAIT_ASSERT_READY(values);
+ EXPECT_TRUE(values.get().empty());
+
+ // Ensure the metered statistics are gone.
+ values = statistics.timeseries("test", "metered");
+ AWAIT_ASSERT_READY(values);
+ EXPECT_TRUE(values.get().empty());
+
+ // Reactivate the statistic, and make sure the meter is still missing.
+ statistics.set("test", "statistic", 1.0, now);
+
+ values = statistics.timeseries("test", "metered");
+ AWAIT_ASSERT_READY(values);
+ EXPECT_TRUE(values.get().empty());
+
+ Clock::resume();
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/tests/time_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/time_tests.cpp b/3rdparty/libprocess/src/tests/time_tests.cpp
new file mode 100644
index 0000000..a25827e
--- /dev/null
+++ b/3rdparty/libprocess/src/tests/time_tests.cpp
@@ -0,0 +1,46 @@
+#include <gtest/gtest.h>
+
+#include <gmock/gmock.h>
+
+#include <process/clock.hpp>
+#include <process/time.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/gtest.hpp>
+#include <stout/os.hpp>
+
+using namespace process;
+
+
+TEST(TimeTest, Arithmetic)
+{
+ Time t = Time::EPOCH + Weeks(1000);
+ t -= Weeks(1);
+ EXPECT_EQ(Time::EPOCH + Weeks(999), t);
+
+ t += Weeks(2);
+ EXPECT_EQ(Time::EPOCH + Weeks(1001), t);
+
+ EXPECT_EQ(t, Time::EPOCH + Weeks(1000) + Weeks(1));
+ EXPECT_EQ(t, Time::EPOCH + Weeks(1002) - Weeks(1));
+
+ EXPECT_EQ(Weeks(1), (Time::EPOCH + Weeks(1000)) - (Time::EPOCH + Weeks(999)));
+}
+
+
+TEST(TimeTest, Now)
+{
+ Time t1 = Clock::now();
+ os::sleep(Microseconds(10));
+ ASSERT_LT(Microseconds(10), Clock::now() - t1);
+}
+
+
+TEST(TimeTest, Output)
+{
+ EXPECT_EQ("1989-03-02 00:00:00+00:00", stringify(Time::EPOCH + Weeks(1000)));
+ EXPECT_EQ("1989-03-02 00:00:00.000000001+00:00",
+ stringify(Time::EPOCH + Weeks(1000) + Nanoseconds(1)));
+ EXPECT_EQ("1989-03-02 00:00:00.000001000+00:00",
+ stringify(Time::EPOCH + Weeks(1000) + Microseconds(1)));
+}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/timer.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/timer.cpp b/3rdparty/libprocess/src/timer.cpp
new file mode 100644
index 0000000..63c5ac1
--- /dev/null
+++ b/3rdparty/libprocess/src/timer.cpp
@@ -0,0 +1,56 @@
+#include <process/timer.hpp>
+
+#include "timeout.hpp"
+
+namespace process {
+
+class TimerProcess : public Process<TimerProcess>
+{
+public:
+ TimerProcess(double _secs,
+ const UPID& _pid,
+ std::tr1::function<void(ProcessBase*)>* _dispatcher)
+ : secs(_secs), pid(_pid), dispatcher(_dispatcher) {}
+
+protected:
+ virtual void operator () ()
+ {
+ if (receive(secs) == TIMEOUT) {
+ internal::dispatch(pid, dispatcher);
+ } else {
+ delete dispatcher;
+ }
+ }
+
+private:
+ const double secs;
+ const UPID pid;
+ std::tr1::function<void(ProcessBase*)>* dispatcher;
+};
+
+
+static void dispatch()
+
+
+Timer::Timer(double secs,
+ const UPID& pid,
+ std::tr1::function<void(ProcessBase*)>* dispatcher)
+{
+ timer = spawn(new TimerProcess(secs, pid, dispatcher), true);
+}
+
+
+Timer::~Timer()
+{
+ // NOTE: Do not terminate the timer! Some users will simply ignore
+ // saving the timer because they never want to cancel, thus
+ // we can not terminate it here!
+}
+
+
+void Timer::cancel()
+{
+ timeouts::cancel(timeout);
+}
+
+} // namespace process {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/src/timer.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/timer.hpp b/3rdparty/libprocess/src/timer.hpp
new file mode 100644
index 0000000..443b5a0
--- /dev/null
+++ b/3rdparty/libprocess/src/timer.hpp
@@ -0,0 +1,125 @@
+#ifndef TIMER_HPP
+#define TIMER_HPP
+
+#include <ctime>
+#include <iostream>
+#include <iomanip>
+
+class timer
+{
+ friend std::ostream& operator<<(std::ostream& os, timer& t);
+
+private:
+ bool running;
+ clock_t start_clock;
+ time_t start_time;
+ double acc_time;
+
+ double elapsed_time();
+
+public:
+ // 'running' is initially false. A timer needs to be explicitly started
+ // using 'start' or 'restart'
+ timer() : running(false), start_clock(0), start_time(0), acc_time(0) { }
+
+ void start(const char* msg = 0);
+ void restart(const char* msg = 0);
+ void stop(const char* msg = 0);
+ void check(const char* msg = 0);
+
+}; // class timer
+
+//===========================================================================
+// Return the total time that the timer has been in the "running"
+// state since it was first "started" or last "restarted". For
+// "short" time periods (less than an hour), the actual cpu time
+// used is reported instead of the elapsed time.
+
+inline double timer::elapsed_time()
+{
+ time_t acc_sec = time(0) - start_time;
+ if (acc_sec < 3600)
+ return (clock() - start_clock) / (1.0 * CLOCKS_PER_SEC);
+ else
+ return (1.0 * acc_sec);
+
+} // timer::elapsed_time
+
+//===========================================================================
+// Start a timer. If it is already running, let it continue running.
+// Print an optional message.
+
+inline void timer::start(const char* msg)
+{
+ // Print an optional message, something like "Starting timer t";
+ if (msg) std::cout << msg << std::endl;
+
+ // Return immediately if the timer is already running
+ if (running) return;
+
+ // Set timer status to running and set the start time
+ running = true;
+ start_clock = clock();
+ start_time = time(0);
+
+} // timer::start
+
+//===========================================================================
+// Turn the timer off and start it again from 0. Print an optional message.
+
+inline void timer::restart(const char* msg)
+{
+ // Print an optional message, something like "Restarting timer t";
+ if (msg) std::cout << msg << std::endl;
+
+ // Set timer status to running, reset accumulated time, and set start time
+ running = true;
+ acc_time = 0;
+ start_clock = clock();
+ start_time = time(0);
+
+} // timer::restart
+
+//===========================================================================
+// Stop the timer and print an optional message.
+
+inline void timer::stop(const char* msg)
+{
+ // Print an optional message, something like "Stopping timer t";
+ if (msg) std::cout << msg << std::endl;
+
+ // Compute accumulated running time and set timer status to not running
+ if (running) acc_time += elapsed_time();
+ running = false;
+
+} // timer::stop
+
+//===========================================================================
+// Print out an optional message followed by the current timer timing.
+
+inline void timer::check(const char* msg)
+{
+ // Print an optional message, something like "Checking timer t";
+ if (msg) std::cout << msg << " : ";
+
+ std::cout << "Elapsed time [" << std::setiosflags(std::ios::fixed)
+ << std::setprecision(2)
+ << acc_time + (running ? elapsed_time() : 0) << "] seconds\n";
+
+} // timer::check
+
+//===========================================================================
+// Allow timers to be printed to ostreams using the syntax 'os << t'
+// for an ostream 'os' and a timer 't'. For example, "cout << t" will
+// print out the total amount of time 't' has been "running".
+
+inline std::ostream& operator<<(std::ostream& os, timer& t)
+{
+ os << std::setprecision(2) << std::setiosflags(std::ios::fixed)
+ << t.acc_time + (t.running ? t.elapsed_time() : 0);
+ return os;
+}
+
+//===========================================================================
+
+#endif /* TIMER_HPP */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/versions.am
----------------------------------------------------------------------
diff --git a/3rdparty/versions.am b/3rdparty/versions.am
new file mode 100644
index 0000000..5932e1f
--- /dev/null
+++ b/3rdparty/versions.am
@@ -0,0 +1,24 @@
+# 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
+
+# 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. For now, however, we
+# still need to update version numbers in src/python/setup.py.in too!
+
+BOTO_VERSION = 2.0b2
+DISTRIBUTE_VERSION = 0.6.26
+ZOOKEEPER_VERSION = 3.3.4
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/zookeeper-3.3.4.tar.gz
----------------------------------------------------------------------
diff --git a/3rdparty/zookeeper-3.3.4.tar.gz b/3rdparty/zookeeper-3.3.4.tar.gz
new file mode 100644
index 0000000..09d4924
Binary files /dev/null and b/3rdparty/zookeeper-3.3.4.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 6d9ab63..180e48a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -211,8 +211,8 @@ subcomponents is subject to the terms and conditions of the following
licenses.
======================================================================
-For the Boost header files (third_party/boost-1.37.0.tar.gz and
-third_party/libprocess/third_party/boost-1.37.0.tar.gz):
+For the Boost header files
+(3rdparty/libprocess/3rdparty/boost-1.37.0.tar.gz):
======================================================================
Boost Software License - Version 1.0 - August 17th, 2003
@@ -241,7 +241,7 @@ DEALINGS IN THE SOFTWARE.
======================================================================
-For boto (third_party/boto-2.0b2.zip):
+For boto (3rdparty/boto-2.0b2.zip):
======================================================================
Permission is hereby granted, free of charge, to any person obtaining a
@@ -265,7 +265,7 @@ IN THE SOFTWARE.
======================================================================
-For distribute-0.6.26 (third_party/distribute-0.6.26.tar.gz):
+For distribute-0.6.26 (3rdparty/distribute-0.6.26.tar.gz):
======================================================================
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -319,8 +319,7 @@ Agreement.
======================================================================
-For glog-0.3.1 (third_party/glog-0.3.1.tar.gz and
-third_party/libprocess/third_party/glog-0.3.1.tar.gz):
+For glog-0.3.1 (3rdparty/libprocess/3rdparty/glog-0.3.1.tar.gz):
======================================================================
Copyright (c) 2008, Google Inc.
@@ -391,8 +390,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
======================================================================
-For gmock-1.6.0 (third_party/gmock-1.6.0.tar.gz and
-third_party/libprocess/third_party/gmock-1.6.0.tar.gz):
+For gmock-1.6.0 (3rdparty/libprocess/3rdparty/gmock-1.6.0.tar.gz):
======================================================================
Copyright 2008, Google Inc.
@@ -426,7 +424,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
======================================================================
-For leveldb (third_party/leveldb.tar.gz):
+For leveldb (3rdparty/leveldb.tar.gz):
======================================================================
Copyright (c) 2011 The LevelDB Authors. All rights reserved.
@@ -459,7 +457,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
======================================================================
-For protobuf-2.3.0 (third_party/protobuf-2.3.0.tar.gz):
+For protobuf-2.3.0
+(3rdparty/libprocess/3rdparty/protobuf-2.3.0.tar.gz):
======================================================================
Copyright 2008, Google Inc.
@@ -498,7 +497,7 @@ support library is itself covered by the above license.
======================================================================
-For libev-3.8 (third_party/libprocess/third_party/libev.tar.gz):
+For libev-3.8 (3rdparty/libprocess/3rdparty/libev.tar.gz):
======================================================================
All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann.
@@ -541,7 +540,7 @@ file under either the BSD or the GPL.
======================================================================
For http-parser
-(third_party/libprocess/third_party/ry-http-parser-1c3624a.tar.gz):
+(3rdparty/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz):
======================================================================
Copyright 2009,2010 Ryan Dahl <ry...@tinyclouds.org>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/Makefile.am
----------------------------------------------------------------------
diff --git a/Makefile.am b/Makefile.am
index 3374da4..8e7a32f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,7 +18,7 @@ ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = foreign
-SUBDIRS = . third_party src ec2 hadoop
+SUBDIRS = . 3rdparty src ec2 hadoop
EXTRA_DIST =
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/bootstrap
----------------------------------------------------------------------
diff --git a/bootstrap b/bootstrap
index cefc2ab..fe542a0 100755
--- a/bootstrap
+++ b/bootstrap
@@ -10,7 +10,7 @@ fi
# Note that we don't use '--no-recursive' becuase older versions of
# autoconf/autoreconf bail with that option. Unfortunately this means
-# that we'll modify a lot of files in third_party/libprocess, but that
+# that we'll modify a lot of files in 3rdparty/libprocess, but that
# may change in the future.
autoreconf --install -Wall --verbose "${@}"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index c3b5a05..e76f775 100644
--- a/configure.ac
+++ b/configure.ac
@@ -51,15 +51,15 @@ LT_OUTPUT
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
+# Save the configure arguments so we can pass them to any third-party
# libraries that we might run configure on (see
-# third_party/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.
+# 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)
-# Force configured third_party libraries (currently only libprocess)
+# Force configured third-party libraries (currently only libprocess)
# to only build a static library with position independent code so
# that we can produce a final shared library which includes everything
# necessary (and only install that).
@@ -74,13 +74,13 @@ ac_configure_args="$ac_configure_args_post"
AC_CONFIG_COMMANDS_PRE([ac_configure_args="$ac_configure_args_pre"])
AC_CONFIG_COMMANDS_POST([ac_configure_args="$ac_configure_args_post"])
-AC_CONFIG_SUBDIRS([third_party/libprocess])
+AC_CONFIG_SUBDIRS([3rdparty/libprocess])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([ec2/Makefile])
AC_CONFIG_FILES([hadoop/Makefile])
AC_CONFIG_FILES([src/Makefile])
-AC_CONFIG_FILES([third_party/Makefile])
+AC_CONFIG_FILES([3rdparty/Makefile])
AC_CONFIG_FILES([bin/mesos-build-env.sh])
AC_CONFIG_FILES([bin/mesos-local.sh], [chmod +x bin/mesos-local.sh])
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 738c18f..a91daae 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,21 +19,21 @@
# master/http.cpp and slave/http.cpp.
AUTOMAKE_OPTIONS = subdir-objects
-include ../third_party/versions.am
-include ../third_party/libprocess/third_party/versions.am
+include ../3rdparty/versions.am
+include ../3rdparty/libprocess/3rdparty/versions.am
# TODO(charles): Move these into an included automakefile and have
# them include $(top_builddir) as appropriate.
-DISTRIBUTE = third_party/distribute-$(DISTRIBUTE_VERSION)
-LEVELDB = third_party/leveldb
-ZOOKEEPER = third_party/zookeeper-$(ZOOKEEPER_VERSION)/src/c
-LIBPROCESS = third_party/libprocess
-STOUT = $(LIBPROCESS)/third_party/stout
-BOOST = $(LIBPROCESS)/third_party/boost-$(BOOST_VERSION)
-GLOG = $(LIBPROCESS)/third_party/glog-$(GLOG_VERSION)
-GMOCK = $(LIBPROCESS)/third_party/gmock-$(GMOCK_VERSION)
+DISTRIBUTE = 3rdparty/distribute-$(DISTRIBUTE_VERSION)
+LEVELDB = 3rdparty/leveldb
+ZOOKEEPER = 3rdparty/zookeeper-$(ZOOKEEPER_VERSION)/src/c
+LIBPROCESS = 3rdparty/libprocess
+STOUT = $(LIBPROCESS)/3rdparty/stout
+BOOST = $(LIBPROCESS)/3rdparty/boost-$(BOOST_VERSION)
+GLOG = $(LIBPROCESS)/3rdparty/glog-$(GLOG_VERSION)
+GMOCK = $(LIBPROCESS)/3rdparty/gmock-$(GMOCK_VERSION)
GTEST = $(GMOCK)/gtest
-PROTOBUF = $(LIBPROCESS)/third_party/protobuf-$(PROTOBUF_VERSION)
+PROTOBUF = $(LIBPROCESS)/3rdparty/protobuf-$(PROTOBUF_VERSION)
# Unfortunatley, 'pkglibexecdir' and 'pkglocalstatedir' are not set
@@ -100,7 +100,7 @@ endif
# README: we build the Mesos library out of a collection of
# convenience libraries (that is, libraries that do not get installed
# but we can use as building blocks to vary compile flags as necessary
-# and then aggregate into final archives): libmesos_no_third_party.la
+# and then aggregate into final archives): libmesos_no_3rdparty.la
# libbuild.la, liblog.la, libjava.la.
# First, let's define necessary protocol buffer files.
@@ -155,14 +155,14 @@ $(PYTHON_PROTOS): $(MESOS_PROTO)
# exclude third party libraries so setuptools/distribute can build a
# self-contained Python library and statically link in the third party
# libraries themselves.
-noinst_LTLIBRARIES += libmesos_no_third_party.la
+noinst_LTLIBRARIES += libmesos_no_3rdparty.la
-nodist_libmesos_no_third_party_la_SOURCES = \
+nodist_libmesos_no_3rdparty_la_SOURCES = \
$(CXX_PROTOS) \
$(MESSAGES_PROTOS) \
$(REGISTRY_PROTOS)
-libmesos_no_third_party_la_SOURCES = \
+libmesos_no_3rdparty_la_SOURCES = \
sched/sched.cpp \
local/local.cpp \
master/constants.cpp \
@@ -203,16 +203,16 @@ pkginclude_HEADERS = $(top_srcdir)/include/mesos/executor.hpp \
nodist_pkginclude_HEADERS = ../include/mesos/mesos.hpp mesos.pb.h
if OS_LINUX
- libmesos_no_third_party_la_SOURCES += slave/cgroups_isolator.cpp
- libmesos_no_third_party_la_SOURCES += linux/cgroups.cpp
- libmesos_no_third_party_la_SOURCES += linux/fs.cpp
+ libmesos_no_3rdparty_la_SOURCES += slave/cgroups_isolator.cpp
+ libmesos_no_3rdparty_la_SOURCES += linux/cgroups.cpp
+ libmesos_no_3rdparty_la_SOURCES += linux/fs.cpp
else
EXTRA_DIST += slave/cgroups_isolator.cpp
EXTRA_DIST += linux/cgroups.cpp
EXTRA_DIST += linux/fs.cpp
endif
-libmesos_no_third_party_la_SOURCES += common/attributes.hpp \
+libmesos_no_3rdparty_la_SOURCES += common/attributes.hpp \
common/build.hpp common/date_utils.hpp common/factory.hpp \
common/protobuf_utils.hpp \
common/lock.hpp common/resources.hpp common/process_utils.hpp \
@@ -244,9 +244,9 @@ libmesos_no_third_party_la_SOURCES += common/attributes.hpp \
zookeeper/group.hpp zookeeper/watcher.hpp \
zookeeper/zookeeper.hpp zookeeper/url.hpp
-libmesos_no_third_party_la_CPPFLAGS = $(MESOS_CPPFLAGS)
+libmesos_no_3rdparty_la_CPPFLAGS = $(MESOS_CPPFLAGS)
-libmesos_no_third_party_la_LIBADD = # Initialized to enable using +=.
+libmesos_no_3rdparty_la_LIBADD = # Initialized to enable using +=.
# Convenience library that *always* gets rebuilt to ensure accurate info.
noinst_LTLIBRARIES += libbuild.la
@@ -265,7 +265,7 @@ BUILD_FLAGS = $(echo $(MESOS_CPPFLAGS) $(CPPFLAGS) | sed 's/\"/\\\"/g') \
libbuild_la_CPPFLAGS += -DBUILD_FLAGS="\"$$BUILD_FLAGS\""
-libmesos_no_third_party_la_LIBADD += libbuild.la
+libmesos_no_3rdparty_la_LIBADD += libbuild.la
# Convenience library for building the replicated log in order to
@@ -277,7 +277,7 @@ liblog_la_SOURCES += log/coordinator.hpp log/replica.hpp log/log.hpp \
nodist_liblog_la_SOURCES = $(LOG_PROTOS)
liblog_la_CPPFLAGS = -I../$(LEVELDB)/include $(MESOS_CPPFLAGS)
-libmesos_no_third_party_la_LIBADD += liblog.la
+libmesos_no_3rdparty_la_LIBADD += liblog.la
# Convenience library for building "state" abstraction in order to
@@ -295,7 +295,7 @@ libstate_la_SOURCES += \
nodist_libstate_la_SOURCES = $(STATE_PROTOS)
libstate_la_CPPFLAGS = -I../$(LEVELDB)/include $(MESOS_CPPFLAGS)
-libmesos_no_third_party_la_LIBADD += libstate.la
+libmesos_no_3rdparty_la_LIBADD += libstate.la
# The final result!
lib_LTLIBRARIES += libmesos.la
@@ -309,7 +309,7 @@ libmesos_la_LDFLAGS = -release $(PACKAGE_VERSION) -shared
libmesos_la_LIBTOOLFLAGS = --tag=CXX
# Add the convenience library.
-libmesos_la_LIBADD = libmesos_no_third_party.la
+libmesos_la_LIBADD = libmesos_no_3rdparty.la
# For non-convenience libraries we need to link them in to make the shared
# library each time. (Currently, we don't support platforms where this is not
@@ -319,7 +319,7 @@ libmesos_la_LIBADD += ../$(GLOG)/libglog.la
# We need to directly include the leveldb library in order to avoid
# the installed libmesos.la file to include leveldb in
-# 'dependency_libs' (via '-L../third_party/leveldb -lleveldb').
+# 'dependency_libs' (via '-L../3rdparty/leveldb -lleveldb').
libmesos_la_LIBADD += ../$(LEVELDB)/libleveldb.a
if WITH_INCLUDED_ZOOKEEPER
@@ -395,7 +395,7 @@ nobase_dist_webui_DATA += \
# Need to distribute/install webui images.
nobase_dist_webui_DATA += webui/master/static/loading.gif
-# Need to distribute/install third_party javascript.
+# Need to distribute/install third-party javascript.
nobase_dist_webui_DATA += \
webui/master/static/angular-1.0.0rc8.js \
webui/master/static/angular-1.0.0rc8.min.js \
@@ -520,7 +520,7 @@ if HAS_JAVA
# Protocol buffers JAR.
PROTOBUF_JAR = ../protobuf-$(PROTOBUF_VERSION).jar
-# TODO(charles): Move into third_party/Makefile.am.
+# TODO(charles): Move into 3rdparty/Makefile.am.
$(PROTOBUF_JAR): # TODO(charles): Specify dependencies for the jar.
@echo "Building protobuf-$(PROTOBUF_VERSION).jar ..."
$(MKDIR_P) ../$(PROTOBUF)/java/src/main/java
@@ -591,7 +591,7 @@ libjava_la_DEPENDENCIES = $(MESOS_PROTO)
libjava_la_LIBADD = $(JAVA_LDFLAGS)
-# We don't add libjava.la to libmesos_no_third_party.la so we don't
+# We don't add libjava.la to libmesos_no_3rdparty.la so we don't
# include the JNI bindings in the Python egg (but we might want to
# reconsider this in the future). We also need to add the JAVA_LDFLAGS
# to libmesos.la so on Linux we set the rpath for libmesos.so.
@@ -700,8 +700,8 @@ $(PROTOBUF_EGG):
CLEANFILES += $(PROTOBUF_EGG)
-# This builds a Python egg against libmesos_no_third_party.a that is
-# self-contained. It currently depends on the libraries in third_party
+# This builds a Python egg against libmesos_no_3rdparty.a that is
+# self-contained. It currently depends on the libraries in 3rdparty
# being built as .a's. (If this is changed, the setup.py will need to
# be edited).
@@ -718,7 +718,7 @@ CLEANFILES += $(PROTOBUF_EGG)
MESOS_EGG = python/dist/mesos-$(PACKAGE_VERSION)$(PYTHON_EGG_POSTFIX).egg
$(MESOS_EGG): python/setup.py $(srcdir)/python/src/mesos.py \
- $(PYTHON_PROTOS) libmesos_no_third_party.la \
+ $(PYTHON_PROTOS) libmesos_no_3rdparty.la \
$(PROTOBUF_EGG)
@echo "Building Mesos Python egg ..."
@if test "$(top_srcdir)" != "$(top_builddir)"; then \
@@ -823,7 +823,7 @@ mesos_tests_CPPFLAGS += -DBUILD_DIR=\"$(abs_top_builddir)\"
mesos_tests_CPPFLAGS += -I../$(GTEST)/include
mesos_tests_CPPFLAGS += -I../$(GMOCK)/include
-mesos_tests_LDADD = ../$(LIBPROCESS)/third_party/libgmock.la libmesos.la
+mesos_tests_LDADD = ../$(LIBPROCESS)/3rdparty/libgmock.la libmesos.la
mesos_tests_DEPENDENCIES = # Initialized to allow += below.
[35/35] git commit: Replaced Mesos CHECK_SOME with stout CHECK_SOME.
Posted by be...@apache.org.
Replaced Mesos CHECK_SOME with stout CHECK_SOME.
Review: https://reviews.apache.org/r/11473
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/5307934e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/5307934e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/5307934e
Branch: refs/heads/master
Commit: 5307934ef024015f62a4ff641e984724e7b13b5c
Parents: 7239579
Author: Benjamin Hindman <be...@twitter.com>
Authored: Mon May 27 12:11:34 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:20:25 2013 -0700
----------------------------------------------------------------------
src/Makefile.am | 2 +-
src/java/jni/org_apache_mesos_Log.cpp | 1 +
src/log/coordinator.cpp | 1 +
src/log/log.cpp | 1 +
src/log/log.hpp | 1 +
src/log/main.cpp | 1 +
src/log/replica.cpp | 1 +
src/logging/check_some.hpp | 107 --------------------
src/logging/logging.hpp | 1 -
src/master/hierarchical_allocator_process.hpp | 1 +
src/master/main.cpp | 1 +
src/master/master.cpp | 1 +
src/slave/cgroups_isolator.cpp | 3 +-
src/slave/main.cpp | 1 +
src/slave/paths.hpp | 1 +
src/slave/process_isolator.cpp | 1 +
src/slave/reaper.cpp | 3 +-
src/slave/slave.cpp | 1 +
src/slave/status_update_manager.cpp | 15 ++--
src/tests/environment.cpp | 1 +
src/tests/flags.hpp | 1 +
src/tests/mesos.cpp | 3 +-
src/tests/paths_tests.cpp | 1 +
src/tests/script.cpp | 3 +-
src/tests/zookeeper.cpp | 1 +
src/tests/zookeeper_test_server.cpp | 1 +
src/zookeeper/group.cpp | 1 +
27 files changed, 32 insertions(+), 124 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index a91daae..e67b342 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -221,7 +221,7 @@ libmesos_no_3rdparty_la_SOURCES += common/attributes.hpp \
detector/detector.hpp examples/utils.hpp files/files.hpp \
launcher/launcher.hpp linux/cgroups.hpp \
linux/fs.hpp local/flags.hpp local/local.hpp \
- logging/check_some.hpp logging/flags.hpp logging/logging.hpp \
+ logging/flags.hpp logging/logging.hpp \
master/allocator.hpp \
master/constants.hpp master/drf_sorter.hpp master/flags.hpp \
master/hierarchical_allocator_process.hpp master/http.hpp \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/java/jni/org_apache_mesos_Log.cpp
----------------------------------------------------------------------
diff --git a/src/java/jni/org_apache_mesos_Log.cpp b/src/java/jni/org_apache_mesos_Log.cpp
index c93f096..36c636d 100644
--- a/src/java/jni/org_apache_mesos_Log.cpp
+++ b/src/java/jni/org_apache_mesos_Log.cpp
@@ -20,6 +20,7 @@
#include <process/timeout.hpp>
+#include <stout/check.hpp>
#include <stout/duration.hpp>
#include "log/log.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/log/coordinator.cpp
----------------------------------------------------------------------
diff --git a/src/log/coordinator.cpp b/src/log/coordinator.cpp
index cec3ec9..6e6466f 100644
--- a/src/log/coordinator.cpp
+++ b/src/log/coordinator.cpp
@@ -21,6 +21,7 @@
#include <process/dispatch.hpp>
#include <process/future.hpp>
+#include <stout/check.hpp>
#include <stout/duration.hpp>
#include <stout/error.hpp>
#include <stout/foreach.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/log/log.cpp
----------------------------------------------------------------------
diff --git a/src/log/log.cpp b/src/log/log.cpp
index 6aa45bd..aea06e7 100644
--- a/src/log/log.cpp
+++ b/src/log/log.cpp
@@ -47,6 +47,7 @@
#include <process/process.hpp>
#include <process/run.hpp>
+#include <stout/check.hpp>
#include <stout/duration.hpp>
#include <stout/fatal.hpp>
#include <stout/foreach.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/log/log.hpp
----------------------------------------------------------------------
diff --git a/src/log/log.hpp b/src/log/log.hpp
index 7fb0c4b..77edc7a 100644
--- a/src/log/log.hpp
+++ b/src/log/log.hpp
@@ -26,6 +26,7 @@
#include <process/process.hpp>
#include <process/timeout.hpp>
+#include <stout/check.hpp>
#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/none.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/log/main.cpp
----------------------------------------------------------------------
diff --git a/src/log/main.cpp b/src/log/main.cpp
index 18a1b23..f07bd10 100644
--- a/src/log/main.cpp
+++ b/src/log/main.cpp
@@ -22,6 +22,7 @@
#include <process/process.hpp>
+#include <stout/check.hpp>
#include <stout/flags.hpp>
#include <stout/foreach.hpp>
#include <stout/none.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/log/replica.cpp
----------------------------------------------------------------------
diff --git a/src/log/replica.cpp b/src/log/replica.cpp
index c1a4689..59a6ff3 100644
--- a/src/log/replica.cpp
+++ b/src/log/replica.cpp
@@ -27,6 +27,7 @@
#include <process/dispatch.hpp>
#include <process/protobuf.hpp>
+#include <stout/check.hpp>
#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/none.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/logging/check_some.hpp
----------------------------------------------------------------------
diff --git a/src/logging/check_some.hpp b/src/logging/check_some.hpp
deleted file mode 100644
index cbfd78b..0000000
--- a/src/logging/check_some.hpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * 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 __LOGGING_CHECK_SOME_HPP__
-#define __LOGGING_CHECK_SOME_HPP__
-
-#include <ostream>
-#include <sstream>
-#include <string>
-
-#include <glog/logging.h> // Includes LOG(*), PLOG(*), CHECK, etc.
-
-#include <stout/none.hpp>
-#include <stout/option.hpp>
-#include <stout/result.hpp>
-#include <stout/try.hpp>
-
-// Provides a CHECK_SOME macro, akin to CHECK.
-// This appends the error if possible to the end of the log message, so there's
-// no need to append the error message explicitly.
-#define CHECK_SOME(expression) \
- for (const Option<std::string>& _error = _check(expression); \
- _error.isSome();) \
- _CheckSome(__FILE__, __LINE__, #expression, _error.get()).stream() \
-
-// Private structs/functions used for CHECK_SOME.
-
-template <typename T>
-Option<std::string> _check(const Option<T>& o)
-{
- if (o.isNone()) {
- return Option<std::string>::some("is NONE");
- }
- return None();
-}
-
-
-template <typename T>
-Option<std::string> _check(const Try<T>& t)
-{
- if (t.isError()) {
- return t.error();
- }
- return None();
-}
-
-
-template <typename T>
-Option<std::string> _check(const Result<T>& r)
-{
- if (r.isError()) {
- return r.error();
- } else if (r.isNone()) {
- return Option<std::string>::some("is NONE");
- }
- return None();
-}
-
-
-struct _CheckSome
-{
- _CheckSome(const char* _file,
- int _line,
- const char* _expression,
- const std::string& _error)
- : file(_file),
- line(_line),
- expression(_expression),
- error(_error)
- {
- out << "CHECK_SOME(" << expression << "): ";
- }
-
- ~_CheckSome()
- {
- out << error;
- google::LogMessageFatal(file.c_str(), line).stream() << out.str();
- }
-
- std::ostream& stream()
- {
- return out;
- }
-
- const std::string file;
- const int line;
- const std::string expression;
- const std::string error;
- std::ostringstream out;
-};
-
-#endif // __LOGGING_CHECK_SOME_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/logging/logging.hpp
----------------------------------------------------------------------
diff --git a/src/logging/logging.hpp b/src/logging/logging.hpp
index 56fbbd4..3c24211 100644
--- a/src/logging/logging.hpp
+++ b/src/logging/logging.hpp
@@ -23,7 +23,6 @@
#include <glog/logging.h> // Includes LOG(*), PLOG(*), CHECK, etc.
-#include "logging/check_some.hpp"
#include "logging/flags.hpp"
namespace mesos {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/master/hierarchical_allocator_process.hpp
----------------------------------------------------------------------
diff --git a/src/master/hierarchical_allocator_process.hpp b/src/master/hierarchical_allocator_process.hpp
index ebd97e4..28a7879 100644
--- a/src/master/hierarchical_allocator_process.hpp
+++ b/src/master/hierarchical_allocator_process.hpp
@@ -23,6 +23,7 @@
#include <process/id.hpp>
#include <process/timeout.hpp>
+#include <stout/check.hpp>
#include <stout/duration.hpp>
#include <stout/hashmap.hpp>
#include <stout/stopwatch.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/master/main.cpp
----------------------------------------------------------------------
diff --git a/src/master/main.cpp b/src/master/main.cpp
index 79a912c..3c1cf4c 100644
--- a/src/master/main.cpp
+++ b/src/master/main.cpp
@@ -18,6 +18,7 @@
#include <mesos/mesos.hpp>
+#include <stout/check.hpp>
#include <stout/flags.hpp>
#include <stout/nothing.hpp>
#include <stout/os.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index cbc40e1..d031b95 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -26,6 +26,7 @@
#include <process/id.hpp>
#include <process/run.hpp>
+#include <stout/check.hpp>
#include <stout/multihashmap.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/slave/cgroups_isolator.cpp
----------------------------------------------------------------------
diff --git a/src/slave/cgroups_isolator.cpp b/src/slave/cgroups_isolator.cpp
index 8e8e99e..9b3a3a5 100644
--- a/src/slave/cgroups_isolator.cpp
+++ b/src/slave/cgroups_isolator.cpp
@@ -34,6 +34,7 @@
#include <process/dispatch.hpp>
#include <stout/bytes.hpp>
+#include <stout/check.hpp>
#include <stout/duration.hpp>
#include <stout/error.hpp>
#include <stout/exit.hpp>
@@ -56,8 +57,6 @@
#include "linux/cgroups.hpp"
-#include "logging/check_some.hpp"
-
#include "slave/cgroups_isolator.hpp"
#include "slave/state.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/slave/main.cpp
----------------------------------------------------------------------
diff --git a/src/slave/main.cpp b/src/slave/main.cpp
index 1d3431f..750a127 100644
--- a/src/slave/main.cpp
+++ b/src/slave/main.cpp
@@ -18,6 +18,7 @@
#include <mesos/mesos.hpp>
+#include <stout/check.hpp>
#include <stout/flags.hpp>
#include <stout/nothing.hpp>
#include <stout/os.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/slave/paths.hpp
----------------------------------------------------------------------
diff --git a/src/slave/paths.hpp b/src/slave/paths.hpp
index 3ac6f13..9d2a2a4 100644
--- a/src/slave/paths.hpp
+++ b/src/slave/paths.hpp
@@ -21,6 +21,7 @@
#include <list>
+#include <stout/check.hpp>
#include <stout/foreach.hpp>
#include <stout/format.hpp>
#include <stout/fs.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/slave/process_isolator.cpp
----------------------------------------------------------------------
diff --git a/src/slave/process_isolator.cpp b/src/slave/process_isolator.cpp
index 477af4e..d4f7b76 100644
--- a/src/slave/process_isolator.cpp
+++ b/src/slave/process_isolator.cpp
@@ -32,6 +32,7 @@
#include <process/dispatch.hpp>
#include <process/id.hpp>
+#include <stout/check.hpp>
#include <stout/exit.hpp>
#include <stout/foreach.hpp>
#include <stout/nothing.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/slave/reaper.cpp
----------------------------------------------------------------------
diff --git a/src/slave/reaper.cpp b/src/slave/reaper.cpp
index 5a6de5a..1d826d1 100644
--- a/src/slave/reaper.cpp
+++ b/src/slave/reaper.cpp
@@ -25,6 +25,7 @@
#include <process/dispatch.hpp>
#include <process/id.hpp>
+#include <stout/check.hpp>
#include <stout/foreach.hpp>
#include <stout/nothing.hpp>
#include <stout/os.hpp>
@@ -32,8 +33,6 @@
#include <stout/utils.hpp>
-#include "logging/check_some.hpp"
-
#include "slave/reaper.hpp"
using namespace process;
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 25c91d9..e905ab3 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -32,6 +32,7 @@
#include <process/id.hpp>
#include <stout/bytes.hpp>
+#include <stout/check.hpp>
#include <stout/duration.hpp>
#include <stout/exit.hpp>
#include <stout/fs.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/slave/status_update_manager.cpp
----------------------------------------------------------------------
diff --git a/src/slave/status_update_manager.cpp b/src/slave/status_update_manager.cpp
index c6866dc..9e9e4e2 100644
--- a/src/slave/status_update_manager.cpp
+++ b/src/slave/status_update_manager.cpp
@@ -20,14 +20,15 @@
#include <process/process.hpp>
#include <process/timer.hpp>
-#include "common/protobuf_utils.hpp"
+#include <stout/check.hpp>
+#include <stout/foreach.hpp>
+#include <stout/hashmap.hpp>
+#include <stout/hashset.hpp>
+#include <stout/protobuf.hpp>
+#include <stout/utils.hpp>
+#include <stout/uuid.hpp>
-#include "stout/foreach.hpp"
-#include "stout/hashmap.hpp"
-#include "stout/hashset.hpp"
-#include "stout/protobuf.hpp"
-#include "stout/utils.hpp"
-#include "stout/uuid.hpp"
+#include "common/protobuf_utils.hpp"
#include "slave/constants.hpp"
#include "slave/flags.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/tests/environment.cpp
----------------------------------------------------------------------
diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp
index 125c306..24227c5 100644
--- a/src/tests/environment.cpp
+++ b/src/tests/environment.cpp
@@ -24,6 +24,7 @@
#include <process/gmock.hpp>
#include <process/gtest.hpp>
+#include <stout/check.hpp>
#include <stout/error.hpp>
#include <stout/exit.hpp>
#include <stout/os.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/tests/flags.hpp
----------------------------------------------------------------------
diff --git a/src/tests/flags.hpp b/src/tests/flags.hpp
index b229e1f..071f138 100644
--- a/src/tests/flags.hpp
+++ b/src/tests/flags.hpp
@@ -21,6 +21,7 @@
#include <string>
+#include <stout/check.hpp>
#include <stout/flags.hpp>
#include <stout/os.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/tests/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.cpp b/src/tests/mesos.cpp
index 4ddf032..d811267 100644
--- a/src/tests/mesos.cpp
+++ b/src/tests/mesos.cpp
@@ -1,3 +1,4 @@
+#include <stout/check.hpp>
#include <stout/foreach.hpp>
#include <stout/os.hpp>
#include <stout/result.hpp>
@@ -6,8 +7,6 @@
#include "linux/cgroups.hpp"
#endif
-#include "logging/logging.hpp"
-
#include "tests/environment.hpp"
#include "tests/flags.hpp"
#include "tests/isolator.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/tests/paths_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/paths_tests.cpp b/src/tests/paths_tests.cpp
index 655e9ce..40c644c 100644
--- a/src/tests/paths_tests.cpp
+++ b/src/tests/paths_tests.cpp
@@ -18,6 +18,7 @@
#include <gtest/gtest.h>
+#include <stout/check.hpp>
#include <stout/os.hpp>
#include <stout/protobuf.hpp>
#include <stout/stringify.hpp>
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/tests/script.cpp
----------------------------------------------------------------------
diff --git a/src/tests/script.cpp b/src/tests/script.cpp
index 74ce91a..e72eea6 100644
--- a/src/tests/script.cpp
+++ b/src/tests/script.cpp
@@ -24,12 +24,11 @@
#include <string>
+#include <stout/check.hpp>
#include <stout/os.hpp>
#include <stout/path.hpp>
#include <stout/strings.hpp>
-#include "logging/logging.hpp"
-
#include "tests/environment.hpp"
#include "tests/flags.hpp"
#include "tests/script.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/tests/zookeeper.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper.cpp b/src/tests/zookeeper.cpp
index 62d93b5..8bb4901 100644
--- a/src/tests/zookeeper.cpp
+++ b/src/tests/zookeeper.cpp
@@ -29,6 +29,7 @@
#include <jvm/org/apache/log4j.hpp>
#include <jvm/org/apache/log4j.hpp>
+#include <stout/check.hpp>
#include <stout/lambda.hpp>
#include "common/lock.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/tests/zookeeper_test_server.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper_test_server.cpp b/src/tests/zookeeper_test_server.cpp
index 8051b4d..0b22f31 100644
--- a/src/tests/zookeeper_test_server.cpp
+++ b/src/tests/zookeeper_test_server.cpp
@@ -23,6 +23,7 @@
#include <jvm/org/apache/zookeeper.hpp>
+#include <stout/check.hpp>
#include <stout/os.hpp>
#include "logging/logging.hpp"
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/5307934e/src/zookeeper/group.cpp
----------------------------------------------------------------------
diff --git a/src/zookeeper/group.cpp b/src/zookeeper/group.cpp
index c1a587a..cd58d23 100644
--- a/src/zookeeper/group.cpp
+++ b/src/zookeeper/group.cpp
@@ -8,6 +8,7 @@
#include <process/dispatch.hpp>
#include <process/process.hpp>
+#include <stout/check.hpp>
#include <stout/duration.hpp>
#include <stout/error.hpp>
#include <stout/none.hpp>
[17/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/gtest.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/gtest.hpp b/third_party/libprocess/include/process/gtest.hpp
deleted file mode 100644
index 8473452..0000000
--- a/third_party/libprocess/include/process/gtest.hpp
+++ /dev/null
@@ -1,338 +0,0 @@
-#ifndef __PROCESS_GTEST_HPP__
-#define __PROCESS_GTEST_HPP__
-
-#include <gtest/gtest.h>
-
-#include <string>
-
-#include <process/clock.hpp>
-#include <process/future.hpp>
-#include <process/http.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/option.hpp>
-
-namespace process {
-
-// A simple test event listener that makes sure to resume the clock
-// after each test even if the previous test had a partial result
-// (i.e., an ASSERT_* failed).
-class ClockTestEventListener : public ::testing::EmptyTestEventListener
-{
-public:
- // Returns the singleton instance of the listener.
- static ClockTestEventListener* instance()
- {
- static ClockTestEventListener* listener = new ClockTestEventListener();
- return listener;
- }
-
- virtual void OnTestEnd(const ::testing::TestInfo&)
- {
- if (process::Clock::paused()) {
- process::Clock::resume();
- }
- }
-private:
- ClockTestEventListener() {}
-};
-
-} // namespace process {
-
-template <typename T>
-::testing::AssertionResult AwaitAssertReady(
- const char* expr,
- const char*, // Unused string representation of 'duration'.
- const process::Future<T>& actual,
- const Duration& duration)
-{
- if (!actual.await(duration)) {
- return ::testing::AssertionFailure()
- << "Failed to wait " << duration << " for " << expr;
- } else if (actual.isDiscarded()) {
- return ::testing::AssertionFailure()
- << expr << " was discarded";
- } else if (actual.isFailed()) {
- return ::testing::AssertionFailure()
- << "(" << expr << ").failure(): " << actual.failure();
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T>
-::testing::AssertionResult AwaitAssertFailed(
- const char* expr,
- const char*, // Unused string representation of 'duration'.
- const process::Future<T>& actual,
- const Duration& duration)
-{
- if (!actual.await(duration)) {
- return ::testing::AssertionFailure()
- << "Failed to wait " << duration << " for " << expr;
- } else if (actual.isDiscarded()) {
- return ::testing::AssertionFailure()
- << expr << " was discarded";
- } else if (actual.isReady()) {
- return ::testing::AssertionFailure()
- << expr << " is ready (" << ::testing::PrintToString(actual.get()) << ")";
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T>
-::testing::AssertionResult AwaitAssertDiscarded(
- const char* expr,
- const char*, // Unused string representation of 'duration'.
- const process::Future<T>& actual,
- const Duration& duration)
-{
- if (!actual.await(duration)) {
- return ::testing::AssertionFailure()
- << "Failed to wait " << duration << " for " << expr;
- } else if (actual.isFailed()) {
- return ::testing::AssertionFailure()
- << "(" << expr << ").failure(): " << actual.failure();
- } else if (actual.isReady()) {
- return ::testing::AssertionFailure()
- << expr << " is ready (" << ::testing::PrintToString(actual.get()) << ")";
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T1, typename T2>
-::testing::AssertionResult AwaitAssertEq(
- const char* expectedExpr,
- const char* actualExpr,
- const char* durationExpr,
- const T1& expected,
- const process::Future<T2>& actual,
- const Duration& duration)
-{
- const ::testing::AssertionResult result =
- AwaitAssertReady(actualExpr, durationExpr, actual, duration);
-
- if (result) {
- if (expected == actual.get()) {
- return ::testing::AssertionSuccess();
- } else {
- return ::testing::AssertionFailure()
- << "Value of: (" << actualExpr << ").get()\n"
- << " Actual: " << ::testing::PrintToString(actual.get()) << "\n"
- << "Expected: " << expectedExpr << "\n"
- << "Which is: " << ::testing::PrintToString(expected);
- }
- }
-
- return result;
-}
-
-
-#define AWAIT_ASSERT_READY_FOR(actual, duration) \
- ASSERT_PRED_FORMAT2(AwaitAssertReady, actual, duration)
-
-
-#define AWAIT_ASSERT_READY(actual) \
- AWAIT_ASSERT_READY_FOR(actual, Seconds(5))
-
-
-#define AWAIT_READY_FOR(actual, duration) \
- AWAIT_ASSERT_READY_FOR(actual, duration)
-
-
-#define AWAIT_READY(actual) \
- AWAIT_ASSERT_READY(actual)
-
-
-#define AWAIT_EXPECT_READY_FOR(actual, duration) \
- EXPECT_PRED_FORMAT2(AwaitAssertReady, actual, duration)
-
-
-#define AWAIT_EXPECT_READY(actual) \
- AWAIT_EXPECT_READY_FOR(actual, Seconds(5))
-
-
-#define AWAIT_ASSERT_FAILED_FOR(actual, duration) \
- ASSERT_PRED_FORMAT2(AwaitAssertFailed, actual, duration)
-
-
-#define AWAIT_ASSERT_FAILED(actual) \
- AWAIT_ASSERT_FAILED_FOR(actual, Seconds(5))
-
-
-#define AWAIT_FAILED_FOR(actual, duration) \
- AWAIT_ASSERT_FAILED_FOR(actual, duration)
-
-
-#define AWAIT_FAILED(actual) \
- AWAIT_ASSERT_FAILED(actual)
-
-
-#define AWAIT_EXPECT_FAILED_FOR(actual, duration) \
- EXPECT_PRED_FORMAT2(AwaitAssertFailed, actual, duration)
-
-
-#define AWAIT_EXPECT_FAILED(actual) \
- AWAIT_EXPECT_FAILED_FOR(actual, Seconds(5))
-
-
-#define AWAIT_ASSERT_DISCARDED_FOR(actual, duration) \
- ASSERT_PRED_FORMAT2(AwaitAssertDiscarded, actual, duration)
-
-
-#define AWAIT_ASSERT_DISCARDED(actual) \
- AWAIT_ASSERT_DISCARDED_FOR(actual, Seconds(5))
-
-
-#define AWAIT_DISCARDED_FOR(actual, duration) \
- AWAIT_ASSERT_DISCARDED_FOR(actual, duration)
-
-
-#define AWAIT_DISCARDED(actual) \
- AWAIT_ASSERT_DISCARDED(actual)
-
-
-#define AWAIT_EXPECT_DISCARDED_FOR(actual, duration) \
- EXPECT_PRED_FORMAT2(AwaitAssertDiscarded, actual, duration)
-
-
-#define AWAIT_EXPECT_DISCARDED(actual) \
- AWAIT_EXPECT_DISCARDED_FOR(actual, Seconds(5))
-
-
-#define AWAIT_ASSERT_EQ_FOR(expected, actual, duration) \
- ASSERT_PRED_FORMAT3(AwaitAssertEq, expected, actual, duration)
-
-
-#define AWAIT_ASSERT_EQ(expected, actual) \
- AWAIT_ASSERT_EQ_FOR(expected, actual, Seconds(5))
-
-
-#define AWAIT_EQ(expected, actual) \
- AWAIT_ASSERT_EQ(expected, actual)
-
-
-#define AWAIT_EXPECT_EQ_FOR(expected, actual, duration) \
- EXPECT_PRED_FORMAT3(AwaitAssertEq, expected, actual, duration)
-
-
-#define AWAIT_EXPECT_EQ(expected, actual) \
- AWAIT_EXPECT_EQ_FOR(expected, actual, Seconds(5))
-
-
-inline ::testing::AssertionResult AwaitAssertResponseStatusEq(
- const char* expectedExpr,
- const char* actualExpr,
- const char* durationExpr,
- const std::string& expected,
- const process::Future<process::http::Response>& actual,
- const Duration& duration)
-{
- const ::testing::AssertionResult result =
- AwaitAssertReady(actualExpr, durationExpr, actual, duration);
-
- if (result) {
- if (expected == actual.get().status) {
- return ::testing::AssertionSuccess();
- } else {
- return ::testing::AssertionFailure()
- << "Value of: (" << actualExpr << ").get().status\n"
- << " Actual: " << ::testing::PrintToString(actual.get().status) << "\n"
- << "Expected: " << expectedExpr << "\n"
- << "Which is: " << ::testing::PrintToString(expected);
- }
- }
-
- return result;
-}
-
-
-#define AWAIT_EXPECT_RESPONSE_STATUS_EQ_FOR(expected, actual, duration) \
- EXPECT_PRED_FORMAT3(AwaitAssertResponseStatusEq, expected, actual, duration)
-
-
-#define AWAIT_EXPECT_RESPONSE_STATUS_EQ(expected, actual) \
- AWAIT_EXPECT_RESPONSE_STATUS_EQ_FOR(expected, actual, Seconds(5))
-
-
-inline ::testing::AssertionResult AwaitAssertResponseBodyEq(
- const char* expectedExpr,
- const char* actualExpr,
- const char* durationExpr,
- const std::string& expected,
- const process::Future<process::http::Response>& actual,
- const Duration& duration)
-{
- const ::testing::AssertionResult result =
- AwaitAssertReady(actualExpr, durationExpr, actual, duration);
-
- if (result) {
- if (expected == actual.get().body) {
- return ::testing::AssertionSuccess();
- } else {
- return ::testing::AssertionFailure()
- << "Value of: (" << actualExpr << ").get().body\n"
- << " Actual: " << ::testing::PrintToString(actual.get().body) << "\n"
- << "Expected: " << expectedExpr << "\n"
- << "Which is: " << ::testing::PrintToString(expected);
- }
- }
-
- return result;
-}
-
-
-#define AWAIT_EXPECT_RESPONSE_BODY_EQ_FOR(expected, actual, duration) \
- EXPECT_PRED_FORMAT3(AwaitAssertResponseBodyEq, expected, actual, duration)
-
-
-#define AWAIT_EXPECT_RESPONSE_BODY_EQ(expected, actual) \
- AWAIT_EXPECT_RESPONSE_BODY_EQ_FOR(expected, actual, Seconds(5))
-
-
-inline ::testing::AssertionResult AwaitAssertResponseHeaderEq(
- const char* expectedExpr,
- const char* keyExpr,
- const char* actualExpr,
- const char* durationExpr,
- const std::string& expected,
- const std::string& key,
- const process::Future<process::http::Response>& actual,
- const Duration& duration)
-{
- const ::testing::AssertionResult result =
- AwaitAssertReady(actualExpr, durationExpr, actual, duration);
-
- if (result) {
- const Option<std::string> value = actual.get().headers.get(key);
- if (value.isNone()) {
- return ::testing::AssertionFailure()
- << "Response does not contain header '" << key << "'";
- } else if (expected == value.get()) {
- return ::testing::AssertionSuccess();
- } else {
- return ::testing::AssertionFailure()
- << "Value of: (" << actualExpr << ").get().headers[" << keyExpr << "]\n"
- << " Actual: " << ::testing::PrintToString(value.get()) << "\n"
- << "Expected: " << expectedExpr << "\n"
- << "Which is: " << ::testing::PrintToString(expected);
- }
- }
-
- return result;
-}
-
-
-#define AWAIT_EXPECT_RESPONSE_HEADER_EQ_FOR(expected, key, actual, duration) \
- EXPECT_PRED_FORMAT4(AwaitAssertResponseHeaderEq, expected, key, actual, duration)
-
-
-#define AWAIT_EXPECT_RESPONSE_HEADER_EQ(expected, key, actual) \
- AWAIT_EXPECT_RESPONSE_HEADER_EQ_FOR(expected, key, actual, Seconds(5))
-
-#endif // __PROCESS_GTEST_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/http.hpp b/third_party/libprocess/include/process/http.hpp
deleted file mode 100644
index 751cfb8..0000000
--- a/third_party/libprocess/include/process/http.hpp
+++ /dev/null
@@ -1,468 +0,0 @@
-#ifndef __PROCESS_HTTP_HPP__
-#define __PROCESS_HTTP_HPP__
-
-#include <cctype>
-#include <cstdlib>
-#include <iomanip>
-#include <sstream>
-#include <string>
-
-#include <limits.h>
-
-#include <process/future.hpp>
-#include <process/pid.hpp>
-
-#include <stout/error.hpp>
-#include <stout/hashmap.hpp>
-#include <stout/json.hpp>
-#include <stout/none.hpp>
-#include <stout/option.hpp>
-#include <stout/stringify.hpp>
-#include <stout/strings.hpp>
-#include <stout/try.hpp>
-
-namespace process {
-namespace http {
-
-struct Request
-{
- // TODO(benh): Add major/minor version.
- // TODO(bmahler): Header names are not case sensitive! Either make these
- // case-insensitive, or add a variable for each header in HTTP 1.0/1.1 (like
- // we've done here with keepAlive).
- // Tracked by: https://issues.apache.org/jira/browse/MESOS-328.
- hashmap<std::string, std::string> headers;
- std::string method;
- std::string path;
- std::string url;
- std::string fragment;
- hashmap<std::string, std::string> query;
- std::string body;
- bool keepAlive;
-
- // Returns whether the encoding is considered acceptable in the request.
- // TODO(bmahler): Consider this logic being in decoder.hpp, and having the
- // Request contain a member variable for each popular HTTP 1.0/1.1 header.
- bool accepts(const std::string& encoding) const
- {
- // See RFC 2616, section 14.3 for the details.
- Option<std::string> accepted = headers.get("Accept-Encoding");
-
- if (accepted.isNone()) {
- return false;
- }
-
- // Remove spaces and tabs for easier parsing.
- accepted = strings::remove(accepted.get(), " ");
- accepted = strings::remove(accepted.get(), "\t");
- accepted = strings::remove(accepted.get(), "\n");
-
- // From RFC 2616:
- // 1. If the content-coding is one of the content-codings listed in
- // the Accept-Encoding field, then it is acceptable, unless it is
- // accompanied by a qvalue of 0. (As defined in section 3.9, a
- // qvalue of 0 means "not acceptable.")
- // 2. The special "*" symbol in an Accept-Encoding field matches any
- // available content-coding not explicitly listed in the header
- // field.
-
- // First we'll look for the encoding specified explicitly, then '*'.
- std::vector<std::string> candidates;
- candidates.push_back(encoding); // Rule 1.
- candidates.push_back("*"); // Rule 2.
-
- foreach (std::string& candidate, candidates) {
- // Is the candidate one of the accepted encodings?
- foreach (const std::string& _encoding,
- strings::tokenize(accepted.get(), ",")) {
- if (strings::startsWith(_encoding, candidate)) {
- // Is there a 0 q value? Ex: 'gzip;q=0.0'.
- const std::map<std::string, std::vector<std::string> >& values =
- strings::pairs(_encoding, ";", "=");
-
- // Look for { "q": ["0"] }.
- if (values.count("q") == 0 || values.find("q")->second.size() != 1) {
- // No q value, or malformed q value.
- return true;
- }
-
- // Is the q value > 0?
- Try<double> value = numify<double>(values.find("q")->second[0]);
- return value.isSome() && value.get() > 0;
- }
- }
- }
-
- // NOTE: 3 and 4 are partially ignored since we can only provide gzip.
- // 3. If multiple content-codings are acceptable, then the acceptable
- // content-coding with the highest non-zero qvalue is preferred.
- // 4. The "identity" content-coding is always acceptable, unless
- // specifically refused because the Accept-Encoding field includes
- // "identity;q=0", or because the field includes "*;q=0" and does
- // not explicitly include the "identity" content-coding. If the
- // Accept-Encoding field-value is empty, then only the "identity"
- // encoding is acceptable.
- return false;
- }
-};
-
-
-struct Response
-{
- Response()
- : type(NONE)
- {}
-
- Response(const std::string& _body)
- : type(BODY),
- body(_body)
- {
- headers["Content-Length"] = stringify(body.size());
- }
-
- // TODO(benh): Add major/minor version.
- std::string status;
- hashmap<std::string, std::string> headers;
-
- // Either provide a "body", an absolute "path" to a file, or a
- // "pipe" for streaming a response. Distinguish between the cases
- // using 'type' below.
- //
- // BODY: Uses 'body' as the body of the response. These may be
- // encoded using gzip for efficiency, if 'Content-Encoding' is not
- // already specified.
- //
- // PATH: Attempts to perform a 'sendfile' operation on the file
- // found at 'path'.
- //
- // PIPE: Splices data from 'pipe' using 'Transfer-Encoding=chunked'.
- // Note that the read end of the pipe will be closed by libprocess
- // either after the write end has been closed or if the socket the
- // data is being spliced to has been closed (i.e., nobody is
- // listening any longer). This can cause writes to the pipe to
- // generate a SIGPIPE (which will terminate your program unless you
- // explicitly ignore them or handle them).
- //
- // In all cases (BODY, PATH, PIPE), you are expected to properly
- // specify the 'Content-Type' header, but the 'Content-Length' and
- // or 'Transfer-Encoding' headers will be filled in for you.
- enum {
- NONE,
- BODY,
- PATH,
- PIPE
- } type;
-
- std::string body;
- std::string path;
- int pipe; // See comment above regarding the semantics for closing.
-};
-
-
-struct OK : Response
-{
- OK()
- {
- status = "200 OK";
- }
-
- OK(const char* body) : Response(std::string(body))
- {
- status = "200 OK";
- }
-
- OK(const std::string& body) : Response(body)
- {
- status = "200 OK";
- }
-
- OK(const JSON::Value& value, const Option<std::string>& jsonp = None())
- {
- type = BODY;
-
- status = "200 OK";
-
- std::ostringstream out;
-
- if (jsonp.isSome()) {
- out << jsonp.get() << "(";
- }
-
- JSON::render(out, value);
-
- if (jsonp.isSome()) {
- out << ");";
- headers["Content-Type"] = "text/javascript";
- } else {
- headers["Content-Type"] = "application/json";
- }
-
- headers["Content-Length"] = stringify(out.str().size());
- body = out.str().data();
- }
-};
-
-
-struct TemporaryRedirect : Response
-{
- TemporaryRedirect(const std::string& url)
- {
- status = "307 Temporary Redirect";
- headers["Location"] = url;
- }
-};
-
-
-struct BadRequest : Response
-{
- BadRequest()
- {
- status = "400 Bad Request";
- }
-
- BadRequest(const std::string& body)
- : Response(body)
- {
- status = "400 Bad Request";
- }
-};
-
-
-struct NotFound : Response
-{
- NotFound()
- {
- status = "404 Not Found";
- }
-
- NotFound(const std::string& body) : Response(body)
- {
- status = "404 Not Found";
- }
-};
-
-
-struct InternalServerError : Response
-{
- InternalServerError()
- {
- status = "500 Internal Server Error";
- }
-
- InternalServerError(const std::string& body) : Response(body)
- {
- status = "500 Internal Server Error";
- }
-};
-
-
-struct ServiceUnavailable : Response
-{
- ServiceUnavailable()
- {
- status = "503 Service Unavailable";
- }
-
- ServiceUnavailable(const std::string& body) : Response(body)
- {
- status = "503 Service Unavailable";
- }
-};
-
-
-namespace query {
-
-// Parses an HTTP query string into a map. For example:
-//
-// parse("foo=1;bar=2;baz;foo=3")
-//
-// Would return a map with the following:
-// bar: "2"
-// baz: ""
-// foo: "3"
-//
-// We use the last value for a key for simplicity, since the RFC does not
-// specify how to handle duplicate keys:
-// http://en.wikipedia.org/wiki/Query_string
-// TODO(bmahler): If needed, investigate populating the query map inline
-// for better performance.
-inline hashmap<std::string, std::string> parse(const std::string& query)
-{
- hashmap<std::string, std::string> result;
-
- const std::vector<std::string>& tokens = strings::tokenize(query, ";&");
- foreach (const std::string& token, tokens) {
- const std::vector<std::string>& pairs = strings::split(token, "=");
- if (pairs.size() == 2) {
- result[pairs[0]] = pairs[1];
- } else if (pairs.size() == 1) {
- result[pairs[0]] = "";
- }
- }
-
- return result;
-}
-
-} // namespace query {
-
-
-// Returns a percent-encoded string according to RFC 3986.
-// The input string must not already be percent encoded.
-inline std::string encode(const std::string& s)
-{
- std::ostringstream out;
-
- foreach (unsigned char c, s) {
- switch (c) {
- // Reserved characters.
- case '$':
- case '&':
- case '+':
- case ',':
- case '/':
- case ':':
- case ';':
- case '=':
- case '?':
- case '@':
- // Unsafe characters.
- case ' ':
- case '"':
- case '<':
- case '>':
- case '#':
- case '%':
- case '{':
- case '}':
- case '|':
- case '\\':
- case '^':
- case '~':
- case '[':
- case ']':
- case '`':
- // NOTE: The cast to unsigned int is needed.
- out << '%' << std::setfill('0') << std::setw(2) << std::hex
- << std::uppercase << (unsigned int) c;
- break;
- default:
- // ASCII control characters and non-ASCII characters.
- // NOTE: The cast to unsigned int is needed.
- if (c < 0x20 || c > 0x7F) {
- out << '%' << std::setfill('0') << std::setw(2) << std::hex
- << std::uppercase << (unsigned int) c;
- } else {
- out << c;
- }
- break;
- }
- }
-
- return out.str();
-}
-
-
-// Decodes a percent-encoded string according to RFC 3986.
-// The input string must not already be decoded.
-// Returns error on the occurrence of a malformed % escape in s.
-inline Try<std::string> decode(const std::string& s)
-{
- std::ostringstream out;
-
- for (size_t i = 0; i < s.length(); ++i) {
- if (s[i] != '%') {
- out << s[i];
- continue;
- }
-
- // We now expect two more characters: % HEXDIG HEXDIG
- if (i + 2 >= s.length() || !isxdigit(s[i+1]) || !isxdigit(s[i+2])) {
- return Error(
- "Malformed % escape in '" + s + "': '" + s.substr(i, 3) + "'");
- }
-
- // Convert from HEXDIG HEXDIG to char value.
- std::istringstream in(s.substr(i + 1, 2));
- unsigned long l;
- in >> std::hex >> l;
- if (l > UCHAR_MAX) {
- std::cerr << "Unexpected conversion from hex string: "
- << s.substr(i + 1, 2) << " to unsigned long: "
- << l << std::endl;
- abort();
- }
- out << static_cast<unsigned char>(l);
-
- i += 2;
- }
-
- return out.str();
-}
-
-
-// Sends a blocking HTTP GET request to the process with the given upid.
-// Returns the HTTP response from the process, read asynchronously.
-//
-// TODO(bmahler): Have the request sent asynchronously as well.
-// TODO(bmahler): For efficiency, this should properly use the ResponseDecoder
-// on the read stream, rather than parsing the full string response at the end.
-Future<Response> get(
- const UPID& upid,
- const std::string& path = "",
- const std::string& query = "");
-
-
-// Status code reason strings, from the HTTP1.1 RFC:
-// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
-extern hashmap<uint16_t, std::string> statuses;
-
-
-inline void initialize()
-{
- statuses[100] = "100 Continue";
- statuses[101] = "101 Switching Protocols";
- statuses[200] = "200 OK";
- statuses[201] = "201 Created";
- statuses[202] = "202 Accepted";
- statuses[203] = "203 Non-Authoritative Information";
- statuses[204] = "204 No Content";
- statuses[205] = "205 Reset Content";
- statuses[206] = "206 Partial Content";
- statuses[300] = "300 Multiple Choices";
- statuses[301] = "301 Moved Permanently";
- statuses[302] = "302 Found";
- statuses[303] = "303 See Other";
- statuses[304] = "304 Not Modified";
- statuses[305] = "305 Use Proxy";
- statuses[307] = "307 Temporary Redirect";
- statuses[400] = "400 Bad Request";
- statuses[401] = "401 Unauthorized";
- statuses[402] = "402 Payment Required";
- statuses[403] = "403 Forbidden";
- statuses[404] = "404 Not Found";
- statuses[405] = "405 Method Not Allowed";
- statuses[406] = "406 Not Acceptable";
- statuses[407] = "407 Proxy Authentication Required";
- statuses[408] = "408 Request Time-out";
- statuses[409] = "409 Conflict";
- statuses[410] = "410 Gone";
- statuses[411] = "411 Length Required";
- statuses[412] = "412 Precondition Failed";
- statuses[413] = "413 Request Entity Too Large";
- statuses[414] = "414 Request-URI Too Large";
- statuses[415] = "415 Unsupported Media Type";
- statuses[416] = "416 Requested range not satisfiable";
- statuses[417] = "417 Expectation Failed";
- statuses[500] = "500 Internal Server Error";
- statuses[501] = "501 Not Implemented";
- statuses[502] = "502 Bad Gateway";
- statuses[503] = "503 Service Unavailable";
- statuses[504] = "504 Gateway Time-out";
- statuses[505] = "505 HTTP Version not supported";
-}
-
-
-} // namespace http {
-} // namespace process {
-
-#endif // __PROCESS_HTTP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/id.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/id.hpp b/third_party/libprocess/include/process/id.hpp
deleted file mode 100644
index 8c256b9..0000000
--- a/third_party/libprocess/include/process/id.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __PROCESS_ID_HPP__
-#define __PROCESS_ID_HPP__
-
-#include <string>
-
-namespace process {
-namespace ID {
-
-// Returns 'prefix(N)' where N represents the number of instances
-// where this prefix has been used to generate an ID.
-std::string generate(const std::string& prefix = "");
-
-} // namespace ID {
-} // namespace process {
-
-#endif // __PROCESS_ID_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/io.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/io.hpp b/third_party/libprocess/include/process/io.hpp
deleted file mode 100644
index 8cf3244..0000000
--- a/third_party/libprocess/include/process/io.hpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __PROCESS_IO_HPP__
-#define __PROCESS_IO_HPP__
-
-#include <cstring> // For size_t.
-#include <string>
-
-#include <process/future.hpp>
-
-namespace process {
-namespace io {
-
-// Possible events for polling.
-const short READ = 0x01;
-const short WRITE = 0x02;
-
-// Buffered read chunk size. Roughly 16 pages.
-const size_t BUFFERED_READ_SIZE = 16*4096;
-
-// TODO(benh): Add a version which takes multiple file descriptors.
-// Returns the events (a subset of the events specified) that can be
-// performed on the specified file descriptor without blocking.
-Future<short> poll(int fd, short events);
-
-
-// Performs a single non-blocking read by polling on the specified file
-// descriptor until any data can be be read. The future will become ready when
-// some data is read (may be less than that specified by size). A future failure
-// will be returned if an error is detected. If end-of-file is reached, value
-// zero will be returned. Note that the return type of this function differs
-// from the standard 'read'. In particular, this function returns the number of
-// bytes read or zero on end-of-file (an error is indicated by failing the
-// future, thus only a 'size_t' is necessary rather than a 'ssize_t').
-Future<size_t> read(int fd, void* data, size_t size);
-
-
-// Performs a series of asynchronous reads, until EOF is reached.
-// NOTE: When using this, ensure the sender will close the connection
-// so that EOF can be reached.
-Future<std::string> read(int fd);
-
-} // namespace io {
-} // namespace process {
-
-#endif // __PROCESS_IO_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/latch.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/latch.hpp b/third_party/libprocess/include/process/latch.hpp
deleted file mode 100644
index 5170aa8..0000000
--- a/third_party/libprocess/include/process/latch.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __PROCESS_LATCH_HPP__
-#define __PROCESS_LATCH_HPP__
-
-#include <process/pid.hpp>
-
-#include <stout/duration.hpp>
-
-namespace process {
-
-class Latch
-{
-public:
- Latch();
- virtual ~Latch();
-
- bool operator == (const Latch& that) const { return pid == that.pid; }
- bool operator < (const Latch& that) const { return pid < that.pid; }
-
- void trigger();
- bool await(const Duration& duration = Seconds(-1));
-
-private:
- // Not copyable, not assignable.
- Latch(const Latch& that);
- Latch& operator = (const Latch& that);
-
- bool triggered;
- UPID pid;
-};
-
-} // namespace process {
-
-#endif // __PROCESS_LATCH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/logging.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/logging.hpp b/third_party/libprocess/include/process/logging.hpp
deleted file mode 100644
index cba2fd4..0000000
--- a/third_party/libprocess/include/process/logging.hpp
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef __PROCESS_LOGGING_HPP__
-#define __PROCESS_LOGGING_HPP__
-
-#include <glog/logging.h>
-
-#include <process/delay.hpp>
-#include <process/future.hpp>
-#include <process/http.hpp>
-#include <process/process.hpp>
-#include <process/timeout.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/numify.hpp>
-#include <stout/option.hpp>
-#include <stout/stringify.hpp>
-#include <stout/try.hpp>
-
-namespace process {
-
-class Logging : public Process<Logging>
-{
-public:
- Logging()
- : ProcessBase("logging"),
- original(FLAGS_v)
- {
- // Make sure all reads/writes can be done atomically (i.e., to
- // make sure VLOG(*) statements don't read partial writes).
- // TODO(benh): Use "atomics" primitives for doing reads/writes of
- // FLAGS_v anyway to account for proper memory barriers.
- CHECK(sizeof(FLAGS_v) == sizeof(int32_t));
- }
-
- virtual ~Logging() {}
-
-protected:
- virtual void initialize()
- {
- route("/toggle", &This::toggle);
- }
-
-private:
- Future<http::Response> toggle(const http::Request& request)
- {
- Option<std::string> level = request.query.get("level");
- Option<std::string> duration = request.query.get("duration");
-
- if (level.isNone() && duration.isNone()) {
- return http::OK(stringify(FLAGS_v) + "\n");
- }
-
- if (level.isSome() && duration.isNone()) {
- return http::BadRequest("Expecting 'duration=value' in query.\n");
- } else if (level.isNone() && duration.isSome()) {
- return http::BadRequest("Expecting 'level=value' in query.\n");
- }
-
- Try<int> v = numify<int>(level.get());
-
- if (v.isError()) {
- return http::BadRequest(v.error() + ".\n");
- }
-
- if (v.get() < 0) {
- return http::BadRequest("Invalid level '" + stringify(v.get()) + "'.\n");
- } else if (v.get() < original) {
- return http::BadRequest("'" + stringify(v.get()) + "' < original level.\n");
- }
-
- Try<Duration> d = Duration::parse(duration.get());
-
- if (d.isError()) {
- return http::BadRequest(d.error() + ".\n");
- }
-
- // Set the logging level.
- set(v.get());
-
- // Start a revert timer (if necessary).
- if (v.get() != original) {
- timeout = d.get();
- delay(timeout.remaining(), this, &This::revert);
- }
-
- return http::OK();
- }
-
- void set(int v)
- {
- if (FLAGS_v != v) {
- VLOG(FLAGS_v) << "Setting verbose logging level to " << v;
- FLAGS_v = v;
- __sync_synchronize(); // Ensure 'FLAGS_v' visible in other threads.
- }
- }
-
- void revert()
- {
- if (timeout.remaining() == Seconds(0)) {
- set(original);
- }
- }
-
- Timeout timeout;
-
- const int32_t original; // Original value of FLAGS_v.
-};
-
-} // namespace process {
-
-#endif // __PROCESS_LOGGING_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/message.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/message.hpp b/third_party/libprocess/include/process/message.hpp
deleted file mode 100644
index c67c5e1..0000000
--- a/third_party/libprocess/include/process/message.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __PROCESS_MESSAGE_HPP__
-#define __PROCESS_MESSAGE_HPP__
-
-#include <string>
-
-#include <process/pid.hpp>
-
-namespace process {
-
-struct Message
-{
- std::string name;
- UPID from;
- UPID to;
- std::string body;
-};
-
-} // namespace process {
-
-#endif // __PROCESS_MESSAGE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/mime.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/mime.hpp b/third_party/libprocess/include/process/mime.hpp
deleted file mode 100644
index 0abeac1..0000000
--- a/third_party/libprocess/include/process/mime.hpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#ifndef __PROCESS_MIME_HPP__
-#define __PROCESS_MIME_HPP__
-
-namespace process {
-namespace mime {
-
-extern std::map<std::string, std::string> types;
-
-inline void initialize()
-{
- // These MIME types were collected via:
- /*
- python -c '
- import mimetypes
- for extension, type in mimetypes.types_map.iteritems():
- print "types[\"%s\"] = \"%s\";" % (extension, type)
- '
- */
-
- types[".obj"] = "application/octet-stream";
- types[".ra"] = "audio/x-pn-realaudio";
- types[".wsdl"] = "application/xml";
- types[".dll"] = "application/octet-stream";
- types[".ras"] = "image/x-cmu-raster";
- types[".ram"] = "application/x-pn-realaudio";
- types[".bcpio"] = "application/x-bcpio";
- types[".sh"] = "application/x-sh";
- types[".m1v"] = "video/mpeg";
- types[".xwd"] = "image/x-xwindowdump";
- types[".doc"] = "application/msword";
- types[".bmp"] = "image/x-ms-bmp";
- types[".shar"] = "application/x-shar";
- types[".js"] = "application/x-javascript";
- types[".src"] = "application/x-wais-source";
- types[".dvi"] = "application/x-dvi";
- types[".aif"] = "audio/x-aiff";
- types[".ksh"] = "text/plain";
- types[".dot"] = "application/msword";
- types[".mht"] = "message/rfc822";
- types[".p12"] = "application/x-pkcs12";
- types[".css"] = "text/css";
- types[".csh"] = "application/x-csh";
- types[".pwz"] = "application/vnd.ms-powerpoint";
- types[".pdf"] = "application/pdf";
- types[".cdf"] = "application/x-netcdf";
- types[".pl"] = "text/plain";
- types[".ai"] = "application/postscript";
- types[".jpe"] = "image/jpeg";
- types[".jpg"] = "image/jpeg";
- types[".py"] = "text/x-python";
- types[".xml"] = "text/xml";
- types[".jpeg"] = "image/jpeg";
- types[".ps"] = "application/postscript";
- types[".gtar"] = "application/x-gtar";
- types[".xpm"] = "image/x-xpixmap";
- types[".hdf"] = "application/x-hdf";
- types[".nws"] = "message/rfc822";
- types[".tsv"] = "text/tab-separated-values";
- types[".xpdl"] = "application/xml";
- types[".p7c"] = "application/pkcs7-mime";
- types[".eps"] = "application/postscript";
- types[".ief"] = "image/ief";
- types[".so"] = "application/octet-stream";
- types[".xlb"] = "application/vnd.ms-excel";
- types[".pbm"] = "image/x-portable-bitmap";
- types[".texinfo"] = "application/x-texinfo";
- types[".xls"] = "application/vnd.ms-excel";
- types[".tex"] = "application/x-tex";
- types[".rtx"] = "text/richtext";
- types[".html"] = "text/html";
- types[".aiff"] = "audio/x-aiff";
- types[".aifc"] = "audio/x-aiff";
- types[".exe"] = "application/octet-stream";
- types[".sgm"] = "text/x-sgml";
- types[".tif"] = "image/tiff";
- types[".mpeg"] = "video/mpeg";
- types[".ustar"] = "application/x-ustar";
- types[".gif"] = "image/gif";
- types[".ppt"] = "application/vnd.ms-powerpoint";
- types[".pps"] = "application/vnd.ms-powerpoint";
- types[".sgml"] = "text/x-sgml";
- types[".ppm"] = "image/x-portable-pixmap";
- types[".latex"] = "application/x-latex";
- types[".bat"] = "text/plain";
- types[".mov"] = "video/quicktime";
- types[".ppa"] = "application/vnd.ms-powerpoint";
- types[".tr"] = "application/x-troff";
- types[".rdf"] = "application/xml";
- types[".xsl"] = "application/xml";
- types[".eml"] = "message/rfc822";
- types[".nc"] = "application/x-netcdf";
- types[".sv4cpio"] = "application/x-sv4cpio";
- types[".bin"] = "application/octet-stream";
- types[".h"] = "text/plain";
- types[".tcl"] = "application/x-tcl";
- types[".wiz"] = "application/msword";
- types[".o"] = "application/octet-stream";
- types[".a"] = "application/octet-stream";
- types[".c"] = "text/plain";
- types[".wav"] = "audio/x-wav";
- types[".vcf"] = "text/x-vcard";
- types[".xbm"] = "image/x-xbitmap";
- types[".txt"] = "text/plain";
- types[".au"] = "audio/basic";
- types[".t"] = "application/x-troff";
- types[".tiff"] = "image/tiff";
- types[".texi"] = "application/x-texinfo";
- types[".oda"] = "application/oda";
- types[".ms"] = "application/x-troff-ms";
- types[".rgb"] = "image/x-rgb";
- types[".me"] = "application/x-troff-me";
- types[".sv4crc"] = "application/x-sv4crc";
- types[".qt"] = "video/quicktime";
- types[".mpa"] = "video/mpeg";
- types[".mpg"] = "video/mpeg";
- types[".mpe"] = "video/mpeg";
- types[".avi"] = "video/x-msvideo";
- types[".pgm"] = "image/x-portable-graymap";
- types[".pot"] = "application/vnd.ms-powerpoint";
- types[".mif"] = "application/x-mif";
- types[".roff"] = "application/x-troff";
- types[".htm"] = "text/html";
- types[".man"] = "application/x-troff-man";
- types[".etx"] = "text/x-setext";
- types[".zip"] = "application/zip";
- types[".movie"] = "video/x-sgi-movie";
- types[".pyc"] = "application/x-python-code";
- types[".png"] = "image/png";
- types[".pfx"] = "application/x-pkcs12";
- types[".mhtml"] = "message/rfc822";
- types[".tar"] = "application/x-tar";
- types[".pnm"] = "image/x-portable-anymap";
- types[".pyo"] = "application/x-python-code";
- types[".snd"] = "audio/basic";
- types[".cpio"] = "application/x-cpio";
- types[".swf"] = "application/x-shockwave-flash";
- types[".mp3"] = "audio/mpeg";
- types[".mp2"] = "audio/mpeg";
- types[".mp4"] = "video/mp4";
-}
-
-} // } namespace mime {
-} // } namespace process {
-
-#endif // __PROCESS_MIME_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/once.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/once.hpp b/third_party/libprocess/include/process/once.hpp
deleted file mode 100644
index e85b382..0000000
--- a/third_party/libprocess/include/process/once.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef __PROCESS_ONCE_HPP__
-#define __PROCESS_ONCE_HPP__
-
-#include <process/future.hpp>
-
-#include <stout/nothing.hpp>
-
-namespace process {
-
-// Provides a _blocking_ abstraction that's useful for performing a
-// task exactly once.
-class Once
-{
-public:
- Once() {}
-
- // Returns true if this Once instance has already transitioned to a
- // 'done' state (i.e., the action you wanted to perform "once" has
- // been completed). Note that this BLOCKS until Once::done has been
- // called.
- bool once()
- {
- if (!outer.set(&inner)) {
- inner.future().await();
- return true;
- }
-
- return false;
- }
-
- // Transitions this Once instance to a 'done' state.
- void done()
- {
- inner.set(Nothing());
- }
-
-private:
- // Not copyable, not assignable.
- Once(const Once& that);
- Once& operator = (const Once& that);
-
- Promise<Nothing> inner;
- Promise<Promise<Nothing>*> outer;
-};
-
-} // namespace process {
-
-#endif // __PROCESS_ONCE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/pid.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/pid.hpp b/third_party/libprocess/include/process/pid.hpp
deleted file mode 100644
index 5a77dbc..0000000
--- a/third_party/libprocess/include/process/pid.hpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#ifndef __PROCESS_PID_HPP__
-#define __PROCESS_PID_HPP__
-
-#include <stdint.h>
-
-#include <iostream>
-#include <sstream>
-#include <string>
-
-
-namespace process {
-
-// Forward declaration to break cyclic dependencies.
-class ProcessBase;
-
-
-struct UPID
-{
- UPID()
- : ip(0), port(0) {}
-
- UPID(const UPID& that)
- : id(that.id), ip(that.ip), port(that.port) {}
-
- UPID(const char* id_, uint32_t ip_, uint16_t port_)
- : id(id_), ip(ip_), port(port_) {}
-
- UPID(const std::string& id_, uint32_t ip_, uint16_t port_)
- : id(id_), ip(ip_), port(port_) {}
-
- UPID(const char* s);
-
- UPID(const std::string& s);
-
- UPID(const ProcessBase& process);
-
- operator std::string () const;
-
- operator bool () const
- {
- return id != "" && ip != 0 && port != 0;
- }
-
- bool operator ! () const
- {
- return id == "" && ip == 0 && port == 0;
- }
-
- bool operator < (const UPID& that) const
- {
- if (this != &that) {
- if (ip == that.ip && port == that.port)
- return id < that.id;
- else if (ip == that.ip && port != that.port)
- return port < that.port;
- else
- return ip < that.ip;
- }
-
- return false;
- }
-
- bool operator == (const UPID& that) const
- {
- if (this != &that) {
- return (id == that.id &&
- ip == that.ip &&
- port == that.port);
- }
-
- return true;
- }
-
- bool operator != (const UPID& that) const
- {
- return !(this->operator == (that));
- }
-
- std::string id;
- uint32_t ip;
- uint16_t port;
-};
-
-
-template <typename T = ProcessBase>
-struct PID : UPID
-{
- PID() : UPID() {}
-
- PID(const T* t) : UPID(static_cast<const ProcessBase&>(*t)) {}
- PID(const T& t) : UPID(static_cast<const ProcessBase&>(t)) {}
-
- template <typename Base>
- operator PID<Base> () const
- {
- // Only allow upcasts!
- T* t = NULL;
- Base* base = t;
- (void)base; // Eliminate unused base warning.
- PID<Base> pid;
- pid.id = id;
- pid.ip = ip;
- pid.port = port;
- return pid;
- }
-};
-
-
-// Outputing UPIDs and generating UPIDs using streams.
-std::ostream& operator << (std::ostream&, const UPID&);
-std::istream& operator >> (std::istream&, UPID&);
-
-
-// UPID hash value (for example, to use in Boost's unordered maps).
-std::size_t hash_value(const UPID&);
-
-} // namespace process {
-
-
-
-#endif // __PROCESS_PID_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/process.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/process.hpp b/third_party/libprocess/include/process/process.hpp
deleted file mode 100644
index 8228e4f..0000000
--- a/third_party/libprocess/include/process/process.hpp
+++ /dev/null
@@ -1,370 +0,0 @@
-#ifndef __PROCESS_PROCESS_HPP__
-#define __PROCESS_PROCESS_HPP__
-
-#include <stdint.h>
-#include <pthread.h>
-
-#include <map>
-#include <queue>
-
-#include <tr1/functional>
-
-#include <process/clock.hpp>
-#include <process/event.hpp>
-#include <process/filter.hpp>
-#include <process/http.hpp>
-#include <process/message.hpp>
-#include <process/mime.hpp>
-#include <process/pid.hpp>
-#include <process/thread.hpp>
-
-#include <stout/duration.hpp>
-
-namespace process {
-
-class ProcessBase : public EventVisitor
-{
-public:
- ProcessBase(const std::string& id = "");
-
- virtual ~ProcessBase();
-
- UPID self() const { return pid; }
-
-protected:
- // Invoked when an event is serviced.
- virtual void serve(const Event& event)
- {
- event.visit(this);
- }
-
- // Callbacks used to visit (i.e., handle) a specific event.
- virtual void visit(const MessageEvent& event);
- virtual void visit(const DispatchEvent& event);
- virtual void visit(const HttpEvent& event);
- virtual void visit(const ExitedEvent& event);
- virtual void visit(const TerminateEvent& event);
-
- // Invoked when a process gets spawned.
- virtual void initialize() {}
-
- // Invoked when a process is terminated (unless visit is overriden).
- virtual void finalize() {}
-
- // Invoked when a linked process has exited (see link).
- virtual void exited(const UPID& pid) {}
-
- // Invoked when a linked process can no longer be monitored (see link).
- virtual void lost(const UPID& pid) {}
-
- // Puts a message at front of queue.
- void inject(
- const UPID& from,
- const std::string& name,
- const char* data = NULL,
- size_t length = 0);
-
- // Sends a message with data to PID.
- void send(
- const UPID& to,
- const std::string& name,
- const char* data = NULL,
- size_t length = 0);
-
- // Links with the specified PID. Linking with a process from within
- // the same "operating system process" is gauranteed to give you
- // perfect monitoring of that process. However, linking with a
- // process on another machine might result in receiving lost
- // callbacks due to the nature of a distributed environment.
- UPID link(const UPID& pid);
-
- // The default visit implementation for message events invokes
- // installed message handlers, or delegates the message to another
- // process (a delegate can be installed below but a message handler
- // always takes precedence over delegating). A message handler is
- // any function which takes two arguments, the "from" pid and the
- // message body.
- typedef std::tr1::function<void(const UPID&, const std::string&)>
- MessageHandler;
-
- // Setup a handler for a message.
- void install(
- const std::string& name,
- const MessageHandler& handler)
- {
- handlers.message[name] = handler;
- }
-
- template <typename T>
- void install(
- const std::string& name,
- void (T::*method)(const UPID&, const std::string&))
- {
- // Note that we use dynamic_cast here so a process can use
- // multiple inheritance if it sees so fit (e.g., to implement
- // multiple callback interfaces).
- MessageHandler handler =
- std::tr1::bind(method,
- dynamic_cast<T*>(this),
- std::tr1::placeholders::_1,
- std::tr1::placeholders::_2);
- install(name, handler);
- }
-
- // Delegate incoming message's with the specified name to pid.
- void delegate(const std::string& name, const UPID& pid)
- {
- delegates[name] = pid;
- }
-
- // The default visit implementation for HTTP events invokes
- // installed HTTP handlers. A HTTP handler is any function which
- // takes an http::Request object and returns an http::Response.
- typedef std::tr1::function<Future<http::Response>(const http::Request&)>
- HttpRequestHandler;
-
- // Setup a handler for an HTTP request.
- bool route(
- const std::string& name,
- const HttpRequestHandler& handler)
- {
- if (name.find('/') != 0) {
- return false;
- }
- handlers.http[name.substr(1)] = handler;
- return true;
- }
-
- template <typename T>
- bool route(
- const std::string& name,
- Future<http::Response> (T::*method)(const http::Request&))
- {
- // Note that we use dynamic_cast here so a process can use
- // multiple inheritance if it sees so fit (e.g., to implement
- // multiple callback interfaces).
- HttpRequestHandler handler =
- std::tr1::bind(method, dynamic_cast<T*>(this),
- std::tr1::placeholders::_1);
- return route(name, handler);
- }
-
- // Provide the static asset(s) at the specified _absolute_ path for
- // the specified name. For example, assuming the process named
- // "server" invoked 'provide("name", "path")' then an HTTP request
- // for '/server/name' would return the asset found at 'path'. If the
- // specified path is a directory then an HTTP request for
- // '/server/name/file' would return the asset found at
- // '/path/file'. The 'Content-Type' header of the HTTP response will
- // be set to the specified type given the file extension (you can
- // manipulate this via the optional 'types' parameter).
- void provide(
- const std::string& name,
- const std::string& path,
- const std::map<std::string, std::string>& types = mime::types)
- {
- // TODO(benh): Check that name is only alphanumeric (i.e., has no
- // '/') and that path is absolute.
- Asset asset;
- asset.path = path;
- asset.types = types;
- assets[name] = asset;
- }
-
-private:
- friend class SocketManager;
- friend class ProcessManager;
- friend class ProcessReference;
- friend void* schedule(void*);
-
- // Process states.
- enum { BOTTOM,
- READY,
- RUNNING,
- BLOCKED,
- TERMINATING,
- TERMINATED } state;
-
- // Mutex protecting internals.
- // TODO(benh): Consider replacing with a spinlock, on multi-core systems.
- pthread_mutex_t m;
- void lock() { pthread_mutex_lock(&m); }
- void unlock() { pthread_mutex_unlock(&m); }
-
- // Enqueue the specified message, request, or function call.
- void enqueue(Event* event, bool inject = false);
-
- // Queue of received events.
- std::deque<Event*> events;
-
- // Delegates for messages.
- std::map<std::string, UPID> delegates;
-
- // Handlers for messages and HTTP requests.
- struct {
- std::map<std::string, MessageHandler> message;
- std::map<std::string, HttpRequestHandler> http;
- } handlers;
-
- // Definition of a static asset.
- struct Asset
- {
- std::string path;
- std::map<std::string, std::string> types;
- };
-
- // Static assets(s) to provide.
- std::map<std::string, Asset> assets;
-
- // Active references.
- int refs;
-
- // Process PID.
- UPID pid;
-};
-
-
-template <typename T>
-class Process : public virtual ProcessBase {
-public:
- virtual ~Process() {}
-
- // Returns pid of process; valid even before calling spawn.
- PID<T> self() const { return PID<T>(dynamic_cast<const T*>(this)); }
-
-protected:
- // Useful typedefs for dispatch/delay/defer to self()/this.
- typedef T Self;
- typedef T This;
-};
-
-
-/**
- * Initialize the library. Note that libprocess uses Google's glog and
- * you can specify options for it (e.g., a logging directory) via
- * environment variables (see the glog documentation for more
- * information).
- *
- * @param delegate process to receive root HTTP requests
- */
-void initialize(const std::string& delegate = "");
-
-
-/**
- * Returns the IP address associated with this instance of the
- * library.
- */
-uint32_t ip();
-
-
-/**
- * Returns the port associated with this instance of the library.
- */
-uint16_t port();
-
-
-/**
- * Spawn a new process.
- *
- * @param process process to be spawned
- * @param manage boolean whether process should get garbage collected
- */
-UPID spawn(ProcessBase* process, bool manage = false);
-
-template <typename T>
-PID<T> spawn(T* t, bool manage = false)
-{
- // We save the pid before spawn is called because it's possible that
- // the process has already been deleted after spawn returns (e.g.,
- // if 'manage' is true).
- PID<T> pid(t);
-
- if (!spawn(static_cast<ProcessBase*>(t), manage)) {
- return PID<T>();
- }
-
- return pid;
-}
-
-template <typename T>
-PID<T> spawn(T& t, bool manage = false)
-{
- return spawn(&t, manage);
-}
-
-
-/**
- * Send a TERMINATE message to a process, injecting the message ahead
- * of all other messages queued up for that process if requested. Note
- * that currently terminate only works for local processes (in the
- * future we plan to make this more explicit via the use of a PID
- * instead of a UPID).
- *
- * @param inject if true message will be put on front of message queue
- */
-void terminate(const UPID& pid, bool inject = true);
-void terminate(const ProcessBase& process, bool inject = true);
-void terminate(const ProcessBase* process, bool inject = true);
-
-
-/**
- * Wait for process to exit no more than specified seconds (returns
- * true if actually waited on a process).
- *
- * @param PID id of the process
- * @param secs max time to wait, 0 implies wait for ever
- */
-bool wait(const UPID& pid, const Duration& duration = Seconds(-1));
-bool wait(const ProcessBase& process, const Duration& duration = Seconds(-1));
-bool wait(const ProcessBase* process, const Duration& duration = Seconds(-1));
-
-
-/**
- * Sends a message with data without a return address.
- *
- * @param to receiver
- * @param name message name
- * @param data data to send (gets copied)
- * @param length length of data
- */
-void post(const UPID& to,
- const std::string& name,
- const char* data = NULL,
- size_t length = 0);
-
-
-// Inline implementations of above.
-inline void terminate(const ProcessBase& process, bool inject)
-{
- terminate(process.self(), inject);
-}
-
-
-inline void terminate(const ProcessBase* process, bool inject)
-{
- terminate(process->self(), inject);
-}
-
-
-inline bool wait(const ProcessBase& process, const Duration& duration)
-{
- return process::wait(process.self(), duration); // Explicit to disambiguate.
-}
-
-
-inline bool wait(const ProcessBase* process, const Duration& duration)
-{
- return process::wait(process->self(), duration); // Explicit to disambiguate.
-}
-
-
-// Per thread process pointer. The extra level of indirection from
-// _process_ to __process__ is used in order to take advantage of the
-// ThreadLocal operators without needing the extra dereference.
-extern ThreadLocal<ProcessBase>* _process_;
-
-#define __process__ (*_process_)
-
-} // namespace process {
-
-#endif // __PROCESS_PROCESS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/profiler.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/profiler.hpp b/third_party/libprocess/include/process/profiler.hpp
deleted file mode 100644
index 64cf622..0000000
--- a/third_party/libprocess/include/process/profiler.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#ifndef __PROCESS_PROFILER_HPP__
-#define __PROCESS_PROFILER_HPP__
-
-#include <glog/logging.h>
-
-#ifdef HAS_GPERFTOOLS
-#include <gperftools/profiler.h>
-#endif
-
-#include <string>
-
-#include <process/future.hpp>
-#include <process/http.hpp>
-#include <process/process.hpp>
-
-#include <stout/format.hpp>
-#include <stout/os.hpp>
-
-namespace process {
-
-const std::string PROFILE_FILE = "perftools.out";
-
-class Profiler : public Process<Profiler>
-{
-public:
- Profiler() : ProcessBase("profiler"), started(false) {}
-
- virtual ~Profiler() {}
-
-protected:
- virtual void initialize()
- {
- route("/start", &Profiler::start);
- route("/stop", &Profiler::stop);
- }
-
-private:
- // HTTP endpoints.
-
- // Starts the profiler. There are no request parameters.
- Future<http::Response> start(const http::Request& request)
- {
-#ifdef HAS_GPERFTOOLS
- if (os::getenv("LIBPROCESS_ENABLE_PROFILER", false) != "1") {
- return http::BadRequest(
- "The profiler is not enabled. To enable the profiler, libprocess "
- "must be started with LIBPROCESS_ENABLE_PROFILER=1 in the "
- "environment.\n");
- }
-
- if (started) {
- return http::BadRequest("Profiler already started.\n");
- }
-
- LOG(INFO) << "Starting Profiler";
-
- // WARNING: If using libunwind < 1.0.1, profiling should not be used, as
- // there are reports of crashes.
- // WARNING: If using libunwind 1.0.1, profiling should not be turned on
- // when it's possible for new threads to be created.
- // This may cause a deadlock. The workaround used in libprocess is described
- // here:
- // https://groups.google.com/d/topic/google-perftools/Df10Uy4Djrg/discussion
- // NOTE: We have not tested this with libunwind > 1.0.1.
- if (!ProfilerStart(PROFILE_FILE.c_str())) {
- std::string error =
- strings::format("Failed to start profiler: %s", strerror(errno)).get();
- LOG(ERROR) << error;
- return http::InternalServerError(error);
- }
-
- started = true;
- return http::OK("Profiler started.\n");
-#else
- return http::BadRequest(
- "Perftools is disabled. To enable perftools, "
- "configure libprocess with --enable-perftools.\n");
-#endif
- }
-
- // Stops the profiler. There are no request parameters.
- // This returns the profile output, it will also remain present
- // in the working directory.
- Future<http::Response> stop(const http::Request& request)
- {
-#ifdef HAS_GPERFTOOLS
- if (!started) {
- return http::BadRequest("Profiler not running.\n");
- }
-
- LOG(INFO) << "Stopping Profiler";
-
- ProfilerStop();
-
- http::OK response;
- response.type = response.PATH;
- response.path = "perftools.out";
- response.headers["Content-Type"] = "application/octet-stream";
- response.headers["Content-Disposition"] =
- strings::format("attachment; filename=%s", PROFILE_FILE).get();
-
- started = false;
- return response;
-#else
- return http::BadRequest(
- "Perftools is disabled. To enable perftools, "
- "configure libprocess with --enable-perftools.\n");
-#endif
- }
-
- bool started;
-};
-
-} // namespace process {
-
-#endif // __PROCESS_PROCESS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/protobuf.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/protobuf.hpp b/third_party/libprocess/include/process/protobuf.hpp
deleted file mode 100644
index 580c87a..0000000
--- a/third_party/libprocess/include/process/protobuf.hpp
+++ /dev/null
@@ -1,415 +0,0 @@
-#ifndef __PROCESS_PROTOBUF_HPP__
-#define __PROCESS_PROTOBUF_HPP__
-
-#include <glog/logging.h>
-
-#include <google/protobuf/message.h>
-#include <google/protobuf/repeated_field.h>
-
-#include <set>
-#include <vector>
-
-#include <tr1/functional>
-#include <tr1/unordered_map>
-
-#include <process/dispatch.hpp>
-#include <process/process.hpp>
-
-
-// Provides an implementation of process::post that for a protobuf.
-namespace process {
-
-inline void post(const process::UPID& to,
- const google::protobuf::Message& message)
-{
- std::string data;
- message.SerializeToString(&data);
- post(to, message.GetTypeName(), data.data(), data.size());
-}
-
-} // namespace process {
-
-
-// The rest of this file provides libprocess "support" for using
-// protocol buffers. In particular, this file defines a subclass of
-// Process (ProtobufProcess) that allows you to install protocol
-// buffer handlers in addition to normal message and HTTP
-// handlers. Note that this header file assumes you will be linking
-// against BOTH libprotobuf and libglog.
-
-namespace google { namespace protobuf {
-
-// Type conversions helpful for changing between protocol buffer types
-// and standard C++ types (for parameters).
-template <typename T>
-const T& convert(const T& t)
-{
- return t;
-}
-
-
-template <typename T>
-std::vector<T> convert(const google::protobuf::RepeatedPtrField<T>& items)
-{
- std::vector<T> result;
- for (int i = 0; i < items.size(); i++) {
- result.push_back(items.Get(i));
- }
-
- return result;
-}
-
-}} // namespace google { namespace protobuf {
-
-
-template <typename T>
-class ProtobufProcess : public process::Process<T>
-{
-public:
- virtual ~ProtobufProcess() {}
-
-protected:
- virtual void visit(const process::MessageEvent& event)
- {
- if (protobufHandlers.count(event.message->name) > 0) {
- from = event.message->from; // For 'reply'.
- protobufHandlers[event.message->name](event.message->body);
- from = process::UPID();
- } else {
- process::Process<T>::visit(event);
- }
- }
-
- void send(const process::UPID& to,
- const google::protobuf::Message& message)
- {
- std::string data;
- message.SerializeToString(&data);
- process::Process<T>::send(to, message.GetTypeName(),
- data.data(), data.size());
- }
-
- using process::Process<T>::send;
-
- void reply(const google::protobuf::Message& message)
- {
- CHECK(from) << "Attempting to reply without a sender";
- std::string data;
- message.SerializeToString(&data);
- send(from, message);
- }
-
- template <typename M>
- void install(void (T::*method)(const M&))
- {
- google::protobuf::Message* m = new M();
- T* t = static_cast<T*>(this);
- protobufHandlers[m->GetTypeName()] =
- std::tr1::bind(&handlerM<M>,
- t, method,
- std::tr1::placeholders::_1);
- delete m;
- }
-
- template <typename M>
- void install(void (T::*method)())
- {
- google::protobuf::Message* m = new M();
- T* t = static_cast<T*>(this);
- protobufHandlers[m->GetTypeName()] =
- std::tr1::bind(&handler0,
- t, method,
- std::tr1::placeholders::_1);
- delete m;
- }
-
- template <typename M,
- typename P1, typename P1C>
- void install(void (T::*method)(P1C),
- P1 (M::*param1)() const)
- {
- google::protobuf::Message* m = new M();
- T* t = static_cast<T*>(this);
- protobufHandlers[m->GetTypeName()] =
- std::tr1::bind(&handler1<M, P1, P1C>,
- t, method, param1,
- std::tr1::placeholders::_1);
- delete m;
- }
-
- template <typename M,
- typename P1, typename P1C,
- typename P2, typename P2C>
- void install(void (T::*method)(P1C, P2C),
- P1 (M::*p1)() const,
- P2 (M::*p2)() const)
- {
- google::protobuf::Message* m = new M();
- T* t = static_cast<T*>(this);
- protobufHandlers[m->GetTypeName()] =
- std::tr1::bind(&handler2<M, P1, P1C, P2, P2C>,
- t, method, p1, p2,
- std::tr1::placeholders::_1);
- delete m;
- }
-
- template <typename M,
- typename P1, typename P1C,
- typename P2, typename P2C,
- typename P3, typename P3C>
- void install(void (T::*method)(P1C, P2C, P3C),
- P1 (M::*p1)() const,
- P2 (M::*p2)() const,
- P3 (M::*p3)() const)
- {
- google::protobuf::Message* m = new M();
- T* t = static_cast<T*>(this);
- protobufHandlers[m->GetTypeName()] =
- std::tr1::bind(&handler3<M, P1, P1C, P2, P2C, P3, P3C>,
- t, method, p1, p2, p3,
- std::tr1::placeholders::_1);
- delete m;
- }
-
- template <typename M,
- typename P1, typename P1C,
- typename P2, typename P2C,
- typename P3, typename P3C,
- typename P4, typename P4C>
- void install(void (T::*method)(P1C, P2C, P3C, P4C),
- P1 (M::*p1)() const,
- P2 (M::*p2)() const,
- P3 (M::*p3)() const,
- P4 (M::*p4)() const)
- {
- google::protobuf::Message* m = new M();
- T* t = static_cast<T*>(this);
- protobufHandlers[m->GetTypeName()] =
- std::tr1::bind(&handler4<M, P1, P1C, P2, P2C, P3, P3C, P4, P4C>,
- t, method, p1, p2, p3, p4,
- std::tr1::placeholders::_1);
- delete m;
- }
-
- template <typename M,
- typename P1, typename P1C,
- typename P2, typename P2C,
- typename P3, typename P3C,
- typename P4, typename P4C,
- typename P5, typename P5C>
- void install(void (T::*method)(P1C, P2C, P3C, P4C, P5C),
- P1 (M::*p1)() const,
- P2 (M::*p2)() const,
- P3 (M::*p3)() const,
- P4 (M::*p4)() const,
- P5 (M::*p5)() const)
- {
- google::protobuf::Message* m = new M();
- T* t = static_cast<T*>(this);
- protobufHandlers[m->GetTypeName()] =
- std::tr1::bind(&handler5<M, P1, P1C, P2, P2C, P3, P3C, P4, P4C, P5, P5C>,
- t, method, p1, p2, p3, p4, p5,
- std::tr1::placeholders::_1);
- delete m;
- }
-
- using process::Process<T>::install;
-
- process::UPID from; // Sender of "current" message, accessible by subclasses.
-
-private:
- template <typename M>
- static void handlerM(T* t, void (T::*method)(const M&),
- const std::string& data)
- {
- M m;
- m.ParseFromString(data);
- if (m.IsInitialized()) {
- (t->*method)(m);
- } else {
- LOG(WARNING) << "Initialization errors: "
- << m.InitializationErrorString();
- }
- }
-
- static void handler0(T* t, void (T::*method)(),
- const std::string& data)
- {
- (t->*method)();
- }
-
- template <typename M,
- typename P1, typename P1C>
- static void handler1(T* t, void (T::*method)(P1C),
- P1 (M::*p1)() const,
- const std::string& data)
- {
- M m;
- m.ParseFromString(data);
- if (m.IsInitialized()) {
- (t->*method)(google::protobuf::convert((&m->*p1)()));
- } else {
- LOG(WARNING) << "Initialization errors: "
- << m.InitializationErrorString();
- }
- }
-
- template <typename M,
- typename P1, typename P1C,
- typename P2, typename P2C>
- static void handler2(T* t, void (T::*method)(P1C, P2C),
- P1 (M::*p1)() const,
- P2 (M::*p2)() const,
- const std::string& data)
- {
- M m;
- m.ParseFromString(data);
- if (m.IsInitialized()) {
- (t->*method)(google::protobuf::convert((&m->*p1)()),
- google::protobuf::convert((&m->*p2)()));
- } else {
- LOG(WARNING) << "Initialization errors: "
- << m.InitializationErrorString();
- }
- }
-
- template <typename M,
- typename P1, typename P1C,
- typename P2, typename P2C,
- typename P3, typename P3C>
- static void handler3(T* t, void (T::*method)(P1C, P2C, P3C),
- P1 (M::*p1)() const,
- P2 (M::*p2)() const,
- P3 (M::*p3)() const,
- const std::string& data)
- {
- M m;
- m.ParseFromString(data);
- if (m.IsInitialized()) {
- (t->*method)(google::protobuf::convert((&m->*p1)()),
- google::protobuf::convert((&m->*p2)()),
- google::protobuf::convert((&m->*p3)()));
- } else {
- LOG(WARNING) << "Initialization errors: "
- << m.InitializationErrorString();
- }
- }
-
- template <typename M,
- typename P1, typename P1C,
- typename P2, typename P2C,
- typename P3, typename P3C,
- typename P4, typename P4C>
- static void handler4(T* t, void (T::*method)(P1C, P2C, P3C, P4C),
- P1 (M::*p1)() const,
- P2 (M::*p2)() const,
- P3 (M::*p3)() const,
- P4 (M::*p4)() const,
- const std::string& data)
- {
- M m;
- m.ParseFromString(data);
- if (m.IsInitialized()) {
- (t->*method)(google::protobuf::convert((&m->*p1)()),
- google::protobuf::convert((&m->*p2)()),
- google::protobuf::convert((&m->*p3)()),
- google::protobuf::convert((&m->*p4)()));
- } else {
- LOG(WARNING) << "Initialization errors: "
- << m.InitializationErrorString();
- }
- }
-
- template <typename M,
- typename P1, typename P1C,
- typename P2, typename P2C,
- typename P3, typename P3C,
- typename P4, typename P4C,
- typename P5, typename P5C>
- static void handler5(T* t, void (T::*method)(P1C, P2C, P3C, P4C, P5C),
- P1 (M::*p1)() const,
- P2 (M::*p2)() const,
- P3 (M::*p3)() const,
- P4 (M::*p4)() const,
- P5 (M::*p5)() const,
- const std::string& data)
- {
- M m;
- m.ParseFromString(data);
- if (m.IsInitialized()) {
- (t->*method)(google::protobuf::convert((&m->*p1)()),
- google::protobuf::convert((&m->*p2)()),
- google::protobuf::convert((&m->*p3)()),
- google::protobuf::convert((&m->*p4)()),
- google::protobuf::convert((&m->*p5)()));
- } else {
- LOG(WARNING) << "Initialization errors: "
- << m.InitializationErrorString();
- }
- }
-
- typedef std::tr1::function<void(const std::string&)> handler;
- std::tr1::unordered_map<std::string, handler> protobufHandlers;
-};
-
-
-// Implements a process for sending protobuf "requests" to a process
-// and waiting for a protobuf "response", but uses futures so that
-// this can be done without needing to implement a process.
-template <typename Req, typename Res>
-class ReqResProcess : public ProtobufProcess<ReqResProcess<Req, Res> >
-{
-public:
- ReqResProcess(const process::UPID& _pid, const Req& _req)
- : pid(_pid), req(_req)
- {
- ProtobufProcess<ReqResProcess<Req, Res> >::template
- install<Res>(&ReqResProcess<Req, Res>::response);
- }
-
- process::Future<Res> run()
- {
- // Terminate this process if no one cares about the response
- // (note, we need to disambiguate the process::terminate).
- void (*terminate)(const process::UPID&, bool) = &process::terminate;
- promise.future().onDiscarded(
- std::tr1::bind(terminate, process::ProcessBase::self(), true));
-
- ProtobufProcess<ReqResProcess<Req, Res> >::send(pid, req);
-
- return promise.future();
- }
-
-private:
- void response(const Res& res)
- {
- promise.set(res);
- process::terminate(process::ProcessBase::self());
- }
-
- const process::UPID pid;
- const Req req;
- process::Promise<Res> promise;
-};
-
-
-// Allows you to describe request/response protocols and then use
-// those for sending requests and getting back responses.
-template <typename Req, typename Res>
-struct Protocol
-{
- process::Future<Res> operator () (
- const process::UPID& pid,
- const Req& req) const
- {
- // Help debugging by adding some "type constraints".
- { Req* req = NULL; google::protobuf::Message* m = req; (void)m; }
- { Res* res = NULL; google::protobuf::Message* m = res; (void)m; }
-
- ReqResProcess<Req, Res>* process = new ReqResProcess<Req, Res>(pid, req);
- process::spawn(process, true);
- return process::dispatch(process, &ReqResProcess<Req, Res>::run);
- }
-};
-
-#endif // __PROCESS_PROTOBUF_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/run.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/run.hpp b/third_party/libprocess/include/process/run.hpp
deleted file mode 100644
index a245b70..0000000
--- a/third_party/libprocess/include/process/run.hpp
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef __PROCESS_RUN_HPP__
-#define __PROCESS_RUN_HPP__
-
-#include <tr1/memory> // TODO(benh): Replace shared_ptr with unique_ptr.
-
-#include <process/process.hpp>
-
-#include <stout/preprocessor.hpp>
-
-namespace process {
-
-namespace internal {
-
-template <typename R>
-class ThunkProcess : public Process<ThunkProcess<R> >
-{
-public:
- ThunkProcess(std::tr1::shared_ptr<std::tr1::function<R(void)> > _thunk,
- std::tr1::shared_ptr<Promise<R> > _promise)
- : thunk(_thunk),
- promise(_promise) {}
-
- virtual ~ThunkProcess() {}
-
-protected:
- virtual void serve(const Event& event)
- {
- promise->set((*thunk)());
- }
-
-private:
- std::tr1::shared_ptr<std::tr1::function<R(void)> > thunk;
- std::tr1::shared_ptr<Promise<R> > promise;
-};
-
-} // namespace internal {
-
-
-template <typename R>
-Future<R> run(R (*method)(void))
-{
- std::tr1::shared_ptr<std::tr1::function<R(void)> > thunk(
- new std::tr1::function<R(void)>(
- std::tr1::bind(method)));
-
- std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
- Future<R> future = promise->future();
-
- terminate(spawn(new internal::ThunkProcess<R>(thunk, promise), true));
-
- return future;
-}
-
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename R, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<R> run( \
- R (*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- std::tr1::shared_ptr<std::tr1::function<R(void)> > thunk( \
- new std::tr1::function<R(void)>( \
- std::tr1::bind(method, ENUM_PARAMS(N, a)))); \
- \
- std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>()); \
- Future<R> future = promise->future(); \
- \
- terminate(spawn(new internal::ThunkProcess<R>(thunk, promise), true)); \
- \
- return future; \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
-} // namespace process {
-
-#endif // __PROCESS_RUN_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/socket.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/socket.hpp b/third_party/libprocess/include/process/socket.hpp
deleted file mode 100644
index 669a333..0000000
--- a/third_party/libprocess/include/process/socket.hpp
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef __PROCESS_SOCKET_HPP__
-#define __PROCESS_SOCKET_HPP__
-
-#include <assert.h>
-#include <unistd.h> // For close.
-
-#include <iostream>
-
-#include <stout/nothing.hpp>
-#include <stout/os.hpp>
-#include <stout/try.hpp>
-
-// An abstraction around a socket (file descriptor) that provides
-// reference counting such that the socket is only closed (and thus,
-// has the possiblity of being reused) after there are no more
-// references.
-
-class Socket
-{
-public:
- Socket()
- : refs(new int(1)), s(-1) {}
-
- explicit Socket(int _s)
- : refs(new int(1)), s(_s) {}
-
- ~Socket()
- {
- cleanup();
- }
-
- Socket(const Socket& that)
- {
- copy(that);
- }
-
- Socket& operator = (const Socket& that)
- {
- if (this != &that) {
- cleanup();
- copy(that);
- }
- return *this;
- }
-
- bool operator == (const Socket& that) const
- {
- return s == that.s && refs == that.refs;
- }
-
- operator int () const
- {
- return s;
- }
-
-private:
- void copy(const Socket& that)
- {
- assert(that.refs > 0);
- __sync_fetch_and_add(that.refs, 1);
- refs = that.refs;
- s = that.s;
- }
-
- void cleanup()
- {
- assert(refs != NULL);
- if (__sync_sub_and_fetch(refs, 1) == 0) {
- delete refs;
- if (s >= 0) {
- Try<Nothing> close = os::close(s);
- if (close.isError()) {
- std::cerr << "Failed to close socket: " << close.error() << std::endl;
- abort();
- }
- }
- }
- }
-
- int* refs;
- int s;
-};
-
-#endif // __PROCESS_SOCKET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/statistics.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/statistics.hpp b/third_party/libprocess/include/process/statistics.hpp
deleted file mode 100644
index fbae641..0000000
--- a/third_party/libprocess/include/process/statistics.hpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#ifndef __PROCESS_STATISTICS_HPP__
-#define __PROCESS_STATISTICS_HPP__
-
-#include <process/clock.hpp>
-#include <process/future.hpp>
-#include <process/time.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/none.hpp>
-#include <stout/nothing.hpp>
-#include <stout/option.hpp>
-#include <stout/owned.hpp>
-
-namespace process {
-
-// Forward declarations.
-class Statistics;
-class StatisticsProcess;
-
-namespace meters {
- class Meter;
- class TimeRate;
-}
-
-
-// Libprocess statistics handle.
-// To be used from anywhere to manage statistics.
-//
-// Ex: process::statistics->increment("http", "num_requests");
-// process::statistics->set("http", "response_size", response.size());
-//
-// Statistics are exposed via JSON for external visibility.
-extern Statistics* statistics;
-
-const Duration STATISTICS_TRUNCATION_INTERVAL = Minutes(5);
-
-// Provides an in-memory time series of statistics over some window
-// (values are truncated outside of the window, but no limit is
-// currently placed on the number of values within a window).
-//
-// TODO(bmahler): Time series granularity should be coarsened over
-// time. This means, for high-frequency statistics, we keep a lot of
-// recent data points (fine granularity), and keep fewer older data
-// points (coarse granularity). The tunable bit here could be the
-// total number of data points to keep around, which informs how
-// often to delete older data points, while still keeping a window
-// worth of data.
-class Statistics
-{
-public:
- Statistics(const Duration& window);
- ~Statistics();
-
- // Returns the time series of a statistic.
- process::Future<std::map<Time, double> > timeseries(
- const std::string& context,
- const std::string& name,
- const Option<Time>& start = None(),
- const Option<Time>& stop = None());
-
- // Returns the latest value of a statistic.
- process::Future<Option<double> > get(
- const std::string& context,
- const std::string& name);
-
- // Returns the latest values of all statistics in the context.
- process::Future<std::map<std::string, double> > get(
- const std::string& context);
-
- // Adds a meter for the statistic with the provided context and name.
- // get(context, meter->name) will return the metered time series.
- // Returns an error if:
- // -meter->name == name, or
- // -The meter already exists.
- Future<Try<Nothing> > meter(
- const std::string& context,
- const std::string& name,
- Owned<meters::Meter> meter);
-
- // Sets the current value of a statistic at the current clock time
- // or at a specified time.
- void set(
- const std::string& context,
- const std::string& name,
- double value,
- const Time& time = Clock::now());
-
- // Archives the provided statistic time series, and any meters associated
- // with it. This means three things:
- // 1. The statistic will no longer be part of the snapshot.
- // 2. However, the time series will be retained until the window expiration.
- // 3. All meters associated with this statistic will be removed, both
- // (1) and (2) will apply to the metered time series as well.
- void archive(const std::string& context, const std::string& name);
-
- // Increments the current value of a statistic. If no statistic was
- // previously present, an initial value of 0.0 is used.
- void increment(const std::string& context, const std::string& name);
-
- // Decrements the current value of a statistic. If no statistic was
- // previously present, an initial value of 0.0 is used.
- void decrement(const std::string& context, const std::string& name);
-
-private:
- StatisticsProcess* process;
-};
-
-
-namespace meters {
-
-// This is the interface for statistical meters.
-// Meters provide additional metering on top of the raw statistical
-// value. Ex: Track the maximum, average, rate, etc.
-class Meter
-{
-protected:
- Meter(const std::string& _name) : name(_name) {}
-
-public:
- virtual ~Meter() {}
-
- // Updates the meter with another input value.
- // Returns the new metered value, or none if no metered value can be produced.
- virtual Option<double> update(const Time& time, double value) = 0;
-
- const std::string name;
-};
-
-
-// Tracks the percent of time 'used' since the last update.
-// Input values to this meter must be in seconds.
-class TimeRate : public Meter
-{
-public:
- TimeRate(const std::string& name)
- : Meter(name), time(None()), value(0) {}
-
- virtual ~TimeRate() {}
-
- virtual Option<double> update(const Time& _time, double _value)
- {
- Option<double> rate;
- if (time.isSome()) {
- rate = (_value - value) / (_time - time.get()).secs();
- }
-
- time = _time;
- value = _value;
- return rate;
- }
-
-private:
- Option<Time> time;
- double value;
-};
-
-} // namespace meters {
-} // namespace process {
-
-#endif // __PROCESS_STATISTICS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/thread.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/thread.hpp b/third_party/libprocess/include/process/thread.hpp
deleted file mode 100644
index 3e3b5d2..0000000
--- a/third_party/libprocess/include/process/thread.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef __PROCESS_THREAD_HPP__
-#define __PROCESS_THREAD_HPP__
-
-#include <pthread.h>
-#include <stdio.h> // For perror.
-#include <stdlib.h> // For abort.
-
-template <typename T>
-struct ThreadLocal
-{
- ThreadLocal()
- {
- if (pthread_key_create(&key, NULL) != 0) {
- perror("Failed to create thread local, pthread_key_create");
- abort();
- }
- }
-
- ThreadLocal<T>& operator = (T* t)
- {
- if (pthread_setspecific(key, t) != 0) {
- perror("Failed to set thread local, pthread_setspecific");
- abort();
- }
- return *this;
- }
-
- operator T* () const
- {
- return reinterpret_cast<T*>(pthread_getspecific(key));
- }
-
- T* operator -> () const
- {
- return reinterpret_cast<T*>(pthread_getspecific(key));
- }
-
-private:
- // Not expecting any other operators to be used (and the rest?).
- bool operator * (const ThreadLocal<T>&) const;
- bool operator == (const ThreadLocal<T>&) const;
- bool operator != (const ThreadLocal<T>&) const;
- bool operator < (const ThreadLocal<T>&) const;
- bool operator > (const ThreadLocal<T>&) const;
-
- pthread_key_t key;
-};
-
-#endif // __PROCESS_THREAD_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/time.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/time.hpp b/third_party/libprocess/include/process/time.hpp
deleted file mode 100644
index 307fd2c..0000000
--- a/third_party/libprocess/include/process/time.hpp
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef __PROCESS_TIME_HPP__
-#define __PROCESS_TIME_HPP__
-
-#include <iomanip>
-
-#include <glog/logging.h>
-
-#include <stout/duration.hpp>
-
-namespace process {
-
-// Represents an instant in time.
-class Time
-{
-public:
- // Constructs a time at the Epoch. It is needed because collections
- // (e.g., std::map) require a default constructor to construct
- // empty values.
- Time() : sinceEpoch(Duration::zero()) {}
-
- static Time EPOCH;
- static Time MAX;
-
- static Try<Time> create(double secs)
- {
- Try<Duration> duration = Duration::create(secs);
- if (duration.isSome()) {
- return Time(duration.get());
- } else {
- return Error("Argument too large for Time: " + duration.error());
- }
- }
-
- Duration duration() const { return sinceEpoch; }
-
- double secs() const { return sinceEpoch.secs(); }
-
- bool operator < (const Time& t) const { return sinceEpoch < t.sinceEpoch; }
- bool operator <= (const Time& t) const { return sinceEpoch <= t.sinceEpoch; }
- bool operator > (const Time& t) const { return sinceEpoch > t.sinceEpoch; }
- bool operator >= (const Time& t) const { return sinceEpoch >= t.sinceEpoch; }
- bool operator == (const Time& t) const { return sinceEpoch == t.sinceEpoch; }
- bool operator != (const Time& t) const { return sinceEpoch != t.sinceEpoch; }
-
- Time& operator += (const Duration& d)
- {
- sinceEpoch += d;
- return *this;
- }
-
- Time& operator -= (const Duration& d)
- {
- sinceEpoch -= d;
- return *this;
- }
-
- Duration operator - (const Time& that) const
- {
- return sinceEpoch - that.sinceEpoch;
- }
-
- Time operator + (const Duration& duration) const
- {
- Time new_ = *this;
- new_ += duration;
- return new_;
- }
-
- Time operator - (const Duration& duration) const
- {
- Time new_ = *this;
- new_ -= duration;
- return new_;
- }
-
-private:
- Duration sinceEpoch;
-
- // Made it private to avoid the confusion between Time and Duration.
- // Users should explicitly use Clock::now() and Time::create() to
- // create a new time instance.
- Time(const Duration& _sinceEpoch) : sinceEpoch(_sinceEpoch) {}
-};
-
-
-// Outputs the time in RFC 3339 Format.
-inline std::ostream& operator << (std::ostream& stream, const Time& time)
-{
- // Round down the secs to use it with strftime and then append the
- // fraction part.
- long secs = static_cast<long>(time.secs());
- char date[64];
-
- // The RFC 3339 Format.
- tm* tm_ = gmtime(&secs);
- if (tm_ == NULL) {
- LOG(ERROR) << "Cannot convert the 'time' to a tm struct using gmtime(): "
- << errno;
- return stream;
- }
-
- strftime(date, 64, "%Y-%m-%d %H:%M:%S", tm_);
- stream << date;
-
- // Append the fraction part in nanoseconds.
- int64_t nsecs = (time.duration() - Seconds(secs)).ns();
-
- if (nsecs != 0) {
- char prev = stream.fill();
-
- // 9 digits for nanosecond level precision.
- stream << "." << std::setfill('0') << std::setw(9) << nsecs;
-
- // Return the stream to original formatting state.
- stream.fill(prev);
- }
-
- stream << "+00:00";
- return stream;
-}
-
-} // namespace process {
-
-#endif // __PROCESS_TIME_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/timeout.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/timeout.hpp b/third_party/libprocess/include/process/timeout.hpp
deleted file mode 100644
index 4634b9f..0000000
--- a/third_party/libprocess/include/process/timeout.hpp
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef __PROCESS_TIMEOUT_HPP__
-#define __PROCESS_TIMEOUT_HPP__
-
-#include <process/process.hpp>
-
-#include <process/time.hpp>
-
-#include <stout/duration.hpp>
-
-
-namespace process {
-
-class Timeout
-{
-public:
- Timeout() : timeout(Clock::now()) {}
-
- Timeout(const Time& time) : timeout(time) {}
-
- Timeout(const Timeout& that) : timeout(that.timeout) {}
-
- // Constructs a Timeout instance from a Time that is the 'duration'
- // from now.
- static Timeout in(const Duration& duration)
- {
- return Timeout(Clock::now() + duration);
- }
-
- Timeout& operator = (const Timeout& that)
- {
- if (this != &that) {
- timeout = that.timeout;
- }
-
- return *this;
- }
-
- Timeout& operator = (const Duration& duration)
- {
- timeout = Clock::now() + duration;
- return *this;
- }
-
- bool operator == (const Timeout& that) const
- {
- return timeout == that.timeout;
- }
-
- bool operator < (const Timeout& that) const
- {
- return timeout < that.timeout;
- }
-
- bool operator <= (const Timeout& that) const
- {
- return timeout <= that.timeout;
- }
-
- // Returns the value of the timeout as a Time object.
- Time time() const
- {
- return timeout;
- }
-
- // Returns the amount of time remaining.
- Duration remaining() const
- {
- Duration remaining = timeout - Clock::now();
- return remaining > Duration::zero() ? remaining : Duration::zero();
- }
-
- // Returns true if the timeout expired.
- bool expired() const
- {
- return timeout <= Clock::now();
- }
-
-private:
- Time timeout;
-};
-
-} // namespace process {
-
-#endif // __PROCESS_TIMEOUT_HPP__
[34/35] git commit: Added stout specific 'CHECK' constructs.
Posted by be...@apache.org.
Added stout specific 'CHECK' constructs.
Review: https://reviews.apache.org/r/11472
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/72395798
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/72395798
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/72395798
Branch: refs/heads/master
Commit: 723957980974ddbf5b206500b894731fcce7699d
Parents: 71a01bd
Author: Benjamin Hindman <be...@twitter.com>
Authored: Mon May 27 12:10:52 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:20:25 2013 -0700
----------------------------------------------------------------------
3rdparty/libprocess/3rdparty/stout/Makefile.am | 1 +
.../3rdparty/stout/include/stout/check.hpp | 89 +++++++++++++++
2 files changed, 90 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/72395798/3rdparty/libprocess/3rdparty/stout/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/Makefile.am b/3rdparty/libprocess/3rdparty/stout/Makefile.am
index fdd3482..4fdee2c 100644
--- a/3rdparty/libprocess/3rdparty/stout/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/Makefile.am
@@ -7,6 +7,7 @@ AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = \
include/stout/bytes.hpp \
include/stout/cache.hpp \
+ include/stout/check.hpp \
include/stout/duration.hpp \
include/stout/error.hpp \
include/stout/exit.hpp \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/72395798/3rdparty/libprocess/3rdparty/stout/include/stout/check.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/check.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/check.hpp
new file mode 100644
index 0000000..0165d42
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/check.hpp
@@ -0,0 +1,89 @@
+#ifndef __STOUT_CHECK_HPP__
+#define __STOUT_CHECK_HPP__
+
+#include <ostream>
+#include <sstream>
+#include <string>
+
+#include <glog/logging.h> // Includes LOG(*), PLOG(*), CHECK, etc.
+
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+#include <stout/try.hpp>
+
+// Provides a CHECK_SOME macro, akin to CHECK.
+// This appends the error if possible to the end of the log message, so there's
+// no need to append the error message explicitly.
+#define CHECK_SOME(expression) \
+ for (const Option<std::string>& _error = _check(expression); \
+ _error.isSome();) \
+ _CheckSome(__FILE__, __LINE__, #expression, _error.get()).stream() \
+
+// Private structs/functions used for CHECK_SOME.
+
+template <typename T>
+Option<std::string> _check(const Option<T>& o)
+{
+ if (o.isNone()) {
+ return Option<std::string>::some("is NONE");
+ }
+ return None();
+}
+
+
+template <typename T>
+Option<std::string> _check(const Try<T>& t)
+{
+ if (t.isError()) {
+ return t.error();
+ }
+ return None();
+}
+
+
+template <typename T>
+Option<std::string> _check(const Result<T>& r)
+{
+ if (r.isError()) {
+ return r.error();
+ } else if (r.isNone()) {
+ return Option<std::string>::some("is NONE");
+ }
+ return None();
+}
+
+
+struct _CheckSome
+{
+ _CheckSome(const char* _file,
+ int _line,
+ const char* _expression,
+ const std::string& _error)
+ : file(_file),
+ line(_line),
+ expression(_expression),
+ error(_error)
+ {
+ out << "CHECK_SOME(" << expression << "): ";
+ }
+
+ ~_CheckSome()
+ {
+ out << error;
+ google::LogMessageFatal(file.c_str(), line).stream() << out.str();
+ }
+
+ std::ostream& stream()
+ {
+ return out;
+ }
+
+ const std::string file;
+ const int line;
+ const std::string expression;
+ const std::string error;
+ std::ostringstream out;
+};
+
+#endif // __STOUT_CHECK_HPP__
[14/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/statistics.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/statistics.cpp b/third_party/libprocess/src/statistics.cpp
deleted file mode 100644
index d8f5ad1..0000000
--- a/third_party/libprocess/src/statistics.cpp
+++ /dev/null
@@ -1,508 +0,0 @@
-#include <glog/logging.h>
-
-#include <algorithm>
-#include <list>
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <process/clock.hpp>
-#include <process/delay.hpp>
-#include <process/dispatch.hpp>
-#include <process/future.hpp>
-#include <process/http.hpp>
-#include <process/process.hpp>
-#include <process/statistics.hpp>
-#include <process/time.hpp>
-
-#include <stout/error.hpp>
-#include <stout/duration.hpp>
-#include <stout/foreach.hpp>
-#include <stout/hashmap.hpp>
-#include <stout/hashset.hpp>
-#include <stout/json.hpp>
-#include <stout/none.hpp>
-#include <stout/numify.hpp>
-#include <stout/option.hpp>
-#include <stout/stringify.hpp>
-#include <stout/strings.hpp>
-
-using namespace process;
-using namespace process::http;
-
-using std::list;
-using std::map;
-using std::string;
-using std::vector;
-
-namespace process {
-
-// This is initialized by process::initialize().
-Statistics* statistics = NULL;
-
-// TODO(bmahler): Move time series related logic into this struct.
-// TODO(bmahler): Investigate using google's btree implementation.
-// This provides better insertion and lookup performance for large
-// containers. This _should_ also provide significant memory
-// savings, especially since:
-// 1. Our insertion order will mostly be in sorted order.
-// 2. Our keys (Seconds) have efficient comparison operators.
-// See: http://code.google.com/p/cpp-btree/
-// http://code.google.com/p/cpp-btree/wiki/UsageInstructions
-struct TimeSeries
-{
- TimeSeries() : values(), archived(false) {}
-
- // We use a map instead of a hashmap to store the values because
- // that way we can retrieve a series in sorted order efficiently.
- map<Time, double> values;
- bool archived;
-};
-
-
-class StatisticsProcess : public Process<StatisticsProcess>
-{
-public:
- StatisticsProcess(const Duration& _window)
- : ProcessBase("statistics"),
- window(_window) {}
-
- virtual ~StatisticsProcess() {}
-
- // Statistics implementation.
- map<Time, double> timeseries(
- const string& context,
- const string& name,
- const Option<Time>& start,
- const Option<Time>& stop);
-
- Option<double> get(const string& context, const string& name);
-
- map<string, double> get(const string& context);
-
- Try<Nothing> meter(
- const string& context,
- const string& name,
- const Owned<meters::Meter>& meter);
-
- void set(
- const string& context,
- const string& name,
- double value,
- const Time& time);
-
- void archive(const string& context, const string& name);
-
- void increment(const string& context, const string& name);
-
- void decrement(const string& context, const string& name);
-
-protected:
- virtual void initialize()
- {
- route("/snapshot.json", &StatisticsProcess::snapshot);
- route("/series.json", &StatisticsProcess::series);
-
- // Schedule the first truncation.
- delay(STATISTICS_TRUNCATION_INTERVAL, self(), &StatisticsProcess::truncate);
- }
-
-private:
- // Removes values for the specified statistic that occurred outside
- // the time series window.
- // NOTE: We always ensure there is at least 1 value left for a statistic,
- // unless it is archived!
- // Returns true iff the time series is empty.
- bool truncate(const string& context, const string& name);
-
- // Removes values for all statistics that occurred outside the time
- // series window.
- // NOTE: Runs periodically every STATISTICS_TRUNCATION_INTERVAL.
- // NOTE: We always ensure there is at least 1 value left for a statistic,
- // unless it is archived.
- void truncate();
-
- // Returns the a snapshot of all statistics in JSON.
- Future<Response> snapshot(const Request& request);
-
- // Returns the time series of a statistic in JSON.
- Future<Response> series(const Request& request);
-
- const Duration window;
-
- // This maps from {context: {name: TimeSeries } }.
- hashmap<string, hashmap<string, TimeSeries> > statistics;
-
- // Each statistic can have many meters.
- // This maps from {context: {name: [meters] } }.
- hashmap<string, hashmap<string, list<Owned<meters::Meter> > > > meters;
-};
-
-
-Try<Nothing> StatisticsProcess::meter(
- const string& context,
- const string& name,
- const Owned<meters::Meter>& meter)
-{
- if (meter->name == name) {
- return Error("Meter name must not match the statistic name");
- }
-
- // Check for a duplicate meter.
- foreachkey (const string& context, meters) {
- foreachkey (const string& name, meters[context]) {
- foreach (Owned<meters::Meter>& existing, meters[context][name]) {
- if (meter->name == existing->name) {
- return Error("Meter name matched existing meter name");
- }
- }
- }
- }
-
- // Add the meter.
- meters[context][name].push_back(meter);
-
- return Nothing();
-}
-
-
-map<Time, double> StatisticsProcess::timeseries(
- const string& context,
- const string& name,
- const Option<Time>& start,
- const Option<Time>& stop)
-{
- if (!statistics.contains(context) || !statistics[context].contains(name)) {
- return map<Time, double>();
- }
-
- const std::map<Time, double>& values =
- statistics[context].find(name)->second.values;
-
- map<Time, double>::const_iterator lower = values.lower_bound(start.isSome()
- ? start.get() : Time::EPOCH);
-
- map<Time, double>::const_iterator upper = values.upper_bound(stop.isSome()
- ? stop.get() : Time::MAX);
-
- return map<Time, double>(lower, upper);
-}
-
-
-Option<double> StatisticsProcess::get(const string& context, const string& name)
-{
- if (!statistics.contains(context) ||
- !statistics[context].contains(name) ||
- statistics[context][name].values.empty()) {
- return Option<double>::none();
- } else {
- return statistics[context][name].values.rbegin()->second;
- }
-}
-
-
-map<string, double> StatisticsProcess::get(const string& context)
-{
- map<string, double> results;
-
- if (!statistics.contains(context)) {
- return results;
- }
-
- foreachkey (const string& name, statistics[context]) {
- const map<Time, double>& values = statistics[context][name].values;
-
- if (!values.empty()) {
- results[name] = values.rbegin()->second;
- }
- }
-
- return results;
-}
-
-
-void StatisticsProcess::set(
- const string& context,
- const string& name,
- double value,
- const Time& time)
-{
- statistics[context][name].values[time] = value; // Update the raw value.
- statistics[context][name].archived = false; // Unarchive.
-
- truncate(context, name);
-
- // Update the metered values, if necessary.
- if (meters.contains(context) && meters[context].contains(name)) {
- foreach (Owned<meters::Meter>& meter, meters[context][name]) {
- const Option<double>& update = meter->update(time, value);
- statistics[context][meter->name].archived = false; // Unarchive.
-
- if (update.isSome()) {
- statistics[context][meter->name].values[time] = update.get();
- truncate(context, meter->name);
- }
- }
- }
-}
-
-
-void StatisticsProcess::archive(const string& context, const string& name)
-{
- // Exclude the statistic from the snapshot.
- statistics[context][name].archived = true;
-
- // Remove any meters as well.
- if (meters.contains(context) && meters[context].contains(name)) {
- foreach (const Owned<meters::Meter>& meter, meters[context][name]) {
- statistics[context][meter->name].archived = true;
- }
- meters[context].erase(name);
- }
-}
-
-
-void StatisticsProcess::increment(const string& context, const string& name)
-{
- double value = 0.0;
- if (!statistics[context][name].values.empty()) {
- value = statistics[context][name].values.rbegin()->second;
- }
- set(context, name, value + 1.0, Clock::now());
-}
-
-
-void StatisticsProcess::decrement(const string& context, const string& name)
-{
- double value = 0.0;
- if (!statistics[context][name].values.empty()) {
- value = statistics[context][name].values.rbegin()->second;
- }
- set(context, name, value - 1.0, Clock::now());
-}
-
-
-bool StatisticsProcess::truncate(const string& context, const string& name)
-{
- CHECK(statistics.contains(context));
- CHECK(statistics[context].contains(name));
-
- if (statistics[context][name].values.empty()) {
- return true; // No truncation is needed, the time series is already empty.
- }
-
- map<Time, double>::iterator start =
- statistics[context][name].values.begin();
-
- while ((Clock::now() - start->first) > window) {
- // Always keep at least one value for a statistic, unless it's archived!
- if (statistics[context][name].values.size() == 1) {
- if (statistics[context][name].archived) {
- statistics[context][name].values.clear();
- }
- break;
- }
-
- statistics[context][name].values.erase(start);
- start = statistics[context][name].values.begin();
- }
-
- return statistics[context][name].values.empty();
-}
-
-
-void StatisticsProcess::truncate()
-{
- hashmap<string, hashset<string> > empties;
-
- foreachkey (const string& context, statistics) {
- foreachkey (const string& name, statistics[context]) {
- // Keep track of the emptied timeseries.
- if (truncate(context, name)) {
- empties[context].insert(name);
- }
- }
- }
-
- // Remove the empty timeseries.
- foreachkey (const string& context, empties) {
- foreach (const string& name, empties[context]) {
- statistics[context].erase(name);
- }
- }
-
- delay(STATISTICS_TRUNCATION_INTERVAL, self(), &StatisticsProcess::truncate);
-}
-
-
-Future<Response> StatisticsProcess::snapshot(const Request& request)
-{
- JSON::Array array;
-
- Option<string> queryContext = request.query.get("context");
- Option<string> queryName = request.query.get("name");
-
- foreachkey (const string& context, statistics) {
- foreachkey (const string& name, statistics[context]) {
- // Exclude archived and empty time series.
- if (statistics[context][name].archived ||
- statistics[context][name].values.empty()) {
- continue;
- }
-
- // Skip statistics that don't match the query, if present.
- if (queryContext.isSome() && queryContext.get() != context) {
- continue;
- } else if (queryName.isSome() && queryName.get() != name) {
- continue;
- }
-
- JSON::Object object;
- object.values["context"] = context;
- object.values["name"] = name;
- object.values["time"] =
- statistics[context][name].values.rbegin()->first.secs();
- object.values["value"] =
- statistics[context][name].values.rbegin()->second;
- array.values.push_back(object);
- }
- }
-
- return OK(array, request.query.get("jsonp"));
-}
-
-
-Future<Response> StatisticsProcess::series(const Request& request)
-{
- Option<string> context = request.query.get("context");
- Option<string> name = request.query.get("name");
-
- if (!context.isSome()) {
- return BadRequest("Expected 'context=val' in query.\n");
- } else if (!name.isSome()) {
- return BadRequest("Expected 'name=val' in query.\n");
- }
-
- Option<Time> start = None();
- Option<Time> stop = None();
-
- if (request.query.get("start").isSome()) {
- Try<double> result = numify<double>(request.query.get("start").get());
- if (result.isError()) {
- return BadRequest("Failed to parse 'start': " + result.error());
- }
-
- Try<Time> start_ = Time::create(result.get());
- if (start_.isError()) {
- return BadRequest("Failed to parse 'start': " + start_.error());
- }
- start = start_.get();
- }
-
- if (request.query.get("stop").isSome()) {
- Try<double> result = numify<double>(request.query.get("stop").get());
- if (result.isError()) {
- return BadRequest("Failed to parse 'stop': " + result.error());
- }
-
- Try<Time> stop_ = Time::create(result.get());
- if (stop_.isError()) {
- return BadRequest("Failed to parse 'stop': " + stop_.error());
- }
- stop = stop_.get();
- }
-
- JSON::Array array;
-
- const map<Time, double>& values =
- timeseries(context.get(), name.get(), start, stop);
-
- foreachpair (const Time& s, double value, values) {
- JSON::Object object;
- object.values["time"] = s.secs();
- object.values["value"] = value;
- array.values.push_back(object);
- }
-
- return OK(array, request.query.get("jsonp"));
-}
-
-
-Statistics::Statistics(const Duration& window)
-{
- process = new StatisticsProcess(window);
- spawn(process);
-}
-
-
-Statistics::~Statistics()
-{
- terminate(process);
- wait(process);
-}
-
-
-Future<map<Time, double> > Statistics::timeseries(
- const string& context,
- const string& name,
- const Option<Time>& start,
- const Option<Time>& stop)
-{
- return dispatch(
- process, &StatisticsProcess::timeseries, context, name, start, stop);
-}
-
-
-Future<Option<double> > Statistics::get(
- const string& context,
- const string& name)
-{
- return dispatch(process, &StatisticsProcess::get, context, name);
-}
-
-
-Future<map<string, double> > Statistics::get(const string& context)
-{
- return dispatch(process, &StatisticsProcess::get, context);
-}
-
-
-Future<Try<Nothing> > Statistics::meter(
- const string& context,
- const string& name,
- Owned<meters::Meter> meter)
-{
-
- return dispatch(process, &StatisticsProcess::meter, context, name, meter);
-}
-
-
-void Statistics::set(
- const string& context,
- const string& name,
- double value,
- const Time& time)
-{
- dispatch(process, &StatisticsProcess::set, context, name, value, time);
-}
-
-
-void Statistics::archive(const string& context, const string& name)
-{
- dispatch(process, &StatisticsProcess::archive, context, name);
-}
-
-
-void Statistics::increment(const string& context, const string& name)
-{
- dispatch(process, &StatisticsProcess::increment, context, name);
-}
-
-
-void Statistics::decrement(const string& context, const string& name)
-{
- dispatch(process, &StatisticsProcess::decrement, context, name);
-}
-
-} // namespace process {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/synchronized.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/synchronized.cpp b/third_party/libprocess/src/synchronized.cpp
deleted file mode 100644
index 79b0849..0000000
--- a/third_party/libprocess/src/synchronized.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "synchronized.hpp"
-
-using std::string;
-
-
-static string s1;
-static synchronizable(s1);
-
-static string s2;
-static synchronizable(s2) = SYNCHRONIZED_INITIALIZER;
-
-static string s3;
-static synchronizable(s3) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
-
-
-void bar()
-{
- synchronized(s3) {
-
- }
-}
-
-
-void foo()
-{
- synchronized(s3) {
- bar();
- }
-}
-
-
-class Foo
-{
-public:
- Foo()
- {
- synchronizer(s) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
- }
-
- void foo()
- {
- synchronized(s) {
- synchronized(s) {
-
- }
- }
- }
-
-private:
- string s;
- synchronizable(s);
-};
-
-
-int main(int argc, char **argv)
-{
- synchronizer(s1) = SYNCHRONIZED_INITIALIZER_RECURSIVE;
- //synchronizer(s2) = SYNCHRONIZED_INITIALIZER;
-
- //foo();
-
- Foo f;
- f.foo();
-
- return 0;
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/synchronized.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/synchronized.hpp b/third_party/libprocess/src/synchronized.hpp
deleted file mode 100644
index 7e0efe2..0000000
--- a/third_party/libprocess/src/synchronized.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include <pthread.h>
-
-#include <iostream>
-
-
-class Synchronizable
-{
-public:
- Synchronizable()
- : initialized(false) {}
-
- explicit Synchronizable(int _type)
- : type(_type), initialized(false)
- {
- initialize();
- }
-
- Synchronizable(const Synchronizable &that)
- {
- type = that.type;
- initialize();
- }
-
- Synchronizable & operator = (const Synchronizable &that)
- {
- type = that.type;
- initialize();
- return *this;
- }
-
- void acquire()
- {
- if (!initialized) {
- std::cerr << "synchronizable not initialized" << std::endl;
- abort();
- }
- pthread_mutex_lock(&mutex);
- }
-
- void release()
- {
- if (!initialized) {
- std::cerr << "synchronizable not initialized" << std::endl;
- abort();
- }
- pthread_mutex_unlock(&mutex);
- }
-
-private:
- void initialize()
- {
- if (!initialized) {
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, type);
- pthread_mutex_init(&mutex, &attr);
- pthread_mutexattr_destroy(&attr);
- initialized = true;
- } else {
- std::cerr << "synchronizable already initialized" << std::endl;
- abort();
- }
- }
-
- int type;
- bool initialized;
- pthread_mutex_t mutex;
-};
-
-
-class Synchronized
-{
-public:
- Synchronized(Synchronizable *_synchronizable)
- : synchronizable(_synchronizable)
- {
- synchronizable->acquire();
- }
-
- ~Synchronized()
- {
- synchronizable->release();
- }
-
- operator bool () { return true; }
-
-private:
- Synchronizable *synchronizable;
-};
-
-
-#define synchronized(s) \
- if (Synchronized __synchronized ## s = Synchronized(&__synchronizable_ ## s))
-
-#define synchronizable(s) \
- Synchronizable __synchronizable_ ## s
-
-#define synchronizer(s) \
- (__synchronizable_ ## s)
-
-
-#define SYNCHRONIZED_INITIALIZER Synchronizable(PTHREAD_MUTEX_NORMAL)
-#define SYNCHRONIZED_INITIALIZER_DEBUG Synchronizable(PTHREAD_MUTEX_ERRORCHECK)
-#define SYNCHRONIZED_INITIALIZER_RECURSIVE Synchronizable(PTHREAD_MUTEX_RECURSIVE)
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/test-master.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/test-master.cpp b/third_party/libprocess/src/test-master.cpp
deleted file mode 100644
index 23c6e1d..0000000
--- a/third_party/libprocess/src/test-master.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <io.hpp>
-#include <tuple.hpp>
-
-#include <string>
-
-#include "test.hpp"
-
-using std::string;
-
-
-using namespace process::tuple;
-
-
-class Master : public Tuple<Process>
-{
-private:
- int id;
-
-protected:
- void operator () ()
- {
- do {
- switch (receive()) {
- case REGISTER: {
- Out::println("Master received REGISTER");
-
- string name;
- unpack<REGISTER>(name);
-
- Out::println("Registered slave: %s", name.c_str());
-
- send(from(), pack<OKAY>(id++));
- break;
- }
- case UNREGISTER: {
- Out::println("Master received UNREGISTER");
-
- int slave_id;
- unpack<UNREGISTER>(slave_id);
-
- Out::println("Unregistered slave id: %d", slave_id);
-
- send(from(), pack<OKAY>(0));
- break;
- }
- default:
- Out::println("UNKNOWN MESSAGE RECEIVED");
- }
- } while (true);
- }
-
-public:
- Master() : id(0) {}
-};
-
-
-int main(int argc, char **argv)
-{
- PID master = Process::spawn(new Master());
- Out::println("master: %s", string(master).c_str());
- Process::wait(master);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/test-slave.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/test-slave.cpp b/third_party/libprocess/src/test-slave.cpp
deleted file mode 100644
index fe08ce8..0000000
--- a/third_party/libprocess/src/test-slave.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <test.hpp>
-
-using namespace process::record;
-
-class Slave : public RecordProcess
-{
-private:
- PID master;
- int id;
-
-protected:
- void operator () ()
- {
- send(master, pack<REGISTER>("c3po"));
-
- switch (receive()) {
- case OKAY: {
- std::cout << "slave registered" << std::endl;
- unpack<OKAY>(id);
- std::cout << "slave id: " << id << std::endl;
- break;
- }
- default:
- std::cout << "slave failed to register" << std::endl;
- break;
- }
-
- send(master, pack<UNREGISTER>(id));
-
- switch (receive()) {
- case OKAY:
- std::cout << "slave unregistered" << std::endl;
- break;
- default:
- std::cout << "slave failed to unregister" << std::endl;
- break;
- }
-
- link(master);
- switch (receive()) {
- case PROCESS_EXIT:
- std::cout << "master exited" << std::endl;
- break;
- default:
- std::cout << "unexpected message" << std::endl;
- break;
- }
- }
-
-public:
- Slave(const PID &_master) : master(_master) {}
-};
-
-
-int main(int argc, char **argv)
-{
- PID master = make_pid(argv[1]);
- PID slave = Process::spawn(new Slave(master));
- std::cout << "slave is at " << slave << std::endl;
- Process::wait(slave);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/tests/decoder_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/tests/decoder_tests.cpp b/third_party/libprocess/src/tests/decoder_tests.cpp
deleted file mode 100644
index 04ca3ff..0000000
--- a/third_party/libprocess/src/tests/decoder_tests.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-#include <gmock/gmock.h>
-
-#include <deque>
-#include <string>
-
-#include <process/socket.hpp>
-
-#include <stout/gtest.hpp>
-
-#include "decoder.hpp"
-
-using namespace process;
-using namespace process::http;
-
-using std::deque;
-using std::string;
-
-
-TEST(Decoder, Request)
-{
- DataDecoder decoder = DataDecoder(Socket());
-
- const string& data =
- "GET /path/file.json?key1=value1&key2=value2#fragment HTTP/1.1\r\n"
- "Host: localhost\r\n"
- "Connection: close\r\n"
- "Accept-Encoding: compress, gzip\r\n"
- "\r\n";
-
- deque<Request*> requests = decoder.decode(data.data(), data.length());
- ASSERT_FALSE(decoder.failed());
- ASSERT_EQ(1, requests.size());
-
- Request* request = requests[0];
- EXPECT_EQ("GET", request->method);
- EXPECT_EQ("/path/file.json", request->path);
- EXPECT_EQ("/path/file.json?key1=value1&key2=value2#fragment", request->url);
- EXPECT_EQ("fragment", request->fragment);
- EXPECT_TRUE(request->body.empty());
- EXPECT_FALSE(request->keepAlive);
-
- EXPECT_EQ(3, request->headers.size());
- EXPECT_SOME_EQ("localhost", request->headers.get("Host"));
- EXPECT_SOME_EQ("close", request->headers.get("Connection"));
- EXPECT_SOME_EQ("compress, gzip", request->headers.get("Accept-Encoding"));
-
- EXPECT_EQ(2, request->query.size());
- EXPECT_SOME_EQ("value1", request->query.get("key1"));
- EXPECT_SOME_EQ("value2", request->query.get("key2"));
-
- delete request;
-}
-
-
-TEST(Decoder, RequestHeaderContinuation)
-{
- DataDecoder decoder = DataDecoder(Socket());
-
- const string& data =
- "GET /path/file.json HTTP/1.1\r\n"
- "Host: localhost\r\n"
- "Connection: close\r\n"
- "Accept-Encoding: compress,"
- " gzip\r\n"
- "\r\n";
-
- deque<Request*> requests = decoder.decode(data.data(), data.length());
- ASSERT_FALSE(decoder.failed());
- ASSERT_EQ(1, requests.size());
-
- Request* request = requests[0];
- EXPECT_SOME_EQ("compress, gzip",
- request->headers.get("Accept-Encoding"));
- delete request;
-}
-
-
-// This is expected to fail for now, see my TODO(bmahler) on http::Request.
-TEST(Decoder, DISABLED_RequestHeaderCaseInsensitive)
-{
- DataDecoder decoder = DataDecoder(Socket());
-
- const string& data =
- "GET /path/file.json HTTP/1.1\r\n"
- "Host: localhost\r\n"
- "cOnnECtioN: close\r\n"
- "accept-ENCODING: compress, gzip\r\n"
- "\r\n";
-
- deque<Request*> requests = decoder.decode(data.data(), data.length());
- ASSERT_FALSE(decoder.failed());
- ASSERT_EQ(1, requests.size());
-
- Request* request = requests[0];
- EXPECT_FALSE(request->keepAlive);
-
- EXPECT_SOME_EQ("compress, gzip", request->headers.get("Accept-Encoding"));
-
- delete request;
-}
-
-
-TEST(Decoder, Response)
-{
- ResponseDecoder decoder;
-
- const string& data =
- "HTTP/1.1 200 OK\r\n"
- "Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"
- "Content-Type: text/plain\r\n"
- "Content-Length: 2\r\n"
- "\r\n"
- "hi";
-
- deque<Response*> requests = decoder.decode(data.data(), data.length());
- ASSERT_FALSE(decoder.failed());
- ASSERT_EQ(1, requests.size());
-
- Response* response = requests[0];
-
- EXPECT_EQ("200 OK", response->status);
- EXPECT_EQ(Response::BODY, response->type);
- EXPECT_EQ("hi", response->body);
-
- EXPECT_EQ(3, response->headers.size());
-
- delete response;
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/tests/encoder_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/tests/encoder_tests.cpp b/third_party/libprocess/src/tests/encoder_tests.cpp
deleted file mode 100644
index fccb865..0000000
--- a/third_party/libprocess/src/tests/encoder_tests.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include <gmock/gmock.h>
-
-#include <deque>
-#include <string>
-#include <vector>
-
-#include <process/http.hpp>
-#include <process/socket.hpp>
-
-#include <stout/gtest.hpp>
-
-#include "encoder.hpp"
-#include "decoder.hpp"
-
-using namespace process;
-using namespace process::http;
-
-using std::deque;
-using std::string;
-using std::vector;
-
-
-TEST(Encoder, Response)
-{
- Request request;
- const OK& response("body");
-
- // Encode the response.
- const string& encoded = HttpResponseEncoder::encode(response, request);
-
- // Now decode it back, and verify the encoding was correct.
- ResponseDecoder decoder;
- deque<Response*> responses = decoder.decode(encoded.data(), encoded.length());
- ASSERT_FALSE(decoder.failed());
- ASSERT_EQ(1, responses.size());
-
- Response* decoded = responses[0];
- EXPECT_EQ("200 OK", decoded->status);
- EXPECT_EQ("body", decoded->body);
-
- // Encoding should have inserted the 'Date' and 'Content-Length' headers.
- EXPECT_EQ(2, decoded->headers.size());
- EXPECT_TRUE(decoded->headers.contains("Date"));
- EXPECT_SOME_EQ(
- stringify(response.body.size()),
- decoded->headers.get("Content-Length"));
-}
-
-
-TEST(Encoder, AcceptableEncodings)
-{
- // Create requests that do not accept gzip encoding.
- vector<Request> requests(7);
- requests[0].headers["Accept-Encoding"] = "gzip;q=0.0,*";
- requests[1].headers["Accept-Encoding"] = "compress";
- requests[2].headers["Accept-Encoding"] = "compress, gzip;q=0.0";
- requests[3].headers["Accept-Encoding"] = "*, gzip;q=0.0";
- requests[4].headers["Accept-Encoding"] = "*;q=0.0, compress";
- requests[5].headers["Accept-Encoding"] = "\n compress";
- requests[6].headers["Accept-Encoding"] = "compress,\tgzip;q=0.0";
-
- foreach (const Request& request, requests) {
- EXPECT_FALSE(request.accepts("gzip"))
- << "Gzip encoding is unacceptable for 'Accept-Encoding: "
- << request.headers.get("Accept-Encoding").get() << "'";
- }
-
- // Create requests that accept gzip encoding.
- vector<Request> gzipRequests(12);
-
- // Using q values.
- gzipRequests[0].headers["Accept-Encoding"] = "gzip;q=0.1,*";
- gzipRequests[1].headers["Accept-Encoding"] = "compress, gzip;q=0.1";
- gzipRequests[2].headers["Accept-Encoding"] = "*, gzip;q=0.5";
- gzipRequests[3].headers["Accept-Encoding"] = "*;q=0.9, compress";
- gzipRequests[4].headers["Accept-Encoding"] = "compress,\tgzip;q=0.1";
-
- // No q values.
- gzipRequests[5].headers["Accept-Encoding"] = "gzip";
- gzipRequests[6].headers["Accept-Encoding"] = "compress, gzip";
- gzipRequests[7].headers["Accept-Encoding"] = "*";
- gzipRequests[8].headers["Accept-Encoding"] = "*, compress";
- gzipRequests[9].headers["Accept-Encoding"] = "\n gzip";
- gzipRequests[10].headers["Accept-Encoding"] = "compress,\tgzip";
- gzipRequests[11].headers["Accept-Encoding"] = "gzip";
-
- foreach (const Request& gzipRequest, gzipRequests) {
- EXPECT_TRUE(gzipRequest.accepts("gzip"))
- << "Gzip encoding is acceptable for 'Accept-Encoding: "
- << gzipRequest.headers.get("Accept-Encoding").get() << "'";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/tests/http_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/tests/http_tests.cpp b/third_party/libprocess/src/tests/http_tests.cpp
deleted file mode 100644
index f677267..0000000
--- a/third_party/libprocess/src/tests/http_tests.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-#include <arpa/inet.h>
-
-#include <gmock/gmock.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <string>
-
-#include <process/future.hpp>
-#include <process/gmock.hpp>
-#include <process/gtest.hpp>
-#include <process/http.hpp>
-#include <process/io.hpp>
-
-#include <stout/gtest.hpp>
-#include <stout/nothing.hpp>
-#include <stout/os.hpp>
-
-#include "encoder.hpp"
-
-using namespace process;
-
-using testing::_;
-using testing::Assign;
-using testing::DoAll;
-using testing::Return;
-
-
-class HttpProcess : public Process<HttpProcess>
-{
-public:
- HttpProcess()
- {
- route("/body", &HttpProcess::body);
- route("/pipe", &HttpProcess::pipe);
- }
-
- MOCK_METHOD1(body, Future<http::Response>(const http::Request&));
- MOCK_METHOD1(pipe, Future<http::Response>(const http::Request&));
-};
-
-
-TEST(HTTP, Endpoints)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- HttpProcess process;
-
- spawn(process);
-
- // First hit '/body' (using explicit sockets and HTTP/1.0).
- int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
-
- ASSERT_LE(0, s);
-
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = PF_INET;
- addr.sin_port = htons(process.self().port);
- addr.sin_addr.s_addr = process.self().ip;
-
- ASSERT_EQ(0, connect(s, (sockaddr*) &addr, sizeof(addr)));
-
- std::ostringstream out;
- out << "GET /" << process.self().id << "/body"
- << " HTTP/1.0\r\n"
- << "Connection: Keep-Alive\r\n"
- << "\r\n";
-
- const std::string& data = out.str();
-
- EXPECT_CALL(process, body(_))
- .WillOnce(Return(http::OK()));
-
- ASSERT_SOME(os::write(s, data));
-
- std::string response = "HTTP/1.1 200 OK";
-
- char temp[response.size()];
- ASSERT_LT(0, ::read(s, temp, response.size()));
- ASSERT_EQ(response, std::string(temp, response.size()));
-
- ASSERT_EQ(0, close(s));
-
- // Now hit '/pipe' (by using http::get).
- int pipes[2];
- ASSERT_NE(-1, ::pipe(pipes));
-
- http::OK ok;
- ok.type = http::Response::PIPE;
- ok.pipe = pipes[0];
-
- Future<Nothing> pipe;
- EXPECT_CALL(process, pipe(_))
- .WillOnce(DoAll(FutureSatisfy(&pipe),
- Return(ok)));
-
- Future<http::Response> future = http::get(process.self(), "pipe");
-
- AWAIT_READY(pipe);
-
- ASSERT_SOME(os::write(pipes[1], "Hello World\n"));
- ASSERT_SOME(os::close(pipes[1]));
-
- AWAIT_READY(future);
- ASSERT_EQ(http::statuses[200], future.get().status);
- ASSERT_EQ("chunked", future.get().headers["Transfer-Encoding"]);
- ASSERT_EQ("Hello World\n", future.get().body);
-
- terminate(process);
- wait(process);
-}
-
-
-TEST(HTTP, Encode)
-{
- std::string unencoded = "a$&+,/:;=?@ \"<>#%{}|\\^~[]`\x19\x80\xFF";
- unencoded += std::string("\x00", 1); // Add a null byte to the end.
-
- std::string encoded = http::encode(unencoded);
-
- EXPECT_EQ("a%24%26%2B%2C%2F%3A%3B%3D%3F%40%20%22%3C%3E%23"
- "%25%7B%7D%7C%5C%5E%7E%5B%5D%60%19%80%FF%00",
- encoded);
-
- EXPECT_SOME_EQ(unencoded, http::decode(encoded));
-
- EXPECT_ERROR(http::decode("%"));
- EXPECT_ERROR(http::decode("%1"));
- EXPECT_ERROR(http::decode("%;1"));
- EXPECT_ERROR(http::decode("%1;"));
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/tests/io_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/tests/io_tests.cpp b/third_party/libprocess/src/tests/io_tests.cpp
deleted file mode 100644
index 288fa83..0000000
--- a/third_party/libprocess/src/tests/io_tests.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-#include <gmock/gmock.h>
-
-#include <string>
-
-#include <process/future.hpp>
-#include <process/gtest.hpp>
-#include <process/io.hpp>
-
-#include <stout/gtest.hpp>
-#include <stout/os.hpp>
-
-#include "encoder.hpp"
-
-using namespace process;
-
-using std::string;
-
-
-TEST(IO, Poll)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- int pipes[2];
- pipe(pipes);
-
- Future<short> future = io::poll(pipes[0], io::READ);
-
- EXPECT_FALSE(future.isReady());
-
- ASSERT_EQ(3, write(pipes[1], "hi", 3));
-
- AWAIT_EXPECT_EQ(io::READ, future);
-
- close(pipes[0]);
- close(pipes[1]);
-}
-
-
-TEST(IO, Read)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- int pipes[2];
- char data[3];
-
- // Create a blocking pipe.
- ASSERT_NE(-1, ::pipe(pipes));
-
- // Test on a blocking file descriptor.
- AWAIT_EXPECT_FAILED(io::read(pipes[0], data, 3));
-
- close(pipes[0]);
- close(pipes[1]);
-
- // Test on a closed file descriptor.
- AWAIT_EXPECT_FAILED(io::read(pipes[0], data, 3));
-
- // Create a nonblocking pipe.
- ASSERT_NE(-1, ::pipe(pipes));
- ASSERT_SOME(os::nonblock(pipes[0]));
- ASSERT_SOME(os::nonblock(pipes[1]));
-
- // Test reading nothing.
- AWAIT_EXPECT_FAILED(io::read(pipes[0], data, 0));
-
- // Test successful read.
- Future<size_t> future = io::read(pipes[0], data, 3);
- ASSERT_FALSE(future.isReady());
-
- ASSERT_EQ(2, write(pipes[1], "hi", 2));
-
- AWAIT_ASSERT_EQ(2u, future);
- EXPECT_EQ('h', data[0]);
- EXPECT_EQ('i', data[1]);
-
- // Test cancellation.
- future = io::read(pipes[0], data, 1);
- ASSERT_FALSE(future.isReady());
-
- future.discard();
-
- ASSERT_EQ(3, write(pipes[1], "omg", 3));
-
- AWAIT_ASSERT_EQ(3u, io::read(pipes[0], data, 3));
- EXPECT_EQ('o', data[0]);
- EXPECT_EQ('m', data[1]);
- EXPECT_EQ('g', data[2]);
-
- // Test read EOF.
- future = io::read(pipes[0], data, 3);
- ASSERT_FALSE(future.isReady());
-
- close(pipes[1]);
-
- AWAIT_ASSERT_EQ(0u, future);
-
- close(pipes[0]);
-}
-
-
-TEST(IO, BufferedRead)
-{
- // 128 Bytes.
- string data =
- "This data is much larger than BUFFERED_READ_SIZE, which means it will "
- "trigger multiple buffered async reads as a result.........";
- ASSERT_EQ(128u, data.size());
-
- // Keep doubling the data size until we're guaranteed to trigger at least
- // 3 buffered async reads.
- while (data.length() < 3 * io::BUFFERED_READ_SIZE) {
- data.append(data);
- }
-
- // First read from a file.
- ASSERT_SOME(os::write("file", data));
-
- Try<int> fd = os::open("file", O_RDONLY);
- ASSERT_SOME(fd);
-
- // Read from blocking fd.
- AWAIT_EXPECT_FAILED(io::read(fd.get()));
-
- // Read from non-blocking fd.
- ASSERT_TRUE(os::nonblock(fd.get()).isSome());
- AWAIT_EXPECT_EQ(data, io::read(fd.get()));
-
- os::close(fd.get());
-
- // Now read from pipes.
- int pipes[2];
-
- // Create a blocking pipe.
- ASSERT_NE(-1, ::pipe(pipes));
-
- // Test on a blocking pipe.
- AWAIT_EXPECT_FAILED(io::read(pipes[0]));
-
- close(pipes[0]);
- close(pipes[1]);
-
- // Test on a closed pipe.
- AWAIT_EXPECT_FAILED(io::read(pipes[0]));
-
- // Create a nonblocking pipe for reading.
- ASSERT_NE(-1, ::pipe(pipes));
- ASSERT_SOME(os::nonblock(pipes[0]));
-
- // Test a successful read from the pipe.
- Future<string> future = io::read(pipes[0]);
-
- // At first, the future will not be ready until we write to and
- // close the pipe.
- ASSERT_FALSE(future.isReady());
-
- ASSERT_SOME(os::write(pipes[1], data));
- close(pipes[1]);
-
- AWAIT_EXPECT_EQ(data, future);
-
- close(pipes[0]);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/tests/main.cpp b/third_party/libprocess/src/tests/main.cpp
deleted file mode 100644
index 6c672b4..0000000
--- a/third_party/libprocess/src/tests/main.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <gmock/gmock.h>
-
-#include <process/gmock.hpp>
-#include <process/gtest.hpp>
-#include <process/process.hpp>
-
-int main(int argc, char** argv)
-{
- // Initialize Google Mock/Test.
- testing::InitGoogleMock(&argc, argv);
-
- // Initialize libprocess.
- process::initialize();
-
- // Add the libprocess test event listeners.
- ::testing::TestEventListeners& listeners =
- ::testing::UnitTest::GetInstance()->listeners();
-
- listeners.Append(process::ClockTestEventListener::instance());
- listeners.Append(process::FilterTestEventListener::instance());
-
- return RUN_ALL_TESTS();
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/tests/process_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/tests/process_tests.cpp b/third_party/libprocess/src/tests/process_tests.cpp
deleted file mode 100644
index dc5c671..0000000
--- a/third_party/libprocess/src/tests/process_tests.cpp
+++ /dev/null
@@ -1,1143 +0,0 @@
-#include <arpa/inet.h>
-
-#include <gmock/gmock.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <string>
-#include <sstream>
-
-#include <process/async.hpp>
-#include <process/collect.hpp>
-#include <process/clock.hpp>
-#include <process/defer.hpp>
-#include <process/delay.hpp>
-#include <process/dispatch.hpp>
-#include <process/executor.hpp>
-#include <process/filter.hpp>
-#include <process/future.hpp>
-#include <process/gc.hpp>
-#include <process/gmock.hpp>
-#include <process/gtest.hpp>
-#include <process/process.hpp>
-#include <process/run.hpp>
-#include <process/thread.hpp>
-#include <process/time.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/nothing.hpp>
-#include <stout/os.hpp>
-#include <stout/stringify.hpp>
-
-#include "encoder.hpp"
-
-using namespace process;
-
-using testing::_;
-using testing::Assign;
-using testing::DoAll;
-using testing::Return;
-using testing::ReturnArg;
-
-// TODO(bmahler): Move tests into their own files as appropriate.
-
-TEST(Process, thread)
-{
- ThreadLocal<ProcessBase>* _process_ = new ThreadLocal<ProcessBase>();
-
- ProcessBase* process = new ProcessBase();
-
- ASSERT_TRUE(*(_process_) == NULL);
-
- (*_process_) = process;
-
- ASSERT_TRUE(*(_process_) == process);
- ASSERT_FALSE(*(_process_) == NULL);
-
- (*_process_) = NULL;
-
- ASSERT_TRUE(*(_process_) == NULL);
-
- delete process;
- delete _process_;
-}
-
-
-TEST(Process, event)
-{
- Event* event = new TerminateEvent(UPID());
- EXPECT_FALSE(event->is<MessageEvent>());
- EXPECT_FALSE(event->is<ExitedEvent>());
- EXPECT_TRUE(event->is<TerminateEvent>());
- delete event;
-}
-
-
-TEST(Process, future)
-{
- Promise<bool> promise;
- promise.set(true);
- ASSERT_TRUE(promise.future().isReady());
- EXPECT_TRUE(promise.future().get());
-}
-
-
-TEST(Process, associate)
-{
- Promise<bool> promise1;
- Future<bool> future1(true);
- promise1.associate(future1);
- ASSERT_TRUE(promise1.future().isReady());
- EXPECT_TRUE(promise1.future().get());
-
- Promise<bool> promise2;
- Future<bool> future2;
- promise2.associate(future2);
- future2.discard();
- ASSERT_TRUE(promise2.future().isDiscarded());
-
- Promise<bool> promise3;
- Promise<bool> promise4;
- promise3.associate(promise4.future());
- promise4.fail("associate");
- ASSERT_TRUE(promise3.future().isFailed());
- EXPECT_EQ("associate", promise3.future().failure());
-}
-
-
-void onAny(const Future<bool>& future, bool* b)
-{
- ASSERT_TRUE(future.isReady());
- *b = future.get();
-}
-
-
-TEST(Process, onAny)
-{
- bool b = false;
- Future<bool>(true)
- .onAny(std::tr1::bind(&onAny, std::tr1::placeholders::_1, &b));
- EXPECT_TRUE(b);
-}
-
-
-Future<std::string> itoa1(int* const& i)
-{
- std::ostringstream out;
- out << *i;
- return out.str();
-}
-
-
-std::string itoa2(int* const& i)
-{
- std::ostringstream out;
- out << *i;
- return out.str();
-}
-
-
-TEST(Process, then)
-{
- Promise<int*> promise;
-
- int i = 42;
-
- promise.set(&i);
-
- Future<std::string> future = promise.future()
- .then(std::tr1::bind(&itoa1, std::tr1::placeholders::_1));
-
- ASSERT_TRUE(future.isReady());
- EXPECT_EQ("42", future.get());
-
- future = promise.future()
- .then(std::tr1::bind(&itoa2, std::tr1::placeholders::_1));
-
- ASSERT_TRUE(future.isReady());
- EXPECT_EQ("42", future.get());
-}
-
-
-Future<bool> readyFuture()
-{
- return true;
-}
-
-
-Future<bool> failedFuture()
-{
- return Future<bool>::failed("The value is not positive (or zero)");
-}
-
-
-Future<bool> pendingFuture(Future<bool>* future)
-{
- return *future; // Keep it pending.
-}
-
-
-Future<std::string> second(const bool& b)
-{
- return b ? std::string("true") : std::string("false");
-}
-
-
-Future<std::string> third(const std::string& s)
-{
- return s;
-}
-
-
-TEST(Process, chain)
-{
- Promise<int*> promise;
-
- Future<std::string> s = readyFuture()
- .then(std::tr1::bind(&second, std::tr1::placeholders::_1))
- .then(std::tr1::bind(&third, std::tr1::placeholders::_1));
-
- s.await();
-
- ASSERT_TRUE(s.isReady());
- EXPECT_EQ("true", s.get());
-
- s = failedFuture()
- .then(std::tr1::bind(&second, std::tr1::placeholders::_1))
- .then(std::tr1::bind(&third, std::tr1::placeholders::_1));
-
- s.await();
-
- ASSERT_TRUE(s.isFailed());
-
- Future<bool> future;
-
- s = pendingFuture(&future)
- .then(std::tr1::bind(&second, std::tr1::placeholders::_1))
- .then(std::tr1::bind(&third, std::tr1::placeholders::_1));
-
- ASSERT_TRUE(s.isPending());
- ASSERT_TRUE(future.isPending());
-
- s.discard();
-
- future.await();
-
- ASSERT_TRUE(future.isDiscarded());
-}
-
-
-class SpawnProcess : public Process<SpawnProcess>
-{
-public:
- MOCK_METHOD0(initialize, void(void));
- MOCK_METHOD0(finalize, void(void));
-};
-
-
-TEST(Process, spawn)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- SpawnProcess process;
-
- EXPECT_CALL(process, initialize())
- .Times(1);
-
- EXPECT_CALL(process, finalize())
- .Times(1);
-
- PID<SpawnProcess> pid = spawn(process);
-
- ASSERT_FALSE(!pid);
-
- ASSERT_FALSE(wait(pid, Seconds(0)));
-
- terminate(pid);
- wait(pid);
-}
-
-
-class DispatchProcess : public Process<DispatchProcess>
-{
-public:
- MOCK_METHOD0(func0, void(void));
- MOCK_METHOD1(func1, bool(bool));
- MOCK_METHOD1(func2, Future<bool>(bool));
- MOCK_METHOD1(func3, int(int));
- MOCK_METHOD2(func4, Future<bool>(bool, int));
-};
-
-
-TEST(Process, dispatch)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- DispatchProcess process;
-
- EXPECT_CALL(process, func0())
- .Times(1);
-
- EXPECT_CALL(process, func1(_))
- .WillOnce(ReturnArg<0>());
-
- EXPECT_CALL(process, func2(_))
- .WillOnce(ReturnArg<0>());
-
- PID<DispatchProcess> pid = spawn(&process);
-
- ASSERT_FALSE(!pid);
-
- dispatch(pid, &DispatchProcess::func0);
-
- Future<bool> future;
-
- future = dispatch(pid, &DispatchProcess::func1, true);
-
- EXPECT_TRUE(future.get());
-
- future = dispatch(pid, &DispatchProcess::func2, true);
-
- EXPECT_TRUE(future.get());
-
- terminate(pid);
- wait(pid);
-}
-
-
-TEST(Process, defer1)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- DispatchProcess process;
-
- EXPECT_CALL(process, func0())
- .Times(1);
-
- EXPECT_CALL(process, func1(_))
- .WillOnce(ReturnArg<0>());
-
- EXPECT_CALL(process, func2(_))
- .WillOnce(ReturnArg<0>());
-
- EXPECT_CALL(process, func4(_, _))
- .WillRepeatedly(ReturnArg<0>());
-
- PID<DispatchProcess> pid = spawn(&process);
-
- ASSERT_FALSE(!pid);
-
- {
- Deferred<void(void)> func0 =
- defer(pid, &DispatchProcess::func0);
- func0();
- }
-
- Future<bool> future;
-
- {
- Deferred<Future<bool>(void)> func1 =
- defer(pid, &DispatchProcess::func1, true);
- future = func1();
- EXPECT_TRUE(future.get());
- }
-
- {
- Deferred<Future<bool>(void)> func2 =
- defer(pid, &DispatchProcess::func2, true);
- future = func2();
- EXPECT_TRUE(future.get());
- }
-
- {
- Deferred<Future<bool>(void)> func4 =
- defer(pid, &DispatchProcess::func4, true, 42);
- future = func4();
- EXPECT_TRUE(future.get());
- }
-
- {
- Deferred<Future<bool>(bool)> func4 =
- defer(pid, &DispatchProcess::func4, std::tr1::placeholders::_1, 42);
- future = func4(false);
- EXPECT_FALSE(future.get());
- }
-
- {
- Deferred<Future<bool>(int)> func4 =
- defer(pid, &DispatchProcess::func4, true, std::tr1::placeholders::_1);
- future = func4(42);
- EXPECT_TRUE(future.get());
- }
-
- // Only take const &!
-
- terminate(pid);
- wait(pid);
-}
-
-
-class DeferProcess : public Process<DeferProcess>
-{
-public:
- Future<std::string> func1(const Future<int>& f)
- {
- return f.then(defer(self(), &Self::_func1, std::tr1::placeholders::_1));
- }
-
- Future<std::string> func2(const Future<int>& f)
- {
- return f.then(defer(self(), &Self::_func2));
- }
-
-private:
- Future<std::string> _func1(int i)
- {
- return stringify(i);
- }
-
- Future<std::string> _func2()
- {
- return std::string("42");
- }
-};
-
-
-TEST(Process, defer2)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- DeferProcess process;
-
- PID<DeferProcess> pid = spawn(process);
-
- Future<std::string> f = dispatch(pid, &DeferProcess::func1, 41);
-
- f.await();
-
- ASSERT_TRUE(f.isReady());
- EXPECT_EQ("41", f.get());
-
- f = dispatch(pid, &DeferProcess::func2, 41);
-
- f.await();
-
- ASSERT_TRUE(f.isReady());
- EXPECT_EQ("42", f.get());
-
- terminate(pid);
- wait(pid);
-}
-
-
-template <typename T>
-void set(T* t1, const T& t2)
-{
- *t1 = t2;
-}
-
-
-TEST(Process, defer3)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- volatile bool bool1 = false;
- volatile bool bool2 = false;
-
- Deferred<void(bool)> set1 =
- defer(std::tr1::function<void(bool)>(
- std::tr1::bind(&set<volatile bool>,
- &bool1,
- std::tr1::placeholders::_1)));
-
- set1(true);
-
- Deferred<void(bool)> set2 =
- defer(std::tr1::function<void(bool)>(
- std::tr1::bind(&set<volatile bool>,
- &bool2,
- std::tr1::placeholders::_1)));
-
- set2(true);
-
- while (!bool1);
- while (!bool2);
-}
-
-
-class HandlersProcess : public Process<HandlersProcess>
-{
-public:
- HandlersProcess()
- {
- install("func", &HandlersProcess::func);
- }
-
- MOCK_METHOD2(func, void(const UPID&, const std::string&));
-};
-
-
-TEST(Process, handlers)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- HandlersProcess process;
-
- EXPECT_CALL(process, func(_, _))
- .Times(1);
-
- PID<HandlersProcess> pid = spawn(&process);
-
- ASSERT_FALSE(!pid);
-
- post(pid, "func");
-
- terminate(pid, false);
- wait(pid);
-}
-
-
-// Tests EXPECT_MESSAGE and EXPECT_DISPATCH and in particular that an
-// event can get dropped before being processed.
-TEST(Process, expect)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- HandlersProcess process;
-
- EXPECT_CALL(process, func(_, _))
- .Times(0);
-
- PID<HandlersProcess> pid = spawn(&process);
-
- ASSERT_FALSE(!pid);
-
- Future<Message> message = DROP_MESSAGE("func", _, _);
-
- post(pid, "func");
-
- AWAIT_EXPECT_READY(message);
-
- Future<Nothing> func = DROP_DISPATCH(pid, &HandlersProcess::func);
-
- dispatch(pid, &HandlersProcess::func, pid, "");
-
- AWAIT_EXPECT_READY(func);
-
- terminate(pid, false);
- wait(pid);
-}
-
-
-// Tests the FutureArg<N> action.
-TEST(Process, action)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- HandlersProcess process;
-
- PID<HandlersProcess> pid = spawn(&process);
-
- ASSERT_FALSE(!pid);
-
- Future<std::string> future1;
- Future<Nothing> future2;
- EXPECT_CALL(process, func(_, _))
- .WillOnce(FutureArg<1>(&future1))
- .WillOnce(FutureSatisfy(&future2));
-
- dispatch(pid, &HandlersProcess::func, pid, "hello world");
-
- AWAIT_EXPECT_EQ("hello world", future1);
-
- EXPECT_TRUE(future2.isPending());
-
- dispatch(pid, &HandlersProcess::func, pid, "hello world");
-
- AWAIT_EXPECT_READY(future2);
-
- terminate(pid, false);
- wait(pid);
-}
-
-
-class BaseProcess : public Process<BaseProcess>
-{
-public:
- virtual void func() = 0;
- MOCK_METHOD0(foo, void());
-};
-
-
-class DerivedProcess : public BaseProcess
-{
-public:
- DerivedProcess() {}
- MOCK_METHOD0(func, void());
-};
-
-
-TEST(Process, inheritance)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- DerivedProcess process;
-
- EXPECT_CALL(process, func())
- .Times(2);
-
- EXPECT_CALL(process, foo())
- .Times(1);
-
- PID<DerivedProcess> pid1 = spawn(&process);
-
- ASSERT_FALSE(!pid1);
-
- dispatch(pid1, &DerivedProcess::func);
-
- PID<BaseProcess> pid2(process);
- PID<BaseProcess> pid3 = pid1;
-
- ASSERT_EQ(pid2, pid3);
-
- dispatch(pid3, &BaseProcess::func);
- dispatch(pid3, &BaseProcess::foo);
-
- terminate(pid1, false);
- wait(pid1);
-}
-
-
-TEST(Process, thunk)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- struct Thunk
- {
- static int run(int i)
- {
- return i;
- }
-
- static int run(int i, int j)
- {
- return run(i + j);
- }
- };
-
- int result = run(&Thunk::run, 21, 21).get();
-
- EXPECT_EQ(42, result);
-}
-
-
-class DelegatorProcess : public Process<DelegatorProcess>
-{
-public:
- DelegatorProcess(const UPID& delegatee)
- {
- delegate("func", delegatee);
- }
-};
-
-
-class DelegateeProcess : public Process<DelegateeProcess>
-{
-public:
- DelegateeProcess()
- {
- install("func", &DelegateeProcess::func);
- }
-
- MOCK_METHOD2(func, void(const UPID&, const std::string&));
-};
-
-
-TEST(Process, delegate)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- DelegateeProcess delegatee;
- DelegatorProcess delegator(delegatee.self());
-
- EXPECT_CALL(delegatee, func(_, _))
- .Times(1);
-
- spawn(&delegator);
- spawn(&delegatee);
-
- post(delegator.self(), "func");
-
- terminate(delegator, false);
- wait(delegator);
-
- terminate(delegatee, false);
- wait(delegatee);
-}
-
-
-class TimeoutProcess : public Process<TimeoutProcess>
-{
-public:
- MOCK_METHOD0(timeout, void());
-};
-
-
-TEST(Process, delay)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- Clock::pause();
-
- volatile bool timeoutCalled = false;
-
- TimeoutProcess process;
-
- EXPECT_CALL(process, timeout())
- .WillOnce(Assign(&timeoutCalled, true));
-
- spawn(process);
-
- delay(Seconds(5), process.self(), &TimeoutProcess::timeout);
-
- Clock::advance(Seconds(5));
-
- while (!timeoutCalled);
-
- terminate(process);
- wait(process);
-
- Clock::resume();
-}
-
-
-class OrderProcess : public Process<OrderProcess>
-{
-public:
- void order(const PID<TimeoutProcess>& pid)
- {
- // TODO(benh): Add a test which uses 'send' instead of dispatch.
- dispatch(pid, &TimeoutProcess::timeout);
- }
-};
-
-
-TEST(Process, order)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- Clock::pause();
-
- TimeoutProcess process1;
-
- volatile bool timeoutCalled = false;
-
- EXPECT_CALL(process1, timeout())
- .WillOnce(Assign(&timeoutCalled, true));
-
- spawn(process1);
-
- Time now = Clock::now(&process1);
-
- Seconds seconds(1);
-
- Clock::advance(Seconds(1));
-
- EXPECT_EQ(now, Clock::now(&process1));
-
- OrderProcess process2;
- spawn(process2);
-
- dispatch(process2, &OrderProcess::order, process1.self());
-
- while (!timeoutCalled);
-
- EXPECT_EQ(now + seconds, Clock::now(&process1));
-
- terminate(process1);
- wait(process1);
-
- terminate(process2);
- wait(process2);
-
- Clock::resume();
-}
-
-
-class DonateProcess : public Process<DonateProcess>
-{
-public:
- void donate()
- {
- DonateProcess process;
- spawn(process);
- terminate(process);
- wait(process);
- }
-};
-
-
-TEST(Process, donate)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- DonateProcess process;
- spawn(process);
-
- dispatch(process, &DonateProcess::donate);
-
- terminate(process, false);
- wait(process);
-}
-
-
-class ExitedProcess : public Process<ExitedProcess>
-{
-public:
- ExitedProcess(const UPID& pid) { link(pid); }
-
- MOCK_METHOD1(exited, void(const UPID&));
-};
-
-
-TEST(Process, exited)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- UPID pid = spawn(new ProcessBase(), true);
-
- ExitedProcess process(pid);
-
- volatile bool exitedCalled = false;
-
- EXPECT_CALL(process, exited(pid))
- .WillOnce(Assign(&exitedCalled, true));
-
- spawn(process);
-
- terminate(pid);
-
- while (!exitedCalled);
-
- terminate(process);
- wait(process);
-}
-
-
-TEST(Process, select)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- Promise<int> promise1;
- Promise<int> promise2;
- Promise<int> promise3;
- Promise<int> promise4;
-
- std::set<Future<int> > futures;
- futures.insert(promise1.future());
- futures.insert(promise2.future());
- futures.insert(promise3.future());
- futures.insert(promise4.future());
-
- promise1.set(42);
-
- Future<Future<int> > future = select(futures);
-
- EXPECT_TRUE(future.await());
- EXPECT_TRUE(future.isReady());
- EXPECT_TRUE(future.get().isReady());
- EXPECT_EQ(42, future.get().get());
-}
-
-
-TEST(Process, collect)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- Promise<int> promise1;
- Promise<int> promise2;
- Promise<int> promise3;
- Promise<int> promise4;
-
- std::list<Future<int> > futures;
- futures.push_back(promise1.future());
- futures.push_back(promise2.future());
- futures.push_back(promise3.future());
- futures.push_back(promise4.future());
-
- promise1.set(1);
- promise2.set(2);
- promise3.set(3);
- promise4.set(4);
-
- Future<std::list<int> > future = collect(futures);
-
- EXPECT_TRUE(future.await());
- EXPECT_TRUE(future.isReady());
-
- std::list<int> values;
- values.push_back(1);
- values.push_back(2);
- values.push_back(3);
- values.push_back(4);
-
- EXPECT_EQ(values, future.get());
-}
-
-
-class SettleProcess : public Process<SettleProcess>
-{
-public:
- SettleProcess() : calledDispatch(false) {}
-
- virtual void initialize()
- {
- os::sleep(Milliseconds(10));
- delay(Seconds(0), self(), &SettleProcess::afterDelay);
- }
-
- void afterDelay()
- {
- dispatch(self(), &SettleProcess::afterDispatch);
- os::sleep(Milliseconds(10));
- TimeoutProcess timeoutProcess;
- spawn(timeoutProcess);
- terminate(timeoutProcess);
- wait(timeoutProcess);
- }
-
- void afterDispatch()
- {
- os::sleep(Milliseconds(10));
- calledDispatch = true;
- }
-
- volatile bool calledDispatch;
-};
-
-
-TEST(Process, settle)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- Clock::pause();
- SettleProcess process;
- spawn(process);
- Clock::settle();
- ASSERT_TRUE(process.calledDispatch);
- terminate(process);
- wait(process);
- Clock::resume();
-}
-
-
-TEST(Process, pid)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- TimeoutProcess process;
-
- PID<TimeoutProcess> pid = process;
-}
-
-
-class Listener1 : public Process<Listener1>
-{
-public:
- virtual void event1() = 0;
-};
-
-
-class Listener2 : public Process<Listener2>
-{
-public:
- virtual void event2() = 0;
-};
-
-
-class MultipleListenerProcess
- : public Process<MultipleListenerProcess>,
- public Listener1,
- public Listener2
-{
-public:
- MOCK_METHOD0(event1, void());
- MOCK_METHOD0(event2, void());
-};
-
-
-TEST(Process, listener)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- MultipleListenerProcess process;
-
- EXPECT_CALL(process, event1())
- .Times(1);
-
- EXPECT_CALL(process, event2())
- .Times(1);
-
- spawn(process);
-
- dispatch(PID<Listener1>(process), &Listener1::event1);
- dispatch(PID<Listener2>(process), &Listener2::event2);
-
- terminate(process, false);
- wait(process);
-}
-
-
-class EventReceiver
-{
-public:
- MOCK_METHOD1(event1, void(int));
- MOCK_METHOD1(event2, void(const std::string&));
-};
-
-
-TEST(Process, executor)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- volatile bool event1Called = false;
- volatile bool event2Called = false;
-
- EventReceiver receiver;
-
- EXPECT_CALL(receiver, event1(42))
- .WillOnce(Assign(&event1Called, true));
-
- EXPECT_CALL(receiver, event2("event2"))
- .WillOnce(Assign(&event2Called, true));
-
- Executor executor;
-
- Deferred<void(int)> event1 =
- executor.defer(std::tr1::bind(&EventReceiver::event1,
- &receiver,
- std::tr1::placeholders::_1));
-
- event1(42);
-
- Deferred<void(const std::string&)> event2 =
- executor.defer(std::tr1::bind(&EventReceiver::event2,
- &receiver,
- std::tr1::placeholders::_1));
-
- event2("event2");
-
- while (!event1Called);
- while (!event2Called);
-}
-
-
-class RemoteProcess : public Process<RemoteProcess>
-{
-public:
- RemoteProcess()
- {
- install("handler", &RemoteProcess::handler);
- }
-
- MOCK_METHOD2(handler, void(const UPID&, const std::string&));
-};
-
-
-TEST(Process, remote)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- RemoteProcess process;
-
- volatile bool handlerCalled = false;
-
- EXPECT_CALL(process, handler(_, _))
- .WillOnce(Assign(&handlerCalled, true));
-
- spawn(process);
-
- int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
-
- ASSERT_LE(0, s);
-
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = PF_INET;
- addr.sin_port = htons(process.self().port);
- addr.sin_addr.s_addr = process.self().ip;
-
- ASSERT_EQ(0, connect(s, (sockaddr*) &addr, sizeof(addr)));
-
- Message message;
- message.name = "handler";
- message.from = UPID();
- message.to = process.self();
-
- const std::string& data = MessageEncoder::encode(&message);
-
- ASSERT_EQ(data.size(), write(s, data.data(), data.size()));
-
- ASSERT_EQ(0, close(s));
-
- while (!handlerCalled);
-
- terminate(process);
- wait(process);
-}
-
-
-int foo()
-{
- return 1;
-}
-
-int foo1(int a)
-{
- return a;
-}
-
-
-int foo2(int a, int b)
-{
- return a + b;
-}
-
-
-int foo3(int a, int b, int c)
-{
- return a + b + c;
-}
-
-
-int foo4(int a, int b, int c, int d)
-{
- return a + b + c + d;
-}
-
-
-void bar(int a)
-{
- return;
-}
-
-
-TEST(Process, async)
-{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- // Non-void functions with different no.of args.
- EXPECT_EQ(1, async(&foo).get());
- EXPECT_EQ(10, async(&foo1, 10).get());
- EXPECT_EQ(30, async(&foo2, 10, 20).get());
- EXPECT_EQ(60, async(&foo3, 10, 20, 30).get());
- EXPECT_EQ(100, async(&foo4, 10, 20, 30, 40).get());
-
- // Non-void function with a complex arg.
- int i = 42;
- EXPECT_EQ("42", async(&itoa2, &i).get());
-
- // Non-void function that returns a future.
- EXPECT_EQ("42", async(&itoa1, &i).get().get());
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/tests/statistics_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/tests/statistics_tests.cpp b/third_party/libprocess/src/tests/statistics_tests.cpp
deleted file mode 100644
index 8695f45..0000000
--- a/third_party/libprocess/src/tests/statistics_tests.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-#include <gmock/gmock.h>
-
-#include <map>
-
-#include <process/clock.hpp>
-#include <process/future.hpp>
-#include <process/gtest.hpp>
-#include <process/statistics.hpp>
-#include <process/time.hpp>
-
-#include <stout/duration.hpp>
-
-using namespace process;
-
-using std::map;
-
-
-TEST(Statistics, set)
-{
- Statistics statistics(Days(1));
-
- // Set one using Clock::now() implicitly.
- statistics.set("test", "statistic", 3.0);
-
- // Set one using Clock::now() explicitly.
- Time now = Clock::now();
- statistics.set("test", "statistic", 4.0, now);
-
- Future<map<Time, double> > values =
- statistics.timeseries("test", "statistic");
-
- AWAIT_ASSERT_READY(values);
-
- EXPECT_EQ(2, values.get().size());
-
- EXPECT_GE(Clock::now(), values.get().begin()->first);
- EXPECT_DOUBLE_EQ(3.0, values.get().begin()->second);
-
- EXPECT_EQ(1, values.get().count(now));
- EXPECT_DOUBLE_EQ(4.0, values.get()[now]);
-}
-
-
-TEST(Statistics, truncate)
-{
- Clock::pause();
-
- Statistics statistics(Days(1));
-
- statistics.set("test", "statistic", 3.0);
-
- Future<map<Time, double> > values =
- statistics.timeseries("test", "statistic");
-
- AWAIT_ASSERT_READY(values);
-
- EXPECT_EQ(1, values.get().size());
- EXPECT_GE(Clock::now(), values.get().begin()->first);
- EXPECT_DOUBLE_EQ(3.0, values.get().begin()->second);
-
- Clock::advance(Days(1) + Seconds(1));
- Clock::settle();
-
- statistics.increment("test", "statistic");
-
- values = statistics.timeseries("test", "statistic");
-
- AWAIT_ASSERT_READY(values);
-
- EXPECT_EQ(1, values.get().size());
- EXPECT_GE(Clock::now(), values.get().begin()->first);
- EXPECT_DOUBLE_EQ(4.0, values.get().begin()->second);
-
- Clock::resume();
-}
-
-
-TEST(Statistics, meter) {
- Statistics statistics(Days(1));
-
- // Set up a meter, and ensure it captures the expected time rate.
- Future<Try<Nothing> > meter =
- statistics.meter("test", "statistic", new meters::TimeRate("metered"));
-
- AWAIT_ASSERT_READY(meter);
-
- ASSERT_TRUE(meter.get().isSome());
-
- Time now = Clock::now();
- statistics.set("test", "statistic", 1.0, now);
- statistics.set("test", "statistic", 2.0, Time(now + Seconds(1)));
- statistics.set("test", "statistic", 4.0, Time(now + Seconds(2)));
-
- // Check the raw statistic values.
- Future<map<Time, double> > values =
- statistics.timeseries("test", "statistic");
-
- AWAIT_ASSERT_READY(values);
-
- EXPECT_EQ(3, values.get().size());
- EXPECT_EQ(1, values.get().count(now));
- EXPECT_EQ(1, values.get().count(Time(now + Seconds(1))));
- EXPECT_EQ(1, values.get().count(Time(now + Seconds(2))));
-
- EXPECT_EQ(1.0, values.get()[now]);
- EXPECT_EQ(2.0, values.get()[Time(now + Seconds(1))]);
- EXPECT_EQ(4.0, values.get()[Time(now + Seconds(2))]);
-
- // Now check the metered values.
- values = statistics.timeseries("test", "metered");
-
- AWAIT_ASSERT_READY(values);
-
- EXPECT_EQ(2, values.get().size());
- EXPECT_EQ(1, values.get().count(Time(now + Seconds(1))));
- EXPECT_EQ(1, values.get().count(Time(now + Seconds(2))));
-
- EXPECT_EQ(0., values.get()[now]);
- EXPECT_EQ(1.0, values.get()[Time(now + Seconds(1))]); // 100%.
- EXPECT_EQ(2.0, values.get()[Time(now + Seconds(2))]); // 200%.
-}
-
-
-TEST(Statistics, archive)
-{
- Clock::pause();
-
- Statistics statistics(Seconds(10));
-
- // Create a meter and a statistic for archival.
- // Set up a meter, and ensure it captures the expected time rate.
- Future<Try<Nothing> > meter =
- statistics.meter("test", "statistic", new meters::TimeRate("metered"));
-
- AWAIT_ASSERT_READY(meter);
-
- ASSERT_TRUE(meter.get().isSome());
-
- Time now = Clock::now();
- statistics.set("test", "statistic", 1.0, now);
- statistics.set("test", "statistic", 2.0, Time(now + Seconds(1)));
-
- // Archive and ensure the following:
- // 1. The statistic will no longer be part of the snapshot.
- // 2. Any meters associated with this statistic will be removed.
- // 3. However, the time series will be retained until the window expiration.
- statistics.archive("test", "statistic");
-
- // TODO(bmahler): Wait for JSON parsing to verify number 1.
-
- // Ensure the raw time series is present.
- Future<map<Time, double> > values =
- statistics.timeseries("test", "statistic");
- AWAIT_ASSERT_READY(values);
- EXPECT_FALSE(values.get().empty());
-
- // Ensure the metered timeseries is present.
- values = statistics.timeseries("test", "metered");
- AWAIT_ASSERT_READY(values);
- EXPECT_FALSE(values.get().empty());
-
- // Expire the window and ensure the statistics were removed.
- Clock::advance(STATISTICS_TRUNCATION_INTERVAL);
- Clock::settle();
-
- // Ensure the raw statistics are gone.
- values = statistics.timeseries("test", "statistic");
- AWAIT_ASSERT_READY(values);
- EXPECT_TRUE(values.get().empty());
-
- // Ensure the metered statistics are gone.
- values = statistics.timeseries("test", "metered");
- AWAIT_ASSERT_READY(values);
- EXPECT_TRUE(values.get().empty());
-
- // Reactivate the statistic, and make sure the meter is still missing.
- statistics.set("test", "statistic", 1.0, now);
-
- values = statistics.timeseries("test", "metered");
- AWAIT_ASSERT_READY(values);
- EXPECT_TRUE(values.get().empty());
-
- Clock::resume();
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/tests/time_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/tests/time_tests.cpp b/third_party/libprocess/src/tests/time_tests.cpp
deleted file mode 100644
index a25827e..0000000
--- a/third_party/libprocess/src/tests/time_tests.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <gmock/gmock.h>
-
-#include <process/clock.hpp>
-#include <process/time.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/gtest.hpp>
-#include <stout/os.hpp>
-
-using namespace process;
-
-
-TEST(TimeTest, Arithmetic)
-{
- Time t = Time::EPOCH + Weeks(1000);
- t -= Weeks(1);
- EXPECT_EQ(Time::EPOCH + Weeks(999), t);
-
- t += Weeks(2);
- EXPECT_EQ(Time::EPOCH + Weeks(1001), t);
-
- EXPECT_EQ(t, Time::EPOCH + Weeks(1000) + Weeks(1));
- EXPECT_EQ(t, Time::EPOCH + Weeks(1002) - Weeks(1));
-
- EXPECT_EQ(Weeks(1), (Time::EPOCH + Weeks(1000)) - (Time::EPOCH + Weeks(999)));
-}
-
-
-TEST(TimeTest, Now)
-{
- Time t1 = Clock::now();
- os::sleep(Microseconds(10));
- ASSERT_LT(Microseconds(10), Clock::now() - t1);
-}
-
-
-TEST(TimeTest, Output)
-{
- EXPECT_EQ("1989-03-02 00:00:00+00:00", stringify(Time::EPOCH + Weeks(1000)));
- EXPECT_EQ("1989-03-02 00:00:00.000000001+00:00",
- stringify(Time::EPOCH + Weeks(1000) + Nanoseconds(1)));
- EXPECT_EQ("1989-03-02 00:00:00.000001000+00:00",
- stringify(Time::EPOCH + Weeks(1000) + Microseconds(1)));
-}
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/timer.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/timer.cpp b/third_party/libprocess/src/timer.cpp
deleted file mode 100644
index 63c5ac1..0000000
--- a/third_party/libprocess/src/timer.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <process/timer.hpp>
-
-#include "timeout.hpp"
-
-namespace process {
-
-class TimerProcess : public Process<TimerProcess>
-{
-public:
- TimerProcess(double _secs,
- const UPID& _pid,
- std::tr1::function<void(ProcessBase*)>* _dispatcher)
- : secs(_secs), pid(_pid), dispatcher(_dispatcher) {}
-
-protected:
- virtual void operator () ()
- {
- if (receive(secs) == TIMEOUT) {
- internal::dispatch(pid, dispatcher);
- } else {
- delete dispatcher;
- }
- }
-
-private:
- const double secs;
- const UPID pid;
- std::tr1::function<void(ProcessBase*)>* dispatcher;
-};
-
-
-static void dispatch()
-
-
-Timer::Timer(double secs,
- const UPID& pid,
- std::tr1::function<void(ProcessBase*)>* dispatcher)
-{
- timer = spawn(new TimerProcess(secs, pid, dispatcher), true);
-}
-
-
-Timer::~Timer()
-{
- // NOTE: Do not terminate the timer! Some users will simply ignore
- // saving the timer because they never want to cancel, thus
- // we can not terminate it here!
-}
-
-
-void Timer::cancel()
-{
- timeouts::cancel(timeout);
-}
-
-} // namespace process {
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/src/timer.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/timer.hpp b/third_party/libprocess/src/timer.hpp
deleted file mode 100644
index 443b5a0..0000000
--- a/third_party/libprocess/src/timer.hpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#ifndef TIMER_HPP
-#define TIMER_HPP
-
-#include <ctime>
-#include <iostream>
-#include <iomanip>
-
-class timer
-{
- friend std::ostream& operator<<(std::ostream& os, timer& t);
-
-private:
- bool running;
- clock_t start_clock;
- time_t start_time;
- double acc_time;
-
- double elapsed_time();
-
-public:
- // 'running' is initially false. A timer needs to be explicitly started
- // using 'start' or 'restart'
- timer() : running(false), start_clock(0), start_time(0), acc_time(0) { }
-
- void start(const char* msg = 0);
- void restart(const char* msg = 0);
- void stop(const char* msg = 0);
- void check(const char* msg = 0);
-
-}; // class timer
-
-//===========================================================================
-// Return the total time that the timer has been in the "running"
-// state since it was first "started" or last "restarted". For
-// "short" time periods (less than an hour), the actual cpu time
-// used is reported instead of the elapsed time.
-
-inline double timer::elapsed_time()
-{
- time_t acc_sec = time(0) - start_time;
- if (acc_sec < 3600)
- return (clock() - start_clock) / (1.0 * CLOCKS_PER_SEC);
- else
- return (1.0 * acc_sec);
-
-} // timer::elapsed_time
-
-//===========================================================================
-// Start a timer. If it is already running, let it continue running.
-// Print an optional message.
-
-inline void timer::start(const char* msg)
-{
- // Print an optional message, something like "Starting timer t";
- if (msg) std::cout << msg << std::endl;
-
- // Return immediately if the timer is already running
- if (running) return;
-
- // Set timer status to running and set the start time
- running = true;
- start_clock = clock();
- start_time = time(0);
-
-} // timer::start
-
-//===========================================================================
-// Turn the timer off and start it again from 0. Print an optional message.
-
-inline void timer::restart(const char* msg)
-{
- // Print an optional message, something like "Restarting timer t";
- if (msg) std::cout << msg << std::endl;
-
- // Set timer status to running, reset accumulated time, and set start time
- running = true;
- acc_time = 0;
- start_clock = clock();
- start_time = time(0);
-
-} // timer::restart
-
-//===========================================================================
-// Stop the timer and print an optional message.
-
-inline void timer::stop(const char* msg)
-{
- // Print an optional message, something like "Stopping timer t";
- if (msg) std::cout << msg << std::endl;
-
- // Compute accumulated running time and set timer status to not running
- if (running) acc_time += elapsed_time();
- running = false;
-
-} // timer::stop
-
-//===========================================================================
-// Print out an optional message followed by the current timer timing.
-
-inline void timer::check(const char* msg)
-{
- // Print an optional message, something like "Checking timer t";
- if (msg) std::cout << msg << " : ";
-
- std::cout << "Elapsed time [" << std::setiosflags(std::ios::fixed)
- << std::setprecision(2)
- << acc_time + (running ? elapsed_time() : 0) << "] seconds\n";
-
-} // timer::check
-
-//===========================================================================
-// Allow timers to be printed to ostreams using the syntax 'os << t'
-// for an ostream 'os' and a timer 't'. For example, "cout << t" will
-// print out the total amount of time 't' has been "running".
-
-inline std::ostream& operator<<(std::ostream& os, timer& t)
-{
- os << std::setprecision(2) << std::setiosflags(std::ios::fixed)
- << t.acc_time + (t.running ? t.elapsed_time() : 0);
- return os;
-}
-
-//===========================================================================
-
-#endif /* TIMER_HPP */
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/versions.am
----------------------------------------------------------------------
diff --git a/third_party/versions.am b/third_party/versions.am
deleted file mode 100644
index c123d26..0000000
--- a/third_party/versions.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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
-
-# This automake utility file is included from third_party/Makefile.am
-# and src/Makefile.am, so we can update the version numbers of
-# third_party packages in exactly one place. For now, however, we
-# still need to update version numbers in src/python/setup.py.in too!
-
-BOTO_VERSION = 2.0b2
-DISTRIBUTE_VERSION = 0.6.26
-ZOOKEEPER_VERSION = 3.3.4
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/zookeeper-3.3.4.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/zookeeper-3.3.4.tar.gz b/third_party/zookeeper-3.3.4.tar.gz
deleted file mode 100644
index 09d4924..0000000
Binary files a/third_party/zookeeper-3.3.4.tar.gz and /dev/null differ
[13/35] git commit: Fixes os::environ for OS X.
Posted by be...@apache.org.
Fixes os::environ for OS X.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/cc5e1e7b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/cc5e1e7b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/cc5e1e7b
Branch: refs/heads/master
Commit: cc5e1e7b704971301d386dafe47893ccfbaac792
Parents: 1caf21b
Author: Benjamin Hindman <be...@twitter.com>
Authored: Tue May 28 13:23:39 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:20:25 2013 -0700
----------------------------------------------------------------------
.../libprocess/3rdparty/stout/include/stout/os.hpp | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/cc5e1e7b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
index 28a08cc..1b3fb47 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os.hpp
@@ -74,8 +74,9 @@ inline char** environ()
// shared libraries.
#ifdef __APPLE__
return *_NSGetEnviron();
-#endif
+#else
return ::environ;
+#endif
}
[22/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/src/examples/python/test-executor.in
----------------------------------------------------------------------
diff --git a/src/examples/python/test-executor.in b/src/examples/python/test-executor.in
index 0e47478..6f18682 100644
--- a/src/examples/python/test-executor.in
+++ b/src/examples/python/test-executor.in
@@ -14,13 +14,13 @@ test ! -z "${PYTHON}" && \
PYTHON=@PYTHON@
-DISTRIBUTE_EGG=`echo ${MESOS_BUILD_DIR}/third_party/distribute-*/dist/*.egg`
+DISTRIBUTE_EGG=`echo ${MESOS_BUILD_DIR}/3rdparty/distribute-*/dist/*.egg`
test ! -e ${DISTRIBUTE_EGG} && \
echo "${RED}Failed to find ${DISTRIBUTE_EGG}${NORMAL}" && \
exit 1
-PROTOBUF=${MESOS_BUILD_DIR}/third_party/libprocess/third_party/protobuf-2.4.1
+PROTOBUF=${MESOS_BUILD_DIR}/3rdparty/libprocess/3rdparty/protobuf-2.4.1
PROTOBUF_EGG=`echo ${PROTOBUF}/python/dist/protobuf*.egg`
test ! -e ${PROTOBUF_EGG} && \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/src/examples/python/test-framework.in
----------------------------------------------------------------------
diff --git a/src/examples/python/test-framework.in b/src/examples/python/test-framework.in
index 9c299d9..d66cf6b 100644
--- a/src/examples/python/test-framework.in
+++ b/src/examples/python/test-framework.in
@@ -14,13 +14,13 @@ test ! -z "${PYTHON}" && \
PYTHON=@PYTHON@
-DISTRIBUTE_EGG=`echo ${MESOS_BUILD_DIR}/third_party/distribute-*/dist/*.egg`
+DISTRIBUTE_EGG=`echo ${MESOS_BUILD_DIR}/3rdparty/distribute-*/dist/*.egg`
test ! -e ${DISTRIBUTE_EGG} && \
echo "${RED}Failed to find ${DISTRIBUTE_EGG}${NORMAL}" && \
exit 1
-PROTOBUF=${MESOS_BUILD_DIR}/third_party/libprocess/third_party/protobuf-2.4.1
+PROTOBUF=${MESOS_BUILD_DIR}/3rdparty/libprocess/3rdparty/protobuf-2.4.1
PROTOBUF_EGG=`echo ${PROTOBUF}/python/dist/protobuf*.egg`
test ! -e ${PROTOBUF_EGG} && \
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/src/python/setup.py.in
----------------------------------------------------------------------
diff --git a/src/python/setup.py.in b/src/python/setup.py.in
index 0083f23..cf10704 100644
--- a/src/python/setup.py.in
+++ b/src/python/setup.py.in
@@ -19,9 +19,9 @@ abs_top_builddir = '@abs_top_builddir@'
src_python_dist = os.path.join('src', 'python', 'dist')
src_python_native = os.path.join('src', 'python', 'native')
-leveldb = os.path.join('third_party', 'leveldb')
-zookeeper = os.path.join('third_party', 'zookeeper-3.3.4', 'src', 'c')
-libprocess = os.path.join('third_party', 'libprocess')
+leveldb = os.path.join('3rdparty', 'leveldb')
+zookeeper = os.path.join('3rdparty', 'zookeeper-3.3.4', 'src', 'c')
+libprocess = os.path.join('3rdparty', 'libprocess')
# Even though a statically compiled libprocess should include glog,
# libev, gperftools, and protobuf before installation this isn't the
@@ -29,10 +29,10 @@ libprocess = os.path.join('third_party', 'libprocess')
# libraries when building the final result, we need to explicitly
# include them here (or more precisely, down where we actually include
# libev.a and libprofiler.a).
-glog = os.path.join(libprocess, 'third_party', 'glog-0.3.1')
-libev = os.path.join(libprocess, 'third_party', 'libev-4.15')
-gperftools = os.path.join(libprocess, 'third_party', 'gperftools-2.0')
-protobuf = os.path.join(libprocess, 'third_party', 'protobuf-2.4.1')
+glog = os.path.join(libprocess, '3rdparty', 'glog-0.3.1')
+libev = os.path.join(libprocess, '3rdparty', 'libev-4.15')
+gperftools = os.path.join(libprocess, '3rdparty', 'gperftools-2.0')
+protobuf = os.path.join(libprocess, '3rdparty', 'protobuf-2.4.1')
# We need to execute from the same directory as this script.
os.chdir(os.path.abspath(os.path.dirname(__file__)))
@@ -70,7 +70,7 @@ INCLUDE_DIRS = [
LIBRARY_DIRS = []
EXTRA_OBJECTS = [
- os.path.join(abs_top_builddir, 'src', '.libs', 'libmesos_no_third_party.a'),
+ os.path.join(abs_top_builddir, 'src', '.libs', 'libmesos_no_3rdparty.a'),
os.path.join(abs_top_builddir, protobuf, 'src', '.libs', 'libprotobuf.a'),
os.path.join(abs_top_builddir, leveldb, 'libleveldb.a'),
os.path.join(abs_top_builddir, zookeeper, '.libs', 'libzookeeper_mt.a'),
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/src/tests/zookeeper.cpp
----------------------------------------------------------------------
diff --git a/src/tests/zookeeper.cpp b/src/tests/zookeeper.cpp
index 237d54c..62d93b5 100644
--- a/src/tests/zookeeper.cpp
+++ b/src/tests/zookeeper.cpp
@@ -50,7 +50,7 @@ void ZooKeeperTest::SetUpTestCase()
{
if (!Jvm::created()) {
std::string zkHome = flags.build_dir +
- "/third_party/zookeeper-" ZOOKEEPER_VERSION;
+ "/3rdparty/zookeeper-" ZOOKEEPER_VERSION;
std::string classpath = "-Djava.class.path=" +
zkHome + "/zookeeper-" ZOOKEEPER_VERSION ".jar:" +
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/Makefile.am b/third_party/Makefile.am
deleted file mode 100644
index de25db9..0000000
--- a/third_party/Makefile.am
+++ /dev/null
@@ -1,101 +0,0 @@
-# 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
-
-# This Makefile is for building third_party packages from
-# tarballs. For autotools-based packages, we configure each of the
-# packages to build static PIC binaries which we can safely link into
-# a shared libmesos, and build it in-place without installing it (even
-# if one runs 'make install' in this directory). Non-autotools based
-# packages may be special cases; this Makefile is responsible for
-# passing any special make or configure flags that might be required.
-
-BUILT_SOURCES = # Initialized to enable using +=.
-
-SUBDIRS = libprocess
-
-# We need to add '--srcdir=.' needed because 'make distcheck' adds
-# '--srcdir=...' when configuring.
-CONFIGURE_ARGS = @CONFIGURE_ARGS@ --enable-shared=no --with-pic --srcdir=.
-
-include versions.am
-
-BOTO = boto-$(BOTO_VERSION)
-DISTRIBUTE = distribute-$(DISTRIBUTE_VERSION)
-LEVELDB = leveldb
-ZOOKEEPER = zookeeper-$(ZOOKEEPER_VERSION)
-
-
-EXTRA_DIST = \
- $(BOTO).zip \
- $(DISTRIBUTE).tar.gz \
- $(LEVELDB).tar.gz \
- $(ZOOKEEPER).tar.gz
-
-CLEAN_EXTRACTED = \
- $(BOTO) \
- $(DISTRIBUTE) \
- $(LEVELDB) \
- $(ZOOKEEPER)
-
-
-# This is where the magic happens: we use stamp files as dependencies
-# which cause the packages to get extracted as necessary. We also
-# apply any patches as appropriate.
-%-stamp: %.tar.gz
- gzip -d -c $^ | tar xf -
- test ! -e $(srcdir)/$*.patch || patch -d $* -p1 <$(srcdir)/$*.patch
- touch $@
-
-
-if HAS_PYTHON
-DISTRIBUTE_EGG = \
- $(DISTRIBUTE)/dist/$(DISTRIBUTE)$(PYTHON_EGG_PUREPY_POSTFIX).egg
-
-$(DISTRIBUTE_EGG): $(DISTRIBUTE)-stamp
- cd $(DISTRIBUTE) && $(PYTHON) setup.py bdist_egg
-endif
-
-
-# TODO(charles): Figure out PIC options in our configure.ac or create
-# a configure.ac for leveldb.
-$(LEVELDB)/libleveldb.a: $(LEVELDB)-stamp
- cd $(LEVELDB) && \
- $(MAKE) $(AM_MAKEFLAGS) CC="$(CXX)" OPT="$(CXXFLAGS) -fPIC"
-
-$(ZOOKEEPER)/src/c/libzookeeper_mt.la: $(ZOOKEEPER)-stamp
- cd $(ZOOKEEPER)/src/c && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
-
-# Dependencies for all-local.
-ALL_LOCAL = $(LEVELDB)/libleveldb.a
-
-if HAS_PYTHON
- ALL_LOCAL += $(DISTRIBUTE_EGG)
-endif
-
-if WITH_INCLUDED_ZOOKEEPER
- ALL_LOCAL += $(ZOOKEEPER)/src/c/libzookeeper_mt.la
-else
- # Now matter what we need to extract ZooKeeper so that we can run
- # 'make check' (some of our tests need the ZooKeeper JAR).
- ALL_LOCAL += $(ZOOKEEPER)-stamp
-endif
-
-all-local: $(ALL_LOCAL)
-
-clean-local:
- rm -r -f $(CLEAN_EXTRACTED)
- rm -f *-stamp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/boto-2.0b2.zip
----------------------------------------------------------------------
diff --git a/third_party/boto-2.0b2.zip b/third_party/boto-2.0b2.zip
deleted file mode 100644
index 5992473..0000000
Binary files a/third_party/boto-2.0b2.zip and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/distribute-0.6.26.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/distribute-0.6.26.tar.gz b/third_party/distribute-0.6.26.tar.gz
deleted file mode 100644
index 3a598cc..0000000
Binary files a/third_party/distribute-0.6.26.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/leveldb.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/leveldb.tar.gz b/third_party/leveldb.tar.gz
deleted file mode 100644
index 2326611..0000000
Binary files a/third_party/leveldb.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/Makefile.am b/third_party/libprocess/3rdparty/Makefile.am
deleted file mode 100644
index 20599ec..0000000
--- a/third_party/libprocess/3rdparty/Makefile.am
+++ /dev/null
@@ -1,170 +0,0 @@
-# This Makefile is for building third-party packages from
-# tarballs. For autotools-based packages, we configure each of the
-# packages to build static PIC binaries which we can safely link into
-# a shared libmesos, and build it in-place without installing it (even
-# if one runs 'make install' in this directory). Non-autotools based
-# packages may be special cases; this Makefile is responsible for
-# passing any special make or configure flags that might be required.
-
-SUBDIRS = stout
-
-BUILT_SOURCES = # Initialized to enable using +=.
-
-# We need to add '--srcdir=.' needed because 'make distcheck' adds
-# '--srcdir=...' when configuring.
-CONFIGURE_ARGS = @CONFIGURE_ARGS@ --enable-shared=no --with-pic --srcdir=.
-
-include versions.am
-
-STOUT = stout
-BOOST = boost-$(BOOST_VERSION)
-GLOG = glog-$(GLOG_VERSION)
-GMOCK = gmock-$(GMOCK_VERSION)
-GPERFTOOLS = gperftools-$(GPERFTOOLS_VERSION)
-GTEST = $(GMOCK)/gtest
-RY_HTTP_PARSER = ry-http-parser-$(RY_HTTP_PARSER_VERSION)
-LIBEV = libev-$(LIBEV_VERSION)
-PROTOBUF = protobuf-$(PROTOBUF_VERSION)
-
-
-EXTRA_DIST = \
- $(BOOST).tar.gz \
- $(GLOG).tar.gz \
- $(GMOCK).tar.gz \
- $(GPERFTOOLS).tar.gz \
- $(LIBEV).tar.gz \
- $(LIBEV).patch \
- $(PROTOBUF).tar.gz \
- $(RY_HTTP_PARSER).tar.gz
-
-CLEAN_EXTRACTED = \
- $(BOOST) \
- $(GLOG) \
- $(GMOCK) \
- $(GPERFTOOLS) \
- $(LIBEV) \
- $(PROTOBUF) \
- $(RY_HTTP_PARSER)
-
-
-# This is where the magic happens: we use stamp files as dependencies
-# which cause the packages to get extracted as necessary. We also
-# apply any patches as appropriate.
-%-stamp: %.tar.gz
- gzip -d -c $^ | tar xf -
- test ! -e $(srcdir)/$*.patch || patch -d $* -p1 <$(srcdir)/$*.patch
- touch $@
-
-
-# Convenience library for Ryan Dahl's HTTP parser.
-noinst_LTLIBRARIES = libry_http_parser.la
-nodist_libry_http_parser_la_SOURCES = $(RY_HTTP_PARSER)/http_parser.c
-libry_http_parser_la_CPPFLAGS = -I$(RY_HTTP_PARSER)
-
-# We list the sources in BUILT_SOURCES to make sure that the package
-# gets unarchived first.
-BUILT_SOURCES += $(nodist_libry_http_parser_la_SOURCES)
-
-
-# Convenience library for gmock/gtest.
-check_LTLIBRARIES = libgmock.la
-nodist_libgmock_la_SOURCES = \
- $(GTEST)/src/gtest-all.cc \
- $(GMOCK)/src/gmock-all.cc
-libgmock_la_CPPFLAGS = \
- -I$(GTEST)/include -I$(GTEST) \
- -I$(GMOCK)/include -I$(GMOCK)
-
-# We list the sources in BUILT_SOURCES to make sure that the package
-# gets unarchived first.
-BUILT_SOURCES += $(nodist_libgmock_la_SOURCES)
-
-$(GMOCK)/src/gmock-all.cc: $(GMOCK)-stamp
-$(GTEST)/src/gtest-all.cc: $(GMOCK)-stamp
-
-
-$(BOOST)/boost: $(BOOST)-stamp
-
-$(GLOG)/libglog.la: $(GLOG)-stamp
- cd $(GLOG) && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
-
-if HAS_GPERFTOOLS
-$(GPERFTOOLS)/libprofiler.la: $(GPERFTOOLS)-build-stamp
-
-$(GPERFTOOLS)-build-stamp: $(GPERFTOOLS)-stamp
- cd $(GPERFTOOLS) && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
- touch $@
-endif
-
-$(LIBEV)/libev.la: $(LIBEV)-stamp
- cd $(LIBEV) && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
-
-$(PROTOBUF)/src/protoc $(PROTOBUF)/src/libprotobuf.la: $(PROTOBUF)-build-stamp
-
-$(PROTOBUF)-build-stamp: $(PROTOBUF)-stamp
- cd $(PROTOBUF) && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
- touch $@
-
-$(RY_HTTP_PARSER)/http_parser.c: $(RY_HTTP_PARSER)-stamp
-
-
-# Tests for stout.
-check_PROGRAMS = stout-tests
-
-stout_tests_SOURCES = \
- $(STOUT)/tests/bytes_tests.cpp \
- $(STOUT)/tests/duration_tests.cpp \
- $(STOUT)/tests/error_tests.cpp \
- $(STOUT)/tests/flags_tests.cpp \
- $(STOUT)/tests/gzip_tests.cpp \
- $(STOUT)/tests/hashset_tests.cpp \
- $(STOUT)/tests/json_tests.cpp \
- $(STOUT)/tests/main.cpp \
- $(STOUT)/tests/multimap_tests.cpp \
- $(STOUT)/tests/none_tests.cpp \
- $(STOUT)/tests/os_tests.cpp \
- $(STOUT)/tests/strings_tests.cpp \
- $(STOUT)/tests/uuid_tests.cpp
-
-if OS_LINUX
- stout_tests_SOURCES += $(STOUT)/tests/proc_tests.cpp
-endif
-
-stout_tests_CPPFLAGS = \
- -I$(srcdir)/$(STOUT)/include \
- -I$(BOOST) \
- -I$(GLOG)/src \
- -I$(GTEST)/include \
- -I$(GMOCK)/include \
- -I$(PROTOBUF)/src \
- $(AM_CPPFLAGS)
-
-stout_tests_LDADD = \
- libgmock.la \
- $(GLOG)/libglog.la \
- $(PROTOBUF)/src/libprotobuf.la
-
-TESTS = stout-tests
-
-# Dependencies for all-local.
-ALL_LOCAL = \
- $(STOUT)/Makefile \
- $(BOOST)-stamp \
- $(GLOG)/libglog.la \
- $(LIBEV)/libev.la \
- $(PROTOBUF)/src/libprotobuf.la \
- $(PROTOBUF)/src/protoc
-
-if HAS_GPERFTOOLS
- ALL_LOCAL += $(GPERFTOOLS)/libprofiler.la
-endif
-
-all-local: $(ALL_LOCAL)
-
-clean-local:
- rm -r -f $(CLEAN_EXTRACTED)
- rm -f *-stamp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/boost-1.53.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/boost-1.53.0.tar.gz b/third_party/libprocess/3rdparty/boost-1.53.0.tar.gz
deleted file mode 100644
index 770d837..0000000
Binary files a/third_party/libprocess/3rdparty/boost-1.53.0.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/glog-0.3.1.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/glog-0.3.1.tar.gz b/third_party/libprocess/3rdparty/glog-0.3.1.tar.gz
deleted file mode 100644
index 19b4b94..0000000
Binary files a/third_party/libprocess/3rdparty/glog-0.3.1.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz b/third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz
deleted file mode 100644
index d45d989..0000000
Binary files a/third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/gperftools-2.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/gperftools-2.0.tar.gz b/third_party/libprocess/3rdparty/gperftools-2.0.tar.gz
deleted file mode 100644
index 13b03ca..0000000
Binary files a/third_party/libprocess/3rdparty/gperftools-2.0.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/libev-4.15.patch
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/libev-4.15.patch b/third_party/libprocess/3rdparty/libev-4.15.patch
deleted file mode 100644
index 2b94532..0000000
--- a/third_party/libprocess/3rdparty/libev-4.15.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -rupN libev-4.15/ev.h libev-4.15-patched/ev.h
---- libev-4.15/ev.h 2013-03-01 03:05:29.000000000 -0800
-+++ libev-4.15-patched/ev.h 2013-05-20 16:01:47.000000000 -0700
-@@ -121,7 +121,7 @@ EV_CPP(extern "C" {)
- # ifdef _WIN32
- # define EV_CHILD_ENABLE 0
- # else
--# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
-+# define EV_CHILD_ENABLE 0
- #endif
- #endif
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/libev-4.15.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/libev-4.15.tar.gz b/third_party/libprocess/3rdparty/libev-4.15.tar.gz
deleted file mode 100644
index 4c282b5..0000000
Binary files a/third_party/libprocess/3rdparty/libev-4.15.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/protobuf-2.4.1.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/protobuf-2.4.1.tar.gz b/third_party/libprocess/3rdparty/protobuf-2.4.1.tar.gz
deleted file mode 100644
index 38ec4de..0000000
Binary files a/third_party/libprocess/3rdparty/protobuf-2.4.1.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz b/third_party/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz
deleted file mode 100644
index b811b63..0000000
Binary files a/third_party/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/LICENSE
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/LICENSE b/third_party/libprocess/3rdparty/stout/LICENSE
deleted file mode 100644
index f433b1a..0000000
--- a/third_party/libprocess/3rdparty/stout/LICENSE
+++ /dev/null
@@ -1,177 +0,0 @@
-
- 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/third_party/libprocess/3rdparty/stout/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/Makefile.am b/third_party/libprocess/3rdparty/stout/Makefile.am
deleted file mode 100644
index fdd3482..0000000
--- a/third_party/libprocess/3rdparty/stout/Makefile.am
+++ /dev/null
@@ -1,61 +0,0 @@
-# Makefile for stout.
-
-ACLOCAL_AMFLAGS = -I m4
-
-AUTOMAKE_OPTIONS = foreign
-
-EXTRA_DIST = \
- include/stout/bytes.hpp \
- include/stout/cache.hpp \
- include/stout/duration.hpp \
- include/stout/error.hpp \
- include/stout/exit.hpp \
- include/stout/fatal.hpp \
- include/stout/flags.hpp \
- include/stout/flags/flag.hpp \
- include/stout/flags/flags.hpp \
- include/stout/flags/loader.hpp \
- include/stout/flags/parse.hpp \
- include/stout/foreach.hpp \
- include/stout/format.hpp \
- include/stout/fs.hpp \
- include/stout/gtest.hpp \
- include/stout/gzip.hpp \
- include/stout/hashmap.hpp \
- include/stout/hashset.hpp \
- include/stout/json.hpp \
- include/stout/lambda.hpp \
- include/stout/multihashmap.hpp \
- include/stout/multimap.hpp \
- include/stout/net.hpp \
- include/stout/none.hpp \
- include/stout/nothing.hpp \
- include/stout/numify.hpp \
- include/stout/option.hpp \
- include/stout/os.hpp \
- include/stout/owned.hpp \
- include/stout/path.hpp \
- include/stout/preprocessor.hpp \
- include/stout/proc.hpp \
- include/stout/protobuf.hpp \
- include/stout/result.hpp \
- include/stout/stopwatch.hpp \
- include/stout/stringify.hpp \
- include/stout/strings.hpp \
- include/stout/try.hpp \
- include/stout/utils.hpp \
- include/stout/uuid.hpp \
- tests/bytes_tests.cpp \
- tests/duration_tests.cpp \
- tests/error_tests.cpp \
- tests/flags_tests.cpp \
- tests/gzip_tests.cpp \
- tests/hashset_tests.cpp \
- tests/json_tests.cpp \
- tests/main.cpp \
- tests/multimap_tests.cpp \
- tests/none_tests.cpp \
- tests/os_tests.cpp \
- tests/proc_tests.cpp \
- tests/strings_tests.cpp \
- tests/uuid_tests.cpp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/README
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/README b/third_party/libprocess/3rdparty/stout/README
deleted file mode 100644
index 685a4ae..0000000
--- a/third_party/libprocess/3rdparty/stout/README
+++ /dev/null
@@ -1,32 +0,0 @@
-Stout is a header-only C++ library.
-
-No action is needed if you would like to use this library in your
-project. Simply add the include folder to your include path during
-compilation.
-
-Depending on which headers you'd like to use, you may require the
-following third party libraries:
-
- - Boost
- - Google's glog (this dependency will be removed in the future).
- - Google's protobuf.
- - Google's gmock/gtest.
-
-
-Building Tests
-==============
-
-We'll assume you've got a distribution of gmock and have already built
-a static archive called libgmock.a (see gmock's README to learn
-how). We'll also assume the Boost and glog headers can be found via
-the include paths and libglog.* can be found via the library search
-paths. You can then build the tests via:
-
-$ g++ -I${STOUT}/include -I$(GMOCK)/gtest/include -I$(GMOCK)/include \
- ${STOUT}/tests/tests.cpp libgmock.a -lglog -o tests
-
-Note that if you want to test the gzip headers you'll need to define
-HAVE_LIBZ and link against libz:
-
-$ g++ -I${STOUT}/include -I$(GMOCK)/gtest/include -I$(GMOCK)/include \
- -DHAVE_LIBZ ${STOUT}/tests/tests.cpp libgmock.a -lglog -lz -o tests
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/bootstrap
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/bootstrap b/third_party/libprocess/3rdparty/stout/bootstrap
deleted file mode 100755
index 89b9bc8..0000000
--- a/third_party/libprocess/3rdparty/stout/bootstrap
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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 "${@}"
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/configure.ac
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/configure.ac b/third_party/libprocess/3rdparty/stout/configure.ac
deleted file mode 100644
index 86e1ff3..0000000
--- a/third_party/libprocess/3rdparty/stout/configure.ac
+++ /dev/null
@@ -1,14 +0,0 @@
-# Generated with autoscan, then modified appropriately.
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ([2.61])
-AC_INIT([stout], [0.1.0])
-
-AC_LANG([C++])
-
-# Initialize automake.
-AM_INIT_AUTOMAKE([1.10])
-
-AC_CONFIG_FILES([Makefile])
-
-AC_OUTPUT
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/bytes.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/bytes.hpp b/third_party/libprocess/3rdparty/stout/include/stout/bytes.hpp
deleted file mode 100644
index 754fbb2..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/bytes.hpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#ifndef __STOUT_BYTES_HPP__
-#define __STOUT_BYTES_HPP__
-
-#include <ctype.h> // For 'isdigit'.
-#include <stdint.h>
-
-#include <iomanip>
-#include <iostream>
-#include <string>
-
-#include "numify.hpp"
-#include "strings.hpp"
-#include "try.hpp"
-
-
-class Bytes
-{
-public:
- static Try<Bytes> parse(const std::string& s)
- {
- size_t index = 0;
-
- while (index < s.size()) {
- if (isdigit(s[index])) {
- index++;
- continue;
- } else if (s[index] == '.') {
- return Error("Fractional bytes '" + s + "'");
- }
-
- Try<uint64_t> value = numify<uint64_t>(s.substr(0, index));
-
- if (value.isError()) {
- return Error(value.error());
- }
-
- const std::string& unit = strings::upper(s.substr(index));
-
- if (unit == "B") {
- return Bytes(value.get(), BYTES);
- } else if (unit == "KB") {
- return Bytes(value.get(), KILOBYTES);
- } else if (unit == "MB") {
- return Bytes(value.get(), MEGABYTES);
- } else if (unit == "GB") {
- return Bytes(value.get(), GIGABYTES);
- } else if (unit == "TB") {
- return Bytes(value.get(), TERABYTES);
- } else {
- return Error("Unknown bytes unit '" + unit + "'");
- }
- }
- return Error("Invalid bytes '" + s + "'");
- }
-
- Bytes(uint64_t bytes = 0) : value(bytes) {}
- Bytes(uint64_t _value, uint64_t _unit) : value(_value * _unit) {}
-
- // TODO(bmahler): Consider killing kilobytes to terabyte helpers, given
- // they implicitly lose precision if not careful.
- uint64_t bytes() const { return value; }
- uint64_t kilobytes() const { return value / KILOBYTES; }
- uint64_t megabytes() const { return value / MEGABYTES; }
- uint64_t gigabytes() const { return value / GIGABYTES; }
- uint64_t terabytes() const { return value / TERABYTES; }
-
- bool operator < (const Bytes& that) const { return value < that.value; }
- bool operator <= (const Bytes& that) const { return value <= that.value; }
- bool operator > (const Bytes& that) const { return value > that.value; }
- bool operator >= (const Bytes& that) const { return value >= that.value; }
- bool operator == (const Bytes& that) const { return value == that.value; }
- bool operator != (const Bytes& that) const { return value != that.value; }
-
- Bytes& operator += (const Bytes& that)
- {
- value += that.value;
- return *this;
- }
-
- Bytes& operator -= (const Bytes& that)
- {
- value -= that.value;
- return *this;
- }
-
-protected:
- static const uint64_t BYTES = 1;
- static const uint64_t KILOBYTES = 1024 * BYTES;
- static const uint64_t MEGABYTES = 1024 * KILOBYTES;
- static const uint64_t GIGABYTES = 1024 * MEGABYTES;
- static const uint64_t TERABYTES = 1024 * GIGABYTES;
-
-private:
- uint64_t value;
-};
-
-
-class Kilobytes : public Bytes
-{
-public:
- explicit Kilobytes(uint64_t value) : Bytes(value, KILOBYTES) {}
-};
-
-
-class Megabytes : public Bytes
-{
-public:
- explicit Megabytes(uint64_t value) : Bytes(value, MEGABYTES) {}
-};
-
-
-class Gigabytes : public Bytes
-{
-public:
- explicit Gigabytes(uint64_t value) : Bytes(value, GIGABYTES) {}
-};
-
-
-class Terabytes : public Bytes
-{
-public:
- explicit Terabytes(uint64_t value) : Bytes(value, TERABYTES) {}
-};
-
-
-inline std::ostream& operator << (std::ostream& stream, const Bytes& bytes)
-{
- // Only raise the unit when there is no loss of information.
- if (bytes.bytes() == 0) {
- return stream << bytes.bytes() << "B";
- } else if (bytes.bytes() % 1024 != 0) {
- return stream << bytes.bytes() << "B";
- } else if (bytes.kilobytes() % 1024 != 0) {
- return stream << bytes.kilobytes() << "KB";
- } else if (bytes.megabytes() % 1024 != 0) {
- return stream << bytes.megabytes() << "MB";
- } else if (bytes.gigabytes() % 1024 != 0) {
- return stream << bytes.gigabytes() << "GB";
- } else {
- return stream << bytes.terabytes() << "TB";
- }
-}
-
-
-inline Bytes operator + (const Bytes& lhs, const Bytes& rhs)
-{
- Bytes sum = lhs;
- sum += rhs;
- return sum;
-}
-
-
-inline Bytes operator - (const Bytes& lhs, const Bytes& rhs)
-{
- Bytes diff = lhs;
- diff -= rhs;
- return diff;
-}
-
-#endif // __STOUT_BYTES_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/cache.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/cache.hpp b/third_party/libprocess/3rdparty/stout/include/stout/cache.hpp
deleted file mode 100644
index 653507c..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/cache.hpp
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef __STOUT_CACHE_HPP__
-#define __STOUT_CACHE_HPP__
-
-#include <functional>
-#include <iostream>
-#include <list>
-#include <map>
-
-#include <tr1/functional>
-#include <tr1/unordered_map>
-
-#include "none.hpp"
-#include "option.hpp"
-
-// Forward declaration.
-template <typename Key, typename Value>
-class cache;
-
-// Outputs the key/value pairs from least to most-recently used.
-template <typename Key, typename Value>
-std::ostream& operator << (
- std::ostream& stream,
- const cache<Key, Value>& c);
-
-
-// Provides a least-recently used (LRU) cache of some predefined
-// capacity. A "write" and a "read" both count as uses.
-template <typename Key, typename Value>
-class cache
-{
-public:
- typedef std::list<Key> list;
- typedef std::tr1::unordered_map<
- Key, std::pair<Value, typename list::iterator> > map;
-
- explicit cache(int _capacity) : capacity(_capacity) {}
-
- void put(const Key& key, const Value& value)
- {
- typename map::iterator i = values.find(key);
- if (i == values.end()) {
- insert(key, value);
- } else {
- (*i).second.first = value;
- use(i);
- }
- }
-
- Option<Value> get(const Key& key)
- {
- typename map::iterator i = values.find(key);
-
- if (i != values.end()) {
- use(i);
- return (*i).second.first;
- }
-
- return None();
- }
-
-private:
- // Not copyable, not assignable.
- cache(const cache&);
- cache& operator = (const cache&);
-
- // Give the operator access to our internals.
- friend std::ostream& operator << <>(
- std::ostream& stream,
- const cache<Key, Value>& c);
-
- // Insert key/value into the cache.
- void insert(const Key& key, const Value& value)
- {
- if (keys.size() == capacity) {
- evict();
- }
-
- // Get a "pointer" into the lru list for efficient update.
- typename list::iterator i = keys.insert(keys.end(), key);
-
- // Save key/value and "pointer" into lru list.
- values.insert(std::make_pair(key, std::make_pair(value, i)));
- }
-
- // Updates the LRU ordering in the cache for the given iterator.
- void use(const typename map::iterator& i)
- {
- // Move the "pointer" to the end of the lru list.
- keys.splice(keys.end(), keys, (*i).second.second);
-
- // Now update the "pointer" so we can do this again.
- (*i).second.second = --keys.end();
- }
-
- // Evict the least-recently used element from the cache.
- void evict()
- {
- const typename map::iterator& i = values.find(keys.front());
- CHECK(i != values.end());
- values.erase(i);
- keys.pop_front();
- }
-
- // Size of the cache.
- int capacity;
-
- // Cache of values and "pointers" into the least-recently used list.
- map values;
-
- // Keys ordered by least-recently used.
- list keys;
-};
-
-
-template <typename Key, typename Value>
-std::ostream& operator << (
- std::ostream& stream,
- const cache<Key, Value>& c)
-{
- typename cache<Key, Value>::list::const_iterator i1;
- for (i1 = c.keys.begin(); i1 != c.keys.end(); i1++) {
- stream << *i1 << ": ";
- typename cache<Key, Value>::map::const_iterator i2;
- i2 = c.values.find(*i1);
- CHECK(i2 != c.values.end());
- stream << *i2 << std::endl;
- }
- return stream;
-}
-
-#endif // __STOUT_CACHE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/duration.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/duration.hpp b/third_party/libprocess/3rdparty/stout/include/stout/duration.hpp
deleted file mode 100644
index 47e85ff..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/duration.hpp
+++ /dev/null
@@ -1,297 +0,0 @@
-#ifndef __STOUT_DURATION_HPP__
-#define __STOUT_DURATION_HPP__
-
-#include <ctype.h> // For 'isdigit'.
-#include <limits.h> // For 'LLONG_(MAX|MIN)'
-
-#include <iomanip>
-#include <iostream>
-#include <string>
-
-#include "error.hpp"
-#include "numify.hpp"
-#include "try.hpp"
-
-class Duration
-{
-public:
- static Try<Duration> parse(const std::string& s)
- {
- // TODO(benh): Support negative durations (i.e., starts with '-').
- size_t index = 0;
- while (index < s.size()) {
- if (isdigit(s[index]) || s[index] == '.') {
- index++;
- continue;
- }
-
- Try<double> value = numify<double>(s.substr(0, index));
-
- if (value.isError()) {
- return Error(value.error());
- }
-
- const std::string& unit = s.substr(index);
-
- if (unit == "ns") {
- return Duration(value.get(), NANOSECONDS);
- } else if (unit == "us") {
- return Duration(value.get(), MICROSECONDS);
- } else if (unit == "ms") {
- return Duration(value.get(), MILLISECONDS);
- } else if (unit == "secs") {
- return Duration(value.get(), SECONDS);
- } else if (unit == "mins") {
- return Duration(value.get(), MINUTES);
- } else if (unit == "hrs") {
- return Duration(value.get(), HOURS);
- } else if (unit == "days") {
- return Duration(value.get(), DAYS);
- } else if (unit == "weeks") {
- return Duration(value.get(), WEEKS);
- } else {
- return Error("Unknown duration unit '" + unit + "'");
- }
- }
- return Error("Invalid duration '" + s + "'");
- }
-
- static Try<Duration> create(double seconds);
-
- Duration() : nanos(0) {}
-
- int64_t ns() const { return nanos; }
- double us() const { return static_cast<double>(nanos) / MICROSECONDS; }
- double ms() const { return static_cast<double>(nanos) / MILLISECONDS; }
- double secs() const { return static_cast<double>(nanos) / SECONDS; }
- double mins() const { return static_cast<double>(nanos) / MINUTES; }
- double hrs() const { return static_cast<double>(nanos) / HOURS; }
- double days() const { return static_cast<double>(nanos) / DAYS; }
- double weeks() const { return static_cast<double>(nanos) / WEEKS; }
-
- bool operator < (const Duration& d) const { return nanos < d.nanos; }
- bool operator <= (const Duration& d) const { return nanos <= d.nanos; }
- bool operator > (const Duration& d) const { return nanos > d.nanos; }
- bool operator >= (const Duration& d) const { return nanos >= d.nanos; }
- bool operator == (const Duration& d) const { return nanos == d.nanos; }
- bool operator != (const Duration& d) const { return nanos != d.nanos; }
-
- Duration& operator += (const Duration& that)
- {
- nanos += that.nanos;
- return *this;
- }
-
- Duration& operator -= (const Duration& that)
- {
- nanos -= that.nanos;
- return *this;
- }
-
- Duration& operator *= (double multiplier)
- {
- nanos = static_cast<int64_t>(nanos * multiplier);
- return *this;
- }
-
- Duration& operator /= (double divisor)
- {
- nanos = static_cast<int64_t>(nanos / divisor);
- return *this;
- }
-
- Duration operator + (const Duration& that) const
- {
- Duration sum = *this;
- sum += that;
- return sum;
- }
-
- Duration operator - (const Duration& that) const
- {
- Duration diff = *this;
- diff -= that;
- return diff;
- }
-
- Duration operator * (double multiplier) const
- {
- Duration product = *this;
- product *= multiplier;
- return product;
- }
-
- Duration operator / (double divisor) const
- {
- Duration quotient = *this;
- quotient /= divisor;
- return quotient;
- }
-
- // TODO(xujyan): Use constexpr for the following variables after
- // switching to C++11.
- // A constant holding the maximum value a Duration can have.
- static Duration max();
- // A constant holding the minimum (negative) value a Duration can
- // have.
- static Duration min();
- // A constant holding a Duration of a "zero" value.
- static Duration zero() { return Duration(); }
-
-protected:
- static const int64_t NANOSECONDS = 1;
- static const int64_t MICROSECONDS = 1000 * NANOSECONDS;
- static const int64_t MILLISECONDS = 1000 * MICROSECONDS;
- static const int64_t SECONDS = 1000 * MILLISECONDS;
- static const int64_t MINUTES = 60 * SECONDS;
- static const int64_t HOURS = 60 * MINUTES;
- static const int64_t DAYS = 24 * HOURS;
- static const int64_t WEEKS = 7 * DAYS;
-
- // For the Seconds, Minutes, Hours, Days & Weeks constructor.
- Duration(int32_t value, int64_t unit)
- : nanos(value * unit) {}
-
- // For the Nanoseconds, Microseconds, Milliseconds constructor.
- Duration(int64_t value, int64_t unit)
- : nanos(value * unit) {}
-
-private:
- // Used only by "parse".
- Duration(double value, int64_t unit)
- : nanos(static_cast<int64_t>(value * unit)) {}
-
- int64_t nanos;
-};
-
-
-class Nanoseconds : public Duration
-{
-public:
- explicit Nanoseconds(int64_t nanoseconds)
- : Duration(nanoseconds, NANOSECONDS) {}
-
- Nanoseconds(const Duration& d) : Duration(d) {}
-};
-
-
-class Microseconds : public Duration
-{
-public:
- explicit Microseconds(int64_t microseconds)
- : Duration(microseconds, MICROSECONDS) {}
-
- Microseconds(const Duration& d) : Duration(d) {}
-};
-
-
-class Milliseconds : public Duration
-{
-public:
- explicit Milliseconds(int64_t milliseconds)
- : Duration(milliseconds, MILLISECONDS) {}
-
- Milliseconds(const Duration& d) : Duration(d) {}
-};
-
-
-class Seconds : public Duration
-{
-public:
- explicit Seconds(int64_t seconds)
- : Duration(seconds, SECONDS) {}
-
- Seconds(const Duration& d) : Duration(d) {}
-};
-
-
-class Minutes : public Duration
-{
-public:
- explicit Minutes(int32_t minutes)
- : Duration(minutes, MINUTES) {}
-
- Minutes(const Duration& d) : Duration(d) {}
-};
-
-
-class Hours : public Duration
-{
-public:
- explicit Hours(int32_t hours)
- : Duration(hours, HOURS) {}
-
- Hours(const Duration& d) : Duration(d) {}
-};
-
-
-class Days : public Duration
-{
-public:
- explicit Days(int32_t days)
- : Duration(days, DAYS) {}
-
- Days(const Duration& d) : Duration(d) {}
-};
-
-
-class Weeks : public Duration
-{
-public:
- explicit Weeks(int32_t value) : Duration(value, WEEKS) {}
-
- Weeks(const Duration& d) : Duration(d) {}
-};
-
-
-inline std::ostream& operator << (
- std::ostream& stream,
- const Duration& duration)
-{
- long precision = stream.precision();
-
- // Output the duration in full double precision.
- stream.precision(std::numeric_limits<double>::digits10);
-
- if (duration < Microseconds(1)) {
- stream << duration.ns() << "ns";
- } else if (duration < Milliseconds(1)) {
- stream << duration.us() << "us";
- } else if (duration < Seconds(1)) {
- stream << duration.ms() << "ms";
- } else if (duration < Minutes(1)) {
- stream << duration.secs() << "secs";
- } else if (duration < Hours(1)) {
- stream << duration.mins() << "mins";
- } else if (duration < Days(1)) {
- stream << duration.hrs() << "hrs";
- } else if (duration < Weeks(1)) {
- stream << duration.days() << "days";
- } else {
- stream << duration.weeks() << "weeks";
- }
-
- // Return the stream to original formatting state.
- stream.precision(precision);
-
- return stream;
-}
-
-
-inline Try<Duration> Duration::create(double seconds)
-{
- if (seconds * SECONDS > LLONG_MAX) {
- return Error("Argument larger than the maximum number of seconds that "
- "a Duration can represent due to int64_t's size limit.");
- }
-
- return Nanoseconds(static_cast<int64_t>(seconds * SECONDS));
-}
-
-
-inline Duration Duration::max() { return Nanoseconds(LLONG_MAX); }
-
-
-inline Duration Duration::min() { return Nanoseconds(LLONG_MIN); }
-
-#endif // __STOUT_DURATION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/error.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/error.hpp b/third_party/libprocess/3rdparty/stout/include/stout/error.hpp
deleted file mode 100644
index 97a5cec..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/error.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef __STOUT_ERROR_HPP__
-#define __STOUT_ERROR_HPP__
-
-#include <errno.h>
-#include <string.h> // For strerror.
-
-#include <string>
-
-#include "result.hpp"
-#include "try.hpp"
-
-// An "error" type that is implicitly convertible to a Try<T> or
-// Result<T> for any T (effectively "syntactic sugar" to make code
-// more readable). The implementation uses cast operators to perform
-// the conversions instead of adding constructors to Try/Result
-// directly. One could imagine revisiting that decision for C++11
-// because the use of rvalue reference could eliminate some
-// unnecessary copies. However, performance is not critical since
-// Error should not get called very often in practice (if so, it's
-// probably being used for things that aren't really errors or there
-// is a more serious problem during execution).
-
-class Error
-{
-public:
- explicit Error(const std::string& _message) : message(_message) {}
-
- template <typename T>
- operator Try<T> () const
- {
- return Try<T>::error(message);
- }
-
- // Give the compiler some help for nested Try<T>. For example,
- // enable converting Error to an Option<Try<T>>. Note that this will
- // bind to the innermost Try<T>.
- template <template <typename> class S, typename T>
- operator S<Try<T> > () const
- {
- return S<Try<T> >(Try<T>::error(message));
- }
-
- template <typename T>
- operator Result<T> () const
- {
- return Result<T>::error(message);
- }
-
- // Give the compiler some help for nested Result<T>. For example,
- // enable converting Error to an Option<Result<T>>. Note that this
- // will bind to the innermost Result<T>.
- template <template <typename> class S, typename T>
- operator S<Result<T> > () const
- {
- return S<Result<T> >(Result<T>::error(message));
- }
-
- const std::string message;
-};
-
-
-class ErrnoError : public Error
-{
-public:
- ErrnoError()
- : Error(std::string(strerror(errno))) {}
-
- ErrnoError(const std::string& message)
- : Error(message + ": " + std::string(strerror(errno))) {}
-};
-
-#endif // __STOUT_ERROR_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/exit.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/exit.hpp b/third_party/libprocess/3rdparty/stout/include/stout/exit.hpp
deleted file mode 100644
index e8da726..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/exit.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __STOUT_EXIT_HPP__
-#define __STOUT_EXIT_HPP__
-
-#include <stdlib.h>
-
-#include <iostream> // For std::cerr.
-#include <ostream>
-#include <sstream>
-#include <string>
-
-// Exit takes an exit status and provides a stream for output prior to
-// exiting. This is like glog's LOG(FATAL) or CHECK, except that it
-// does _not_ print a stack trace.
-//
-// Ex: EXIT(1) << "Cgroups are not present in this system.";
-#define EXIT(status) __Exit(status).stream()
-
-struct __Exit
-{
- __Exit(int _status) : status(_status) {}
-
- ~__Exit()
- {
- std::cerr << out.str() << std::endl;
- exit(status);
- }
-
- std::ostream& stream()
- {
- return out;
- }
-
- std::ostringstream out;
- const int status;
-};
-
-#endif // __STOUT_EXIT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/fatal.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/fatal.hpp b/third_party/libprocess/3rdparty/stout/include/stout/fatal.hpp
deleted file mode 100644
index eabee3e..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/fatal.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef __STOUT_FATAL_HPP__
-#define __STOUT_FATAL_HPP__
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-
-/*
- * Like the non-debug version except includes the file name and line
- * number in the output.
- */
-#define fatal(fmt...) __fatal(__FILE__, __LINE__, fmt)
-inline void __fatal(const char *file, int line, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, " (%s:%u)\n", file, line);
- fflush(stderr);
- va_end(args);
- exit(1);
-}
-
-
-/*
- * Like the non-debug version except includes the file name and line
- * number in the output.
- */
-#define fatalerror(fmt...) __fatalerror(__FILE__, __LINE__, fmt)
-inline void __fatalerror(const char *file, int line, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, " (%s:%u): ", file, line);
- perror(NULL);
- fflush(stderr);
- va_end(args);
- exit(1);
-}
-
-#endif // __STOUT_FATAL_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/flags.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags.hpp
deleted file mode 100644
index 0efd079..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/flags.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef __STOUT_FLAGS_HPP__
-#define __STOUT_FLAGS_HPP__
-
-#include <stout/flags/flags.hpp>
-
-// An abstraction for application/library "flags". An example is
-// probably best:
-// -------------------------------------------------------------
-// class MyFlags : public virtual FlagsBase // Use 'virtual' for composition!
-// {
-// public:
-// Flags()
-// {
-// add(&debug,
-// "debug",
-// "Help string for debug",
-// false);
-//
-// add(&name,
-// "name",
-// "Help string for name");
-// }
-
-// bool debug;
-// Option<string> name;
-// };
-//
-// ...
-//
-// map<string, Option<string> > values;
-// values["no-debug"] = None(); // --no-debug
-// values["debug"] = None(); // --debug
-// values["debug"] = Option<string>::some("true"); // --debug=true
-// values["debug"] = Option<string>::some("false"); // --debug=false
-// values["name"] = Option<string>::some("frank"); // --name=frank
-//
-// MyFlags flags;
-// flags.load(values);
-// flags.name.isSome() ...
-// flags.debug ...
-// -------------------------------------------------------------
-//
-// You can also compose flags provided that each has used "virtual
-// inheritance":
-// -------------------------------------------------------------
-// Flags<MyFlags1, MyFlags2> flags;
-// flags.add(...); // Any other flags you want to throw in there.
-// flags.load(values);
-// flags.flag_from_myflags1 ...
-// flags.flag_from_myflags2 ...
-// -------------------------------------------------------------
-//
-// "Fail early, fail often":
-//
-// You can not add duplicate flags, this is checked for you at compile
-// time for composite flags (e.g., Flag<MyFlags1, MyFlags2>) and also
-// checked at runtime for any other flags added via inheritance or
-// Flags::add(...).
-//
-// Flags that can not be loaded (e.g., attempting to use the 'no-'
-// prefix for a flag that is not boolean) will print a message to
-// standard error and abort the process.
-
-// TODO(benh): Provide a boolean which specifies whether or not to
-// abort on duplicates or load errors.
-
-// TODO(benh): Make prefix for environment variables configurable
-// (e.g., "MESOS_").
-
-#endif // __STOUT_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags/flag.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
deleted file mode 100644
index d31c984..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __STOUT_FLAGS_FLAG_HPP__
-#define __STOUT_FLAGS_FLAG_HPP__
-
-#include <string>
-
-#include <tr1/functional>
-
-#include <stout/nothing.hpp>
-#include <stout/try.hpp>
-
-namespace flags {
-
-// Forward declaration.
-class FlagsBase;
-
-struct Flag
-{
- std::string name;
- std::string help;
- bool boolean;
- std::tr1::function<Try<Nothing>(FlagsBase*, const std::string&)> loader;
-};
-
-} // namespace flags {
-
-#endif // __STOUT_FLAGS_FLAG_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags/flags.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
deleted file mode 100644
index 77d36e6..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
+++ /dev/null
@@ -1,481 +0,0 @@
-#ifndef __STOUT_FLAGS_FLAGS_HPP__
-#define __STOUT_FLAGS_FLAGS_HPP__
-
-#include <stdlib.h> // For abort.
-
-#include <map>
-#include <string>
-#include <typeinfo> // For typeid.
-
-#include <tr1/functional>
-
-#include <stout/error.hpp>
-#include <stout/exit.hpp>
-#include <stout/foreach.hpp>
-#include <stout/none.hpp>
-#include <stout/nothing.hpp>
-#include <stout/option.hpp>
-#include <stout/os.hpp>
-#include <stout/stringify.hpp>
-#include <stout/strings.hpp>
-#include <stout/try.hpp>
-
-#include <stout/flags/flag.hpp>
-#include <stout/flags/loader.hpp>
-#include <stout/flags/parse.hpp>
-
-namespace flags {
-
-class FlagsBase
-{
-public:
- virtual ~FlagsBase() {}
-
- // Load any flags from the environment given the variable prefix,
- // i.e., given prefix 'STOUT_' will load a flag named 'foo' via
- // environment variables 'STOUT_foo' or 'STOUT_FOO'.
- virtual Try<Nothing> load(
- const std::string& prefix,
- bool unknowns = false);
-
- // Load any flags from the environment given the variable prefix
- // (see above) followed by loading from the command line (via 'argc'
- // and 'argv'). If 'unknowns' is true then we'll ignore unknown
- // flags we see while loading. If 'duplicates' is true then we'll
- // ignore any duplicates we see while loading.
- virtual Try<Nothing> load(
- const Option<std::string>& prefix,
- int argc,
- char** argv,
- bool unknowns = false,
- bool duplicates = false);
-
- Try<Nothing> load(
- const std::string& prefix,
- int argc,
- char** argv,
- bool unknowns = false,
- bool duplicates = false);
-
- virtual Try<Nothing> load(
- const std::map<std::string, Option<std::string> >& values,
- bool unknowns = false);
-
- virtual Try<Nothing> load(
- const std::map<std::string, std::string>& values,
- bool unknowns = false);
-
- // Returns a string describing the flags.
- std::string usage() const;
-
- typedef std::map<std::string, Flag>::const_iterator const_iterator;
-
- const_iterator begin() const { return flags.begin(); }
- const_iterator end() const { return flags.end(); }
-
- template <typename T1, typename T2>
- void add(T1* t1,
- const std::string& name,
- const std::string& help,
- const T2& t2);
-
- template <typename T>
- void add(Option<T>* option,
- const std::string& name,
- const std::string& help);
-
-protected:
- template <typename Flags, typename T1, typename T2>
- void add(T1 Flags::*t1,
- const std::string& name,
- const std::string& help,
- const T2& t2);
-
- template <typename Flags, typename T>
- void add(Option<T> Flags::*option,
- const std::string& name,
- const std::string& help);
-
- void add(const Flag& flag);
-
-private:
- std::map<std::string, Flag> flags;
-};
-
-
-// Need to declare/define some explicit subclasses of FlagsBase so
-// that we can overload the 'Flags::operator FlagsN () const'
-// functions for each possible type.
-class _Flags1 : public virtual FlagsBase {};
-class _Flags2 : public virtual FlagsBase {};
-class _Flags3 : public virtual FlagsBase {};
-class _Flags4 : public virtual FlagsBase {};
-class _Flags5 : public virtual FlagsBase {};
-
-
-// TODO(benh): Add some "type constraints" for template paramters to
-// make sure they are all of type FlagsBase.
-template <typename Flags1 = _Flags1,
- typename Flags2 = _Flags2,
- typename Flags3 = _Flags3,
- typename Flags4 = _Flags4,
- typename Flags5 = _Flags5>
-class Flags : public virtual Flags1,
- public virtual Flags2,
- public virtual Flags3,
- public virtual Flags4,
- public virtual Flags5 {};
-
-
-template <typename T1, typename T2>
-void FlagsBase::add(
- T1* t1,
- const std::string& name,
- const std::string& help,
- const T2& t2)
-{
- *t1 = t2; // Set the default.
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T1) == typeid(bool);
- flag.loader = std::tr1::bind(
- &Loader<T1>::load,
- t1,
- std::tr1::function<Try<T1>(const std::string&)>(
- std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
-
- // Update the help string to include the default value.
- flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
- ? " (default: " // On same line, add space.
- : "(default: "; // On newline.
- flag.help += stringify(t2);
- flag.help += ")";
-
- FlagsBase::add(flag);
-}
-
-
-template <typename T>
-void FlagsBase::add(
- Option<T>* option,
- const std::string& name,
- const std::string& help)
-{
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T) == typeid(bool);
- flag.loader = std::tr1::bind(
- &OptionLoader<T>::load,
- option,
- std::tr1::function<Try<T>(const std::string&)>(
- std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
-
- FlagsBase::add(flag);
-}
-
-
-template <typename Flags, typename T1, typename T2>
-void FlagsBase::add(
- T1 Flags::*t1,
- const std::string& name,
- const std::string& help,
- const T2& t2)
-{
- Flags* flags = dynamic_cast<Flags*>(this);
- if (flags == NULL) {
- std::cerr << "Attempted to add flag '" << name
- << "' with incompatible type" << std::endl;
- abort();
- } else {
- flags->*t1 = t2; // Set the default.
- }
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T1) == typeid(bool);
- flag.loader = std::tr1::bind(
- &MemberLoader<Flags, T1>::load,
- std::tr1::placeholders::_1,
- t1,
- std::tr1::function<Try<T1>(const std::string&)>(
- std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2);
-
- // Update the help string to include the default value.
- flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
- ? " (default: " // On same line, add space.
- : "(default: "; // On newline.
- flag.help += stringify(t2);
- flag.help += ")";
-
- add(flag);
-}
-
-
-template <typename Flags, typename T>
-void FlagsBase::add(
- Option<T> Flags::*option,
- const std::string& name,
- const std::string& help)
-{
- Flags* flags = dynamic_cast<Flags*>(this);
- if (flags == NULL) {
- std::cerr << "Attempted to add flag '" << name
- << "' with incompatible type" << std::endl;
- abort();
- }
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T) == typeid(bool);
- flag.loader = std::tr1::bind(
- &OptionMemberLoader<Flags, T>::load,
- std::tr1::placeholders::_1,
- option,
- std::tr1::function<Try<T>(const std::string&)>(
- std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2);
-
- add(flag);
-}
-
-
-inline void FlagsBase::add(const Flag& flag)
-{
- if (flags.count(flag.name) > 0) {
- EXIT(1) << "Attempted to add duplicate flag '" << flag.name << "'";
- } else if (flag.name.find("no-") == 0) {
- EXIT(1) << "Attempted to add flag '" << flag.name
- << "' that starts with the reserved 'no-' prefix";
- }
-
- flags[flag.name] = flag;
-}
-
-
-// Extract environment variable "flags" with the specified prefix.
-inline std::map<std::string, Option<std::string> > extract(
- const std::string& prefix)
-{
- char** environ = os::environ();
-
- std::map<std::string, Option<std::string> > values;
-
- for (int i = 0; environ[i] != NULL; i++) {
- std::string variable = environ[i];
- if (variable.find(prefix) == 0) {
- size_t eq = variable.find_first_of("=");
- if (eq == std::string::npos) {
- continue; // Not expecting a missing '=', but ignore anyway.
- }
- std::string name = variable.substr(prefix.size(), eq - prefix.size());
- name = strings::lower(name); // Allow PREFIX_NAME or PREFIX_name.
- std::string value = variable.substr(eq + 1);
- values[name] = Option<std::string>::some(value);
- }
- }
-
- return values;
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const std::string& prefix,
- bool unknowns)
-{
- return load(extract(prefix), unknowns);
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const Option<std::string>& prefix,
- int argc,
- char** argv,
- bool unknowns,
- bool duplicates)
-{
- std::map<std::string, Option<std::string> > values;
-
- if (prefix.isSome()) {
- values = extract(prefix.get());
- }
-
- // Read flags from the command line.
- for (int i = 1; i < argc; i++) {
- const std::string arg(argv[i]);
-
- std::string name;
- Option<std::string> value = None();
- if (arg.find("--") == 0) {
- size_t eq = arg.find_first_of("=");
- if (eq == std::string::npos && arg.find("--no-") == 0) { // --no-name
- name = arg.substr(2);
- } else if (eq == std::string::npos) { // --name
- name = arg.substr(2);
- } else { // --name=value
- name = arg.substr(2, eq - 2);
- value = arg.substr(eq + 1);
- }
- }
- name = strings::lower(name);
-
- if (!duplicates) {
- if (values.count(name) > 0 ||
- (name.find("no-") == 0 && values.count(name.substr(3)) > 0)) {
- return Error("Duplicate flag '" + name + "' on command line");
- }
- }
-
- values[name] = value;
- }
-
- return load(values, unknowns);
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const std::string& prefix,
- int argc,
- char** argv,
- bool unknowns,
- bool duplicates)
-{
- return load(Option<std::string>::some(prefix),
- argc,
- argv,
- unknowns,
- duplicates);
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const std::map<std::string, Option<std::string> >& values,
- bool unknowns)
-{
- std::map<std::string, Option<std::string> >::const_iterator iterator;
-
- for (iterator = values.begin(); iterator != values.end(); ++iterator) {
- const std::string& name = iterator->first;
- const Option<std::string>& value = iterator->second;
-
- if (flags.count(name) > 0) {
- if (value.isSome()) { // --name=value
- if (flags[name].boolean && value.get() == "") {
- flags[name].loader(this, "true"); // Should never fail.
- } else {
- Try<Nothing> loader = flags[name].loader(this, value.get());
- if (loader.isError()) {
- return Error(
- "Failed to load flag '" + name + "': " + loader.error());
- }
- }
- } else { // --name
- if (flags[name].boolean) {
- flags[name].loader(this, "true"); // Should never fail.
- } else {
- return Error(
- "Failed to load non-boolean flag '" + name + "': Missing value");
- }
- }
- } else if (name.find("no-") == 0) {
- if (flags.count(name.substr(3)) > 0) { // --no-name
- if (flags[name.substr(3)].boolean) {
- if (value.isNone() || value.get() == "") {
- flags[name.substr(3)].loader(this, "false"); // Should never fail.
- } else {
- return Error(
- "Failed to load boolean flag '" + name.substr(3) +
- "' via '" + name + "' with value '" + value.get() + "'");
- }
- } else {
- return Error(
- "Failed to load non-boolean flag '" + name.substr(3) +
- "' via '" + name + "'");
- }
- } else {
- return Error(
- "Failed to load unknown flag '" + name.substr(3) +
- "' via '" + name + "'");
- }
- } else if (!unknowns) {
- return Error("Failed to load unknown flag '" + name + "'");
- }
- }
-
- return Nothing();
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const std::map<std::string, std::string>& _values,
- bool unknowns)
-{
- std::map<std::string, Option<std::string> > values;
- std::map<std::string, std::string>::const_iterator iterator;
- for (iterator = _values.begin(); iterator != _values.end(); ++iterator) {
- const std::string& name = iterator->first;
- const std::string& value = iterator->second;
- values[name] = Option<std::string>::some(value);
- }
- return load(values, unknowns);
-}
-
-
-inline std::string FlagsBase::usage() const
-{
- const int PAD = 5;
-
- std::string usage;
-
- std::map<std::string, std::string> col1; // key -> col 1 string
-
- // Construct string for the first column and store width of column.
- size_t width = 0;
-
- foreachvalue (const flags::Flag& flag, *this) {
- if (flag.boolean) {
- col1[flag.name] = " --[no-]" + flag.name;
- } else {
- col1[flag.name] = " --" + flag.name + "=VALUE";
- }
- width = std::max(width, col1[flag.name].size());
- }
-
- foreachvalue (const flags::Flag& flag, *this) {
- std::string line = col1[flag.name];
-
- std::string pad(PAD + width - line.size(), ' ');
- line += pad;
-
- size_t pos1 = 0, pos2 = 0;
- pos2 = flag.help.find_first_of("\n\r", pos1);
- line += flag.help.substr(pos1, pos2 - pos1) + "\n";
- usage += line;
-
- while (pos2 != std::string::npos) { // Handle multi-line help strings.
- line = "";
- pos1 = pos2 + 1;
- std::string pad2(PAD + width, ' ');
- line += pad2;
- pos2 = flag.help.find_first_of("\n\r", pos1);
- line += flag.help.substr(pos1, pos2 - pos1) + "\n";
- usage += line;
- }
- }
- return usage;
-}
-
-} // namespace flags {
-
-#endif // __STOUT_FLAGS_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags/loader.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
deleted file mode 100644
index e5eaf24..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef __STOUT_FLAGS_LOADER_HPP__
-#define __STOUT_FLAGS_LOADER_HPP__
-
-#include <string>
-
-#include <tr1/functional>
-
-#include <stout/error.hpp>
-#include <stout/nothing.hpp>
-#include <stout/option.hpp>
-#include <stout/try.hpp>
-
-#include <stout/flags/parse.hpp>
-
-namespace flags {
-
-// Forward declaration.
-class FlagsBase;
-
-template <typename T>
-struct Loader
-{
- static Try<Nothing> load(
- T* flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- Try<T> t = parse(value);
- if (t.isSome()) {
- *flag = t.get();
- } else {
- return Error("Failed to load value '" + value + "': " + t.error());
- }
- return Nothing();
- }
-};
-
-
-template <typename T>
-struct OptionLoader
-{
- static Try<Nothing> load(
- Option<T>* flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- Try<T> t = parse(value);
- if (t.isSome()) {
- *flag = Option<T>::some(t.get());
- } else {
- return Error("Failed to load value '" + value + "': " + t.error());
- }
- return Nothing();
- }
-};
-
-
-template <typename F, typename T>
-struct MemberLoader
-{
- static Try<Nothing> load(
- FlagsBase* base,
- T F::*flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- F* f = dynamic_cast<F*>(base);
- if (f != NULL) {
- Try<T> t = parse(value);
- if (t.isSome()) {
- f->*flag = t.get();
- } else {
- return Error("Failed to load value '" + value + "': " + t.error());
- }
- }
- return Nothing();
- }
-};
-
-
-template <typename F, typename T>
-struct OptionMemberLoader
-{
- static Try<Nothing> load(
- FlagsBase* base,
- Option<T> F::*flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- F* f = dynamic_cast<F*>(base);
- if (f != NULL) {
- Try<T> t = parse(value);
- if (t.isSome()) {
- f->*flag = Option<T>::some(t.get());
- } else {
- return Error("Failed to load value '" + value + "': " + t.error());
- }
- }
- return Nothing();
- }
-};
-
-} // namespace flags {
-
-#endif // __STOUT_FLAGS_LOADER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags/parse.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
deleted file mode 100644
index 54eb35c..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __STOUT_FLAGS_PARSE_HPP__
-#define __STOUT_FLAGS_PARSE_HPP__
-
-#include <sstream> // For istringstream.
-#include <string>
-
-#include <tr1/functional>
-
-#include <stout/duration.hpp>
-#include <stout/error.hpp>
-#include <stout/try.hpp>
-
-namespace flags {
-
-template <typename T>
-Try<T> parse(const std::string& value)
-{
- T t;
- std::istringstream in(value);
- in >> t;
- if (!in.good() && !in.eof()) {
- return Error("Failed to convert into required type");
- }
- return t;
-}
-
-
-template <>
-inline Try<std::string> parse(const std::string& value)
-{
- return value;
-}
-
-
-template <>
-inline Try<bool> parse(const std::string& value)
-{
- if (value == "true" || value == "1") {
- return true;
- } else if (value == "false" || value == "0") {
- return false;
- }
- return Error("Expecting a boolean (e.g., true or false)");
-}
-
-
-template <>
-inline Try<Duration> parse(const std::string& value)
-{
- return Duration::parse(value);
-}
-
-} // namespace flags {
-
-#endif // __STOUT_FLAGS_PARSE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/3rdparty/stout/include/stout/foreach.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/foreach.hpp b/third_party/libprocess/3rdparty/stout/include/stout/foreach.hpp
deleted file mode 100644
index 0afe285..0000000
--- a/third_party/libprocess/3rdparty/stout/include/stout/foreach.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef __STOUT_FOREACH_HPP__
-#define __STOUT_FOREACH_HPP__
-
-#include <boost/foreach.hpp>
-
-#include <boost/tuple/tuple.hpp>
-
-namespace __foreach__ {
-
-// NOTE: This is a copied from Boost
-// (boost/tuple/detail/tuple_basic_no_partial_spec.hpp) because the
-// new 'boost::tuples::ignore' does not work in our 'foreachkey' and
-// 'foreachvalue'.
-struct swallow_assign {
- template<typename T>
- swallow_assign const& operator=(const T&) const {
- return *this;
- }
-};
-
-swallow_assign const ignore = swallow_assign();
-
-} // namespace __foreach__ {
-
-#define BOOST_FOREACH_PAIR(VARFIRST, VARSECOND, COL) \
- BOOST_FOREACH_PREAMBLE() \
- if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \
- if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else \
- if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_END(COL)) {} else \
- for (bool BOOST_FOREACH_ID(_foreach_continue) = true, BOOST_FOREACH_ID(_foreach_onetime) = true; \
- BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_DONE(COL); \
- BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0) \
- if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_onetime))) {} else \
- for (VARFIRST = BOOST_FOREACH_DEREF(COL).first; \
- !BOOST_FOREACH_ID(_foreach_onetime); \
- BOOST_FOREACH_ID(_foreach_onetime) = true) \
- if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \
- for (VARSECOND = BOOST_FOREACH_DEREF(COL).second; \
- !BOOST_FOREACH_ID(_foreach_continue); \
- BOOST_FOREACH_ID(_foreach_continue) = true)
-
-#define foreach BOOST_FOREACH
-#define foreachpair BOOST_FOREACH_PAIR
-
-#define foreachkey(VAR, COL) \
- foreachpair (VAR, __foreach__::ignore, COL)
-
-#define foreachvalue(VAR, COL) \
- foreachpair (__foreach__::ignore, VAR, COL)
-
-#endif // __STOUT_FOREACH_HPP__
[26/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/gtest.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/gtest.hpp b/3rdparty/libprocess/include/process/gtest.hpp
new file mode 100644
index 0000000..8473452
--- /dev/null
+++ b/3rdparty/libprocess/include/process/gtest.hpp
@@ -0,0 +1,338 @@
+#ifndef __PROCESS_GTEST_HPP__
+#define __PROCESS_GTEST_HPP__
+
+#include <gtest/gtest.h>
+
+#include <string>
+
+#include <process/clock.hpp>
+#include <process/future.hpp>
+#include <process/http.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/option.hpp>
+
+namespace process {
+
+// A simple test event listener that makes sure to resume the clock
+// after each test even if the previous test had a partial result
+// (i.e., an ASSERT_* failed).
+class ClockTestEventListener : public ::testing::EmptyTestEventListener
+{
+public:
+ // Returns the singleton instance of the listener.
+ static ClockTestEventListener* instance()
+ {
+ static ClockTestEventListener* listener = new ClockTestEventListener();
+ return listener;
+ }
+
+ virtual void OnTestEnd(const ::testing::TestInfo&)
+ {
+ if (process::Clock::paused()) {
+ process::Clock::resume();
+ }
+ }
+private:
+ ClockTestEventListener() {}
+};
+
+} // namespace process {
+
+template <typename T>
+::testing::AssertionResult AwaitAssertReady(
+ const char* expr,
+ const char*, // Unused string representation of 'duration'.
+ const process::Future<T>& actual,
+ const Duration& duration)
+{
+ if (!actual.await(duration)) {
+ return ::testing::AssertionFailure()
+ << "Failed to wait " << duration << " for " << expr;
+ } else if (actual.isDiscarded()) {
+ return ::testing::AssertionFailure()
+ << expr << " was discarded";
+ } else if (actual.isFailed()) {
+ return ::testing::AssertionFailure()
+ << "(" << expr << ").failure(): " << actual.failure();
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T>
+::testing::AssertionResult AwaitAssertFailed(
+ const char* expr,
+ const char*, // Unused string representation of 'duration'.
+ const process::Future<T>& actual,
+ const Duration& duration)
+{
+ if (!actual.await(duration)) {
+ return ::testing::AssertionFailure()
+ << "Failed to wait " << duration << " for " << expr;
+ } else if (actual.isDiscarded()) {
+ return ::testing::AssertionFailure()
+ << expr << " was discarded";
+ } else if (actual.isReady()) {
+ return ::testing::AssertionFailure()
+ << expr << " is ready (" << ::testing::PrintToString(actual.get()) << ")";
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T>
+::testing::AssertionResult AwaitAssertDiscarded(
+ const char* expr,
+ const char*, // Unused string representation of 'duration'.
+ const process::Future<T>& actual,
+ const Duration& duration)
+{
+ if (!actual.await(duration)) {
+ return ::testing::AssertionFailure()
+ << "Failed to wait " << duration << " for " << expr;
+ } else if (actual.isFailed()) {
+ return ::testing::AssertionFailure()
+ << "(" << expr << ").failure(): " << actual.failure();
+ } else if (actual.isReady()) {
+ return ::testing::AssertionFailure()
+ << expr << " is ready (" << ::testing::PrintToString(actual.get()) << ")";
+ }
+
+ return ::testing::AssertionSuccess();
+}
+
+
+template <typename T1, typename T2>
+::testing::AssertionResult AwaitAssertEq(
+ const char* expectedExpr,
+ const char* actualExpr,
+ const char* durationExpr,
+ const T1& expected,
+ const process::Future<T2>& actual,
+ const Duration& duration)
+{
+ const ::testing::AssertionResult result =
+ AwaitAssertReady(actualExpr, durationExpr, actual, duration);
+
+ if (result) {
+ if (expected == actual.get()) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Value of: (" << actualExpr << ").get()\n"
+ << " Actual: " << ::testing::PrintToString(actual.get()) << "\n"
+ << "Expected: " << expectedExpr << "\n"
+ << "Which is: " << ::testing::PrintToString(expected);
+ }
+ }
+
+ return result;
+}
+
+
+#define AWAIT_ASSERT_READY_FOR(actual, duration) \
+ ASSERT_PRED_FORMAT2(AwaitAssertReady, actual, duration)
+
+
+#define AWAIT_ASSERT_READY(actual) \
+ AWAIT_ASSERT_READY_FOR(actual, Seconds(5))
+
+
+#define AWAIT_READY_FOR(actual, duration) \
+ AWAIT_ASSERT_READY_FOR(actual, duration)
+
+
+#define AWAIT_READY(actual) \
+ AWAIT_ASSERT_READY(actual)
+
+
+#define AWAIT_EXPECT_READY_FOR(actual, duration) \
+ EXPECT_PRED_FORMAT2(AwaitAssertReady, actual, duration)
+
+
+#define AWAIT_EXPECT_READY(actual) \
+ AWAIT_EXPECT_READY_FOR(actual, Seconds(5))
+
+
+#define AWAIT_ASSERT_FAILED_FOR(actual, duration) \
+ ASSERT_PRED_FORMAT2(AwaitAssertFailed, actual, duration)
+
+
+#define AWAIT_ASSERT_FAILED(actual) \
+ AWAIT_ASSERT_FAILED_FOR(actual, Seconds(5))
+
+
+#define AWAIT_FAILED_FOR(actual, duration) \
+ AWAIT_ASSERT_FAILED_FOR(actual, duration)
+
+
+#define AWAIT_FAILED(actual) \
+ AWAIT_ASSERT_FAILED(actual)
+
+
+#define AWAIT_EXPECT_FAILED_FOR(actual, duration) \
+ EXPECT_PRED_FORMAT2(AwaitAssertFailed, actual, duration)
+
+
+#define AWAIT_EXPECT_FAILED(actual) \
+ AWAIT_EXPECT_FAILED_FOR(actual, Seconds(5))
+
+
+#define AWAIT_ASSERT_DISCARDED_FOR(actual, duration) \
+ ASSERT_PRED_FORMAT2(AwaitAssertDiscarded, actual, duration)
+
+
+#define AWAIT_ASSERT_DISCARDED(actual) \
+ AWAIT_ASSERT_DISCARDED_FOR(actual, Seconds(5))
+
+
+#define AWAIT_DISCARDED_FOR(actual, duration) \
+ AWAIT_ASSERT_DISCARDED_FOR(actual, duration)
+
+
+#define AWAIT_DISCARDED(actual) \
+ AWAIT_ASSERT_DISCARDED(actual)
+
+
+#define AWAIT_EXPECT_DISCARDED_FOR(actual, duration) \
+ EXPECT_PRED_FORMAT2(AwaitAssertDiscarded, actual, duration)
+
+
+#define AWAIT_EXPECT_DISCARDED(actual) \
+ AWAIT_EXPECT_DISCARDED_FOR(actual, Seconds(5))
+
+
+#define AWAIT_ASSERT_EQ_FOR(expected, actual, duration) \
+ ASSERT_PRED_FORMAT3(AwaitAssertEq, expected, actual, duration)
+
+
+#define AWAIT_ASSERT_EQ(expected, actual) \
+ AWAIT_ASSERT_EQ_FOR(expected, actual, Seconds(5))
+
+
+#define AWAIT_EQ(expected, actual) \
+ AWAIT_ASSERT_EQ(expected, actual)
+
+
+#define AWAIT_EXPECT_EQ_FOR(expected, actual, duration) \
+ EXPECT_PRED_FORMAT3(AwaitAssertEq, expected, actual, duration)
+
+
+#define AWAIT_EXPECT_EQ(expected, actual) \
+ AWAIT_EXPECT_EQ_FOR(expected, actual, Seconds(5))
+
+
+inline ::testing::AssertionResult AwaitAssertResponseStatusEq(
+ const char* expectedExpr,
+ const char* actualExpr,
+ const char* durationExpr,
+ const std::string& expected,
+ const process::Future<process::http::Response>& actual,
+ const Duration& duration)
+{
+ const ::testing::AssertionResult result =
+ AwaitAssertReady(actualExpr, durationExpr, actual, duration);
+
+ if (result) {
+ if (expected == actual.get().status) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Value of: (" << actualExpr << ").get().status\n"
+ << " Actual: " << ::testing::PrintToString(actual.get().status) << "\n"
+ << "Expected: " << expectedExpr << "\n"
+ << "Which is: " << ::testing::PrintToString(expected);
+ }
+ }
+
+ return result;
+}
+
+
+#define AWAIT_EXPECT_RESPONSE_STATUS_EQ_FOR(expected, actual, duration) \
+ EXPECT_PRED_FORMAT3(AwaitAssertResponseStatusEq, expected, actual, duration)
+
+
+#define AWAIT_EXPECT_RESPONSE_STATUS_EQ(expected, actual) \
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ_FOR(expected, actual, Seconds(5))
+
+
+inline ::testing::AssertionResult AwaitAssertResponseBodyEq(
+ const char* expectedExpr,
+ const char* actualExpr,
+ const char* durationExpr,
+ const std::string& expected,
+ const process::Future<process::http::Response>& actual,
+ const Duration& duration)
+{
+ const ::testing::AssertionResult result =
+ AwaitAssertReady(actualExpr, durationExpr, actual, duration);
+
+ if (result) {
+ if (expected == actual.get().body) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Value of: (" << actualExpr << ").get().body\n"
+ << " Actual: " << ::testing::PrintToString(actual.get().body) << "\n"
+ << "Expected: " << expectedExpr << "\n"
+ << "Which is: " << ::testing::PrintToString(expected);
+ }
+ }
+
+ return result;
+}
+
+
+#define AWAIT_EXPECT_RESPONSE_BODY_EQ_FOR(expected, actual, duration) \
+ EXPECT_PRED_FORMAT3(AwaitAssertResponseBodyEq, expected, actual, duration)
+
+
+#define AWAIT_EXPECT_RESPONSE_BODY_EQ(expected, actual) \
+ AWAIT_EXPECT_RESPONSE_BODY_EQ_FOR(expected, actual, Seconds(5))
+
+
+inline ::testing::AssertionResult AwaitAssertResponseHeaderEq(
+ const char* expectedExpr,
+ const char* keyExpr,
+ const char* actualExpr,
+ const char* durationExpr,
+ const std::string& expected,
+ const std::string& key,
+ const process::Future<process::http::Response>& actual,
+ const Duration& duration)
+{
+ const ::testing::AssertionResult result =
+ AwaitAssertReady(actualExpr, durationExpr, actual, duration);
+
+ if (result) {
+ const Option<std::string> value = actual.get().headers.get(key);
+ if (value.isNone()) {
+ return ::testing::AssertionFailure()
+ << "Response does not contain header '" << key << "'";
+ } else if (expected == value.get()) {
+ return ::testing::AssertionSuccess();
+ } else {
+ return ::testing::AssertionFailure()
+ << "Value of: (" << actualExpr << ").get().headers[" << keyExpr << "]\n"
+ << " Actual: " << ::testing::PrintToString(value.get()) << "\n"
+ << "Expected: " << expectedExpr << "\n"
+ << "Which is: " << ::testing::PrintToString(expected);
+ }
+ }
+
+ return result;
+}
+
+
+#define AWAIT_EXPECT_RESPONSE_HEADER_EQ_FOR(expected, key, actual, duration) \
+ EXPECT_PRED_FORMAT4(AwaitAssertResponseHeaderEq, expected, key, actual, duration)
+
+
+#define AWAIT_EXPECT_RESPONSE_HEADER_EQ(expected, key, actual) \
+ AWAIT_EXPECT_RESPONSE_HEADER_EQ_FOR(expected, key, actual, Seconds(5))
+
+#endif // __PROCESS_GTEST_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
new file mode 100644
index 0000000..751cfb8
--- /dev/null
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -0,0 +1,468 @@
+#ifndef __PROCESS_HTTP_HPP__
+#define __PROCESS_HTTP_HPP__
+
+#include <cctype>
+#include <cstdlib>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <limits.h>
+
+#include <process/future.hpp>
+#include <process/pid.hpp>
+
+#include <stout/error.hpp>
+#include <stout/hashmap.hpp>
+#include <stout/json.hpp>
+#include <stout/none.hpp>
+#include <stout/option.hpp>
+#include <stout/stringify.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+
+namespace process {
+namespace http {
+
+struct Request
+{
+ // TODO(benh): Add major/minor version.
+ // TODO(bmahler): Header names are not case sensitive! Either make these
+ // case-insensitive, or add a variable for each header in HTTP 1.0/1.1 (like
+ // we've done here with keepAlive).
+ // Tracked by: https://issues.apache.org/jira/browse/MESOS-328.
+ hashmap<std::string, std::string> headers;
+ std::string method;
+ std::string path;
+ std::string url;
+ std::string fragment;
+ hashmap<std::string, std::string> query;
+ std::string body;
+ bool keepAlive;
+
+ // Returns whether the encoding is considered acceptable in the request.
+ // TODO(bmahler): Consider this logic being in decoder.hpp, and having the
+ // Request contain a member variable for each popular HTTP 1.0/1.1 header.
+ bool accepts(const std::string& encoding) const
+ {
+ // See RFC 2616, section 14.3 for the details.
+ Option<std::string> accepted = headers.get("Accept-Encoding");
+
+ if (accepted.isNone()) {
+ return false;
+ }
+
+ // Remove spaces and tabs for easier parsing.
+ accepted = strings::remove(accepted.get(), " ");
+ accepted = strings::remove(accepted.get(), "\t");
+ accepted = strings::remove(accepted.get(), "\n");
+
+ // From RFC 2616:
+ // 1. If the content-coding is one of the content-codings listed in
+ // the Accept-Encoding field, then it is acceptable, unless it is
+ // accompanied by a qvalue of 0. (As defined in section 3.9, a
+ // qvalue of 0 means "not acceptable.")
+ // 2. The special "*" symbol in an Accept-Encoding field matches any
+ // available content-coding not explicitly listed in the header
+ // field.
+
+ // First we'll look for the encoding specified explicitly, then '*'.
+ std::vector<std::string> candidates;
+ candidates.push_back(encoding); // Rule 1.
+ candidates.push_back("*"); // Rule 2.
+
+ foreach (std::string& candidate, candidates) {
+ // Is the candidate one of the accepted encodings?
+ foreach (const std::string& _encoding,
+ strings::tokenize(accepted.get(), ",")) {
+ if (strings::startsWith(_encoding, candidate)) {
+ // Is there a 0 q value? Ex: 'gzip;q=0.0'.
+ const std::map<std::string, std::vector<std::string> >& values =
+ strings::pairs(_encoding, ";", "=");
+
+ // Look for { "q": ["0"] }.
+ if (values.count("q") == 0 || values.find("q")->second.size() != 1) {
+ // No q value, or malformed q value.
+ return true;
+ }
+
+ // Is the q value > 0?
+ Try<double> value = numify<double>(values.find("q")->second[0]);
+ return value.isSome() && value.get() > 0;
+ }
+ }
+ }
+
+ // NOTE: 3 and 4 are partially ignored since we can only provide gzip.
+ // 3. If multiple content-codings are acceptable, then the acceptable
+ // content-coding with the highest non-zero qvalue is preferred.
+ // 4. The "identity" content-coding is always acceptable, unless
+ // specifically refused because the Accept-Encoding field includes
+ // "identity;q=0", or because the field includes "*;q=0" and does
+ // not explicitly include the "identity" content-coding. If the
+ // Accept-Encoding field-value is empty, then only the "identity"
+ // encoding is acceptable.
+ return false;
+ }
+};
+
+
+struct Response
+{
+ Response()
+ : type(NONE)
+ {}
+
+ Response(const std::string& _body)
+ : type(BODY),
+ body(_body)
+ {
+ headers["Content-Length"] = stringify(body.size());
+ }
+
+ // TODO(benh): Add major/minor version.
+ std::string status;
+ hashmap<std::string, std::string> headers;
+
+ // Either provide a "body", an absolute "path" to a file, or a
+ // "pipe" for streaming a response. Distinguish between the cases
+ // using 'type' below.
+ //
+ // BODY: Uses 'body' as the body of the response. These may be
+ // encoded using gzip for efficiency, if 'Content-Encoding' is not
+ // already specified.
+ //
+ // PATH: Attempts to perform a 'sendfile' operation on the file
+ // found at 'path'.
+ //
+ // PIPE: Splices data from 'pipe' using 'Transfer-Encoding=chunked'.
+ // Note that the read end of the pipe will be closed by libprocess
+ // either after the write end has been closed or if the socket the
+ // data is being spliced to has been closed (i.e., nobody is
+ // listening any longer). This can cause writes to the pipe to
+ // generate a SIGPIPE (which will terminate your program unless you
+ // explicitly ignore them or handle them).
+ //
+ // In all cases (BODY, PATH, PIPE), you are expected to properly
+ // specify the 'Content-Type' header, but the 'Content-Length' and
+ // or 'Transfer-Encoding' headers will be filled in for you.
+ enum {
+ NONE,
+ BODY,
+ PATH,
+ PIPE
+ } type;
+
+ std::string body;
+ std::string path;
+ int pipe; // See comment above regarding the semantics for closing.
+};
+
+
+struct OK : Response
+{
+ OK()
+ {
+ status = "200 OK";
+ }
+
+ OK(const char* body) : Response(std::string(body))
+ {
+ status = "200 OK";
+ }
+
+ OK(const std::string& body) : Response(body)
+ {
+ status = "200 OK";
+ }
+
+ OK(const JSON::Value& value, const Option<std::string>& jsonp = None())
+ {
+ type = BODY;
+
+ status = "200 OK";
+
+ std::ostringstream out;
+
+ if (jsonp.isSome()) {
+ out << jsonp.get() << "(";
+ }
+
+ JSON::render(out, value);
+
+ if (jsonp.isSome()) {
+ out << ");";
+ headers["Content-Type"] = "text/javascript";
+ } else {
+ headers["Content-Type"] = "application/json";
+ }
+
+ headers["Content-Length"] = stringify(out.str().size());
+ body = out.str().data();
+ }
+};
+
+
+struct TemporaryRedirect : Response
+{
+ TemporaryRedirect(const std::string& url)
+ {
+ status = "307 Temporary Redirect";
+ headers["Location"] = url;
+ }
+};
+
+
+struct BadRequest : Response
+{
+ BadRequest()
+ {
+ status = "400 Bad Request";
+ }
+
+ BadRequest(const std::string& body)
+ : Response(body)
+ {
+ status = "400 Bad Request";
+ }
+};
+
+
+struct NotFound : Response
+{
+ NotFound()
+ {
+ status = "404 Not Found";
+ }
+
+ NotFound(const std::string& body) : Response(body)
+ {
+ status = "404 Not Found";
+ }
+};
+
+
+struct InternalServerError : Response
+{
+ InternalServerError()
+ {
+ status = "500 Internal Server Error";
+ }
+
+ InternalServerError(const std::string& body) : Response(body)
+ {
+ status = "500 Internal Server Error";
+ }
+};
+
+
+struct ServiceUnavailable : Response
+{
+ ServiceUnavailable()
+ {
+ status = "503 Service Unavailable";
+ }
+
+ ServiceUnavailable(const std::string& body) : Response(body)
+ {
+ status = "503 Service Unavailable";
+ }
+};
+
+
+namespace query {
+
+// Parses an HTTP query string into a map. For example:
+//
+// parse("foo=1;bar=2;baz;foo=3")
+//
+// Would return a map with the following:
+// bar: "2"
+// baz: ""
+// foo: "3"
+//
+// We use the last value for a key for simplicity, since the RFC does not
+// specify how to handle duplicate keys:
+// http://en.wikipedia.org/wiki/Query_string
+// TODO(bmahler): If needed, investigate populating the query map inline
+// for better performance.
+inline hashmap<std::string, std::string> parse(const std::string& query)
+{
+ hashmap<std::string, std::string> result;
+
+ const std::vector<std::string>& tokens = strings::tokenize(query, ";&");
+ foreach (const std::string& token, tokens) {
+ const std::vector<std::string>& pairs = strings::split(token, "=");
+ if (pairs.size() == 2) {
+ result[pairs[0]] = pairs[1];
+ } else if (pairs.size() == 1) {
+ result[pairs[0]] = "";
+ }
+ }
+
+ return result;
+}
+
+} // namespace query {
+
+
+// Returns a percent-encoded string according to RFC 3986.
+// The input string must not already be percent encoded.
+inline std::string encode(const std::string& s)
+{
+ std::ostringstream out;
+
+ foreach (unsigned char c, s) {
+ switch (c) {
+ // Reserved characters.
+ case '$':
+ case '&':
+ case '+':
+ case ',':
+ case '/':
+ case ':':
+ case ';':
+ case '=':
+ case '?':
+ case '@':
+ // Unsafe characters.
+ case ' ':
+ case '"':
+ case '<':
+ case '>':
+ case '#':
+ case '%':
+ case '{':
+ case '}':
+ case '|':
+ case '\\':
+ case '^':
+ case '~':
+ case '[':
+ case ']':
+ case '`':
+ // NOTE: The cast to unsigned int is needed.
+ out << '%' << std::setfill('0') << std::setw(2) << std::hex
+ << std::uppercase << (unsigned int) c;
+ break;
+ default:
+ // ASCII control characters and non-ASCII characters.
+ // NOTE: The cast to unsigned int is needed.
+ if (c < 0x20 || c > 0x7F) {
+ out << '%' << std::setfill('0') << std::setw(2) << std::hex
+ << std::uppercase << (unsigned int) c;
+ } else {
+ out << c;
+ }
+ break;
+ }
+ }
+
+ return out.str();
+}
+
+
+// Decodes a percent-encoded string according to RFC 3986.
+// The input string must not already be decoded.
+// Returns error on the occurrence of a malformed % escape in s.
+inline Try<std::string> decode(const std::string& s)
+{
+ std::ostringstream out;
+
+ for (size_t i = 0; i < s.length(); ++i) {
+ if (s[i] != '%') {
+ out << s[i];
+ continue;
+ }
+
+ // We now expect two more characters: % HEXDIG HEXDIG
+ if (i + 2 >= s.length() || !isxdigit(s[i+1]) || !isxdigit(s[i+2])) {
+ return Error(
+ "Malformed % escape in '" + s + "': '" + s.substr(i, 3) + "'");
+ }
+
+ // Convert from HEXDIG HEXDIG to char value.
+ std::istringstream in(s.substr(i + 1, 2));
+ unsigned long l;
+ in >> std::hex >> l;
+ if (l > UCHAR_MAX) {
+ std::cerr << "Unexpected conversion from hex string: "
+ << s.substr(i + 1, 2) << " to unsigned long: "
+ << l << std::endl;
+ abort();
+ }
+ out << static_cast<unsigned char>(l);
+
+ i += 2;
+ }
+
+ return out.str();
+}
+
+
+// Sends a blocking HTTP GET request to the process with the given upid.
+// Returns the HTTP response from the process, read asynchronously.
+//
+// TODO(bmahler): Have the request sent asynchronously as well.
+// TODO(bmahler): For efficiency, this should properly use the ResponseDecoder
+// on the read stream, rather than parsing the full string response at the end.
+Future<Response> get(
+ const UPID& upid,
+ const std::string& path = "",
+ const std::string& query = "");
+
+
+// Status code reason strings, from the HTTP1.1 RFC:
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
+extern hashmap<uint16_t, std::string> statuses;
+
+
+inline void initialize()
+{
+ statuses[100] = "100 Continue";
+ statuses[101] = "101 Switching Protocols";
+ statuses[200] = "200 OK";
+ statuses[201] = "201 Created";
+ statuses[202] = "202 Accepted";
+ statuses[203] = "203 Non-Authoritative Information";
+ statuses[204] = "204 No Content";
+ statuses[205] = "205 Reset Content";
+ statuses[206] = "206 Partial Content";
+ statuses[300] = "300 Multiple Choices";
+ statuses[301] = "301 Moved Permanently";
+ statuses[302] = "302 Found";
+ statuses[303] = "303 See Other";
+ statuses[304] = "304 Not Modified";
+ statuses[305] = "305 Use Proxy";
+ statuses[307] = "307 Temporary Redirect";
+ statuses[400] = "400 Bad Request";
+ statuses[401] = "401 Unauthorized";
+ statuses[402] = "402 Payment Required";
+ statuses[403] = "403 Forbidden";
+ statuses[404] = "404 Not Found";
+ statuses[405] = "405 Method Not Allowed";
+ statuses[406] = "406 Not Acceptable";
+ statuses[407] = "407 Proxy Authentication Required";
+ statuses[408] = "408 Request Time-out";
+ statuses[409] = "409 Conflict";
+ statuses[410] = "410 Gone";
+ statuses[411] = "411 Length Required";
+ statuses[412] = "412 Precondition Failed";
+ statuses[413] = "413 Request Entity Too Large";
+ statuses[414] = "414 Request-URI Too Large";
+ statuses[415] = "415 Unsupported Media Type";
+ statuses[416] = "416 Requested range not satisfiable";
+ statuses[417] = "417 Expectation Failed";
+ statuses[500] = "500 Internal Server Error";
+ statuses[501] = "501 Not Implemented";
+ statuses[502] = "502 Bad Gateway";
+ statuses[503] = "503 Service Unavailable";
+ statuses[504] = "504 Gateway Time-out";
+ statuses[505] = "505 HTTP Version not supported";
+}
+
+
+} // namespace http {
+} // namespace process {
+
+#endif // __PROCESS_HTTP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/id.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/id.hpp b/3rdparty/libprocess/include/process/id.hpp
new file mode 100644
index 0000000..8c256b9
--- /dev/null
+++ b/3rdparty/libprocess/include/process/id.hpp
@@ -0,0 +1,16 @@
+#ifndef __PROCESS_ID_HPP__
+#define __PROCESS_ID_HPP__
+
+#include <string>
+
+namespace process {
+namespace ID {
+
+// Returns 'prefix(N)' where N represents the number of instances
+// where this prefix has been used to generate an ID.
+std::string generate(const std::string& prefix = "");
+
+} // namespace ID {
+} // namespace process {
+
+#endif // __PROCESS_ID_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/io.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/io.hpp b/3rdparty/libprocess/include/process/io.hpp
new file mode 100644
index 0000000..8cf3244
--- /dev/null
+++ b/3rdparty/libprocess/include/process/io.hpp
@@ -0,0 +1,44 @@
+#ifndef __PROCESS_IO_HPP__
+#define __PROCESS_IO_HPP__
+
+#include <cstring> // For size_t.
+#include <string>
+
+#include <process/future.hpp>
+
+namespace process {
+namespace io {
+
+// Possible events for polling.
+const short READ = 0x01;
+const short WRITE = 0x02;
+
+// Buffered read chunk size. Roughly 16 pages.
+const size_t BUFFERED_READ_SIZE = 16*4096;
+
+// TODO(benh): Add a version which takes multiple file descriptors.
+// Returns the events (a subset of the events specified) that can be
+// performed on the specified file descriptor without blocking.
+Future<short> poll(int fd, short events);
+
+
+// Performs a single non-blocking read by polling on the specified file
+// descriptor until any data can be be read. The future will become ready when
+// some data is read (may be less than that specified by size). A future failure
+// will be returned if an error is detected. If end-of-file is reached, value
+// zero will be returned. Note that the return type of this function differs
+// from the standard 'read'. In particular, this function returns the number of
+// bytes read or zero on end-of-file (an error is indicated by failing the
+// future, thus only a 'size_t' is necessary rather than a 'ssize_t').
+Future<size_t> read(int fd, void* data, size_t size);
+
+
+// Performs a series of asynchronous reads, until EOF is reached.
+// NOTE: When using this, ensure the sender will close the connection
+// so that EOF can be reached.
+Future<std::string> read(int fd);
+
+} // namespace io {
+} // namespace process {
+
+#endif // __PROCESS_IO_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/latch.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/latch.hpp b/3rdparty/libprocess/include/process/latch.hpp
new file mode 100644
index 0000000..5170aa8
--- /dev/null
+++ b/3rdparty/libprocess/include/process/latch.hpp
@@ -0,0 +1,33 @@
+#ifndef __PROCESS_LATCH_HPP__
+#define __PROCESS_LATCH_HPP__
+
+#include <process/pid.hpp>
+
+#include <stout/duration.hpp>
+
+namespace process {
+
+class Latch
+{
+public:
+ Latch();
+ virtual ~Latch();
+
+ bool operator == (const Latch& that) const { return pid == that.pid; }
+ bool operator < (const Latch& that) const { return pid < that.pid; }
+
+ void trigger();
+ bool await(const Duration& duration = Seconds(-1));
+
+private:
+ // Not copyable, not assignable.
+ Latch(const Latch& that);
+ Latch& operator = (const Latch& that);
+
+ bool triggered;
+ UPID pid;
+};
+
+} // namespace process {
+
+#endif // __PROCESS_LATCH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/logging.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/logging.hpp b/3rdparty/libprocess/include/process/logging.hpp
new file mode 100644
index 0000000..cba2fd4
--- /dev/null
+++ b/3rdparty/libprocess/include/process/logging.hpp
@@ -0,0 +1,111 @@
+#ifndef __PROCESS_LOGGING_HPP__
+#define __PROCESS_LOGGING_HPP__
+
+#include <glog/logging.h>
+
+#include <process/delay.hpp>
+#include <process/future.hpp>
+#include <process/http.hpp>
+#include <process/process.hpp>
+#include <process/timeout.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/numify.hpp>
+#include <stout/option.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+namespace process {
+
+class Logging : public Process<Logging>
+{
+public:
+ Logging()
+ : ProcessBase("logging"),
+ original(FLAGS_v)
+ {
+ // Make sure all reads/writes can be done atomically (i.e., to
+ // make sure VLOG(*) statements don't read partial writes).
+ // TODO(benh): Use "atomics" primitives for doing reads/writes of
+ // FLAGS_v anyway to account for proper memory barriers.
+ CHECK(sizeof(FLAGS_v) == sizeof(int32_t));
+ }
+
+ virtual ~Logging() {}
+
+protected:
+ virtual void initialize()
+ {
+ route("/toggle", &This::toggle);
+ }
+
+private:
+ Future<http::Response> toggle(const http::Request& request)
+ {
+ Option<std::string> level = request.query.get("level");
+ Option<std::string> duration = request.query.get("duration");
+
+ if (level.isNone() && duration.isNone()) {
+ return http::OK(stringify(FLAGS_v) + "\n");
+ }
+
+ if (level.isSome() && duration.isNone()) {
+ return http::BadRequest("Expecting 'duration=value' in query.\n");
+ } else if (level.isNone() && duration.isSome()) {
+ return http::BadRequest("Expecting 'level=value' in query.\n");
+ }
+
+ Try<int> v = numify<int>(level.get());
+
+ if (v.isError()) {
+ return http::BadRequest(v.error() + ".\n");
+ }
+
+ if (v.get() < 0) {
+ return http::BadRequest("Invalid level '" + stringify(v.get()) + "'.\n");
+ } else if (v.get() < original) {
+ return http::BadRequest("'" + stringify(v.get()) + "' < original level.\n");
+ }
+
+ Try<Duration> d = Duration::parse(duration.get());
+
+ if (d.isError()) {
+ return http::BadRequest(d.error() + ".\n");
+ }
+
+ // Set the logging level.
+ set(v.get());
+
+ // Start a revert timer (if necessary).
+ if (v.get() != original) {
+ timeout = d.get();
+ delay(timeout.remaining(), this, &This::revert);
+ }
+
+ return http::OK();
+ }
+
+ void set(int v)
+ {
+ if (FLAGS_v != v) {
+ VLOG(FLAGS_v) << "Setting verbose logging level to " << v;
+ FLAGS_v = v;
+ __sync_synchronize(); // Ensure 'FLAGS_v' visible in other threads.
+ }
+ }
+
+ void revert()
+ {
+ if (timeout.remaining() == Seconds(0)) {
+ set(original);
+ }
+ }
+
+ Timeout timeout;
+
+ const int32_t original; // Original value of FLAGS_v.
+};
+
+} // namespace process {
+
+#endif // __PROCESS_LOGGING_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/message.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/message.hpp b/3rdparty/libprocess/include/process/message.hpp
new file mode 100644
index 0000000..c67c5e1
--- /dev/null
+++ b/3rdparty/libprocess/include/process/message.hpp
@@ -0,0 +1,20 @@
+#ifndef __PROCESS_MESSAGE_HPP__
+#define __PROCESS_MESSAGE_HPP__
+
+#include <string>
+
+#include <process/pid.hpp>
+
+namespace process {
+
+struct Message
+{
+ std::string name;
+ UPID from;
+ UPID to;
+ std::string body;
+};
+
+} // namespace process {
+
+#endif // __PROCESS_MESSAGE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/mime.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/mime.hpp b/3rdparty/libprocess/include/process/mime.hpp
new file mode 100644
index 0000000..0abeac1
--- /dev/null
+++ b/3rdparty/libprocess/include/process/mime.hpp
@@ -0,0 +1,145 @@
+#ifndef __PROCESS_MIME_HPP__
+#define __PROCESS_MIME_HPP__
+
+namespace process {
+namespace mime {
+
+extern std::map<std::string, std::string> types;
+
+inline void initialize()
+{
+ // These MIME types were collected via:
+ /*
+ python -c '
+ import mimetypes
+ for extension, type in mimetypes.types_map.iteritems():
+ print "types[\"%s\"] = \"%s\";" % (extension, type)
+ '
+ */
+
+ types[".obj"] = "application/octet-stream";
+ types[".ra"] = "audio/x-pn-realaudio";
+ types[".wsdl"] = "application/xml";
+ types[".dll"] = "application/octet-stream";
+ types[".ras"] = "image/x-cmu-raster";
+ types[".ram"] = "application/x-pn-realaudio";
+ types[".bcpio"] = "application/x-bcpio";
+ types[".sh"] = "application/x-sh";
+ types[".m1v"] = "video/mpeg";
+ types[".xwd"] = "image/x-xwindowdump";
+ types[".doc"] = "application/msword";
+ types[".bmp"] = "image/x-ms-bmp";
+ types[".shar"] = "application/x-shar";
+ types[".js"] = "application/x-javascript";
+ types[".src"] = "application/x-wais-source";
+ types[".dvi"] = "application/x-dvi";
+ types[".aif"] = "audio/x-aiff";
+ types[".ksh"] = "text/plain";
+ types[".dot"] = "application/msword";
+ types[".mht"] = "message/rfc822";
+ types[".p12"] = "application/x-pkcs12";
+ types[".css"] = "text/css";
+ types[".csh"] = "application/x-csh";
+ types[".pwz"] = "application/vnd.ms-powerpoint";
+ types[".pdf"] = "application/pdf";
+ types[".cdf"] = "application/x-netcdf";
+ types[".pl"] = "text/plain";
+ types[".ai"] = "application/postscript";
+ types[".jpe"] = "image/jpeg";
+ types[".jpg"] = "image/jpeg";
+ types[".py"] = "text/x-python";
+ types[".xml"] = "text/xml";
+ types[".jpeg"] = "image/jpeg";
+ types[".ps"] = "application/postscript";
+ types[".gtar"] = "application/x-gtar";
+ types[".xpm"] = "image/x-xpixmap";
+ types[".hdf"] = "application/x-hdf";
+ types[".nws"] = "message/rfc822";
+ types[".tsv"] = "text/tab-separated-values";
+ types[".xpdl"] = "application/xml";
+ types[".p7c"] = "application/pkcs7-mime";
+ types[".eps"] = "application/postscript";
+ types[".ief"] = "image/ief";
+ types[".so"] = "application/octet-stream";
+ types[".xlb"] = "application/vnd.ms-excel";
+ types[".pbm"] = "image/x-portable-bitmap";
+ types[".texinfo"] = "application/x-texinfo";
+ types[".xls"] = "application/vnd.ms-excel";
+ types[".tex"] = "application/x-tex";
+ types[".rtx"] = "text/richtext";
+ types[".html"] = "text/html";
+ types[".aiff"] = "audio/x-aiff";
+ types[".aifc"] = "audio/x-aiff";
+ types[".exe"] = "application/octet-stream";
+ types[".sgm"] = "text/x-sgml";
+ types[".tif"] = "image/tiff";
+ types[".mpeg"] = "video/mpeg";
+ types[".ustar"] = "application/x-ustar";
+ types[".gif"] = "image/gif";
+ types[".ppt"] = "application/vnd.ms-powerpoint";
+ types[".pps"] = "application/vnd.ms-powerpoint";
+ types[".sgml"] = "text/x-sgml";
+ types[".ppm"] = "image/x-portable-pixmap";
+ types[".latex"] = "application/x-latex";
+ types[".bat"] = "text/plain";
+ types[".mov"] = "video/quicktime";
+ types[".ppa"] = "application/vnd.ms-powerpoint";
+ types[".tr"] = "application/x-troff";
+ types[".rdf"] = "application/xml";
+ types[".xsl"] = "application/xml";
+ types[".eml"] = "message/rfc822";
+ types[".nc"] = "application/x-netcdf";
+ types[".sv4cpio"] = "application/x-sv4cpio";
+ types[".bin"] = "application/octet-stream";
+ types[".h"] = "text/plain";
+ types[".tcl"] = "application/x-tcl";
+ types[".wiz"] = "application/msword";
+ types[".o"] = "application/octet-stream";
+ types[".a"] = "application/octet-stream";
+ types[".c"] = "text/plain";
+ types[".wav"] = "audio/x-wav";
+ types[".vcf"] = "text/x-vcard";
+ types[".xbm"] = "image/x-xbitmap";
+ types[".txt"] = "text/plain";
+ types[".au"] = "audio/basic";
+ types[".t"] = "application/x-troff";
+ types[".tiff"] = "image/tiff";
+ types[".texi"] = "application/x-texinfo";
+ types[".oda"] = "application/oda";
+ types[".ms"] = "application/x-troff-ms";
+ types[".rgb"] = "image/x-rgb";
+ types[".me"] = "application/x-troff-me";
+ types[".sv4crc"] = "application/x-sv4crc";
+ types[".qt"] = "video/quicktime";
+ types[".mpa"] = "video/mpeg";
+ types[".mpg"] = "video/mpeg";
+ types[".mpe"] = "video/mpeg";
+ types[".avi"] = "video/x-msvideo";
+ types[".pgm"] = "image/x-portable-graymap";
+ types[".pot"] = "application/vnd.ms-powerpoint";
+ types[".mif"] = "application/x-mif";
+ types[".roff"] = "application/x-troff";
+ types[".htm"] = "text/html";
+ types[".man"] = "application/x-troff-man";
+ types[".etx"] = "text/x-setext";
+ types[".zip"] = "application/zip";
+ types[".movie"] = "video/x-sgi-movie";
+ types[".pyc"] = "application/x-python-code";
+ types[".png"] = "image/png";
+ types[".pfx"] = "application/x-pkcs12";
+ types[".mhtml"] = "message/rfc822";
+ types[".tar"] = "application/x-tar";
+ types[".pnm"] = "image/x-portable-anymap";
+ types[".pyo"] = "application/x-python-code";
+ types[".snd"] = "audio/basic";
+ types[".cpio"] = "application/x-cpio";
+ types[".swf"] = "application/x-shockwave-flash";
+ types[".mp3"] = "audio/mpeg";
+ types[".mp2"] = "audio/mpeg";
+ types[".mp4"] = "video/mp4";
+}
+
+} // } namespace mime {
+} // } namespace process {
+
+#endif // __PROCESS_MIME_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/once.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/once.hpp b/3rdparty/libprocess/include/process/once.hpp
new file mode 100644
index 0000000..e85b382
--- /dev/null
+++ b/3rdparty/libprocess/include/process/once.hpp
@@ -0,0 +1,48 @@
+#ifndef __PROCESS_ONCE_HPP__
+#define __PROCESS_ONCE_HPP__
+
+#include <process/future.hpp>
+
+#include <stout/nothing.hpp>
+
+namespace process {
+
+// Provides a _blocking_ abstraction that's useful for performing a
+// task exactly once.
+class Once
+{
+public:
+ Once() {}
+
+ // Returns true if this Once instance has already transitioned to a
+ // 'done' state (i.e., the action you wanted to perform "once" has
+ // been completed). Note that this BLOCKS until Once::done has been
+ // called.
+ bool once()
+ {
+ if (!outer.set(&inner)) {
+ inner.future().await();
+ return true;
+ }
+
+ return false;
+ }
+
+ // Transitions this Once instance to a 'done' state.
+ void done()
+ {
+ inner.set(Nothing());
+ }
+
+private:
+ // Not copyable, not assignable.
+ Once(const Once& that);
+ Once& operator = (const Once& that);
+
+ Promise<Nothing> inner;
+ Promise<Promise<Nothing>*> outer;
+};
+
+} // namespace process {
+
+#endif // __PROCESS_ONCE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/pid.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/pid.hpp b/3rdparty/libprocess/include/process/pid.hpp
new file mode 100644
index 0000000..5a77dbc
--- /dev/null
+++ b/3rdparty/libprocess/include/process/pid.hpp
@@ -0,0 +1,121 @@
+#ifndef __PROCESS_PID_HPP__
+#define __PROCESS_PID_HPP__
+
+#include <stdint.h>
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+
+namespace process {
+
+// Forward declaration to break cyclic dependencies.
+class ProcessBase;
+
+
+struct UPID
+{
+ UPID()
+ : ip(0), port(0) {}
+
+ UPID(const UPID& that)
+ : id(that.id), ip(that.ip), port(that.port) {}
+
+ UPID(const char* id_, uint32_t ip_, uint16_t port_)
+ : id(id_), ip(ip_), port(port_) {}
+
+ UPID(const std::string& id_, uint32_t ip_, uint16_t port_)
+ : id(id_), ip(ip_), port(port_) {}
+
+ UPID(const char* s);
+
+ UPID(const std::string& s);
+
+ UPID(const ProcessBase& process);
+
+ operator std::string () const;
+
+ operator bool () const
+ {
+ return id != "" && ip != 0 && port != 0;
+ }
+
+ bool operator ! () const
+ {
+ return id == "" && ip == 0 && port == 0;
+ }
+
+ bool operator < (const UPID& that) const
+ {
+ if (this != &that) {
+ if (ip == that.ip && port == that.port)
+ return id < that.id;
+ else if (ip == that.ip && port != that.port)
+ return port < that.port;
+ else
+ return ip < that.ip;
+ }
+
+ return false;
+ }
+
+ bool operator == (const UPID& that) const
+ {
+ if (this != &that) {
+ return (id == that.id &&
+ ip == that.ip &&
+ port == that.port);
+ }
+
+ return true;
+ }
+
+ bool operator != (const UPID& that) const
+ {
+ return !(this->operator == (that));
+ }
+
+ std::string id;
+ uint32_t ip;
+ uint16_t port;
+};
+
+
+template <typename T = ProcessBase>
+struct PID : UPID
+{
+ PID() : UPID() {}
+
+ PID(const T* t) : UPID(static_cast<const ProcessBase&>(*t)) {}
+ PID(const T& t) : UPID(static_cast<const ProcessBase&>(t)) {}
+
+ template <typename Base>
+ operator PID<Base> () const
+ {
+ // Only allow upcasts!
+ T* t = NULL;
+ Base* base = t;
+ (void)base; // Eliminate unused base warning.
+ PID<Base> pid;
+ pid.id = id;
+ pid.ip = ip;
+ pid.port = port;
+ return pid;
+ }
+};
+
+
+// Outputing UPIDs and generating UPIDs using streams.
+std::ostream& operator << (std::ostream&, const UPID&);
+std::istream& operator >> (std::istream&, UPID&);
+
+
+// UPID hash value (for example, to use in Boost's unordered maps).
+std::size_t hash_value(const UPID&);
+
+} // namespace process {
+
+
+
+#endif // __PROCESS_PID_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/process.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/process.hpp b/3rdparty/libprocess/include/process/process.hpp
new file mode 100644
index 0000000..8228e4f
--- /dev/null
+++ b/3rdparty/libprocess/include/process/process.hpp
@@ -0,0 +1,370 @@
+#ifndef __PROCESS_PROCESS_HPP__
+#define __PROCESS_PROCESS_HPP__
+
+#include <stdint.h>
+#include <pthread.h>
+
+#include <map>
+#include <queue>
+
+#include <tr1/functional>
+
+#include <process/clock.hpp>
+#include <process/event.hpp>
+#include <process/filter.hpp>
+#include <process/http.hpp>
+#include <process/message.hpp>
+#include <process/mime.hpp>
+#include <process/pid.hpp>
+#include <process/thread.hpp>
+
+#include <stout/duration.hpp>
+
+namespace process {
+
+class ProcessBase : public EventVisitor
+{
+public:
+ ProcessBase(const std::string& id = "");
+
+ virtual ~ProcessBase();
+
+ UPID self() const { return pid; }
+
+protected:
+ // Invoked when an event is serviced.
+ virtual void serve(const Event& event)
+ {
+ event.visit(this);
+ }
+
+ // Callbacks used to visit (i.e., handle) a specific event.
+ virtual void visit(const MessageEvent& event);
+ virtual void visit(const DispatchEvent& event);
+ virtual void visit(const HttpEvent& event);
+ virtual void visit(const ExitedEvent& event);
+ virtual void visit(const TerminateEvent& event);
+
+ // Invoked when a process gets spawned.
+ virtual void initialize() {}
+
+ // Invoked when a process is terminated (unless visit is overriden).
+ virtual void finalize() {}
+
+ // Invoked when a linked process has exited (see link).
+ virtual void exited(const UPID& pid) {}
+
+ // Invoked when a linked process can no longer be monitored (see link).
+ virtual void lost(const UPID& pid) {}
+
+ // Puts a message at front of queue.
+ void inject(
+ const UPID& from,
+ const std::string& name,
+ const char* data = NULL,
+ size_t length = 0);
+
+ // Sends a message with data to PID.
+ void send(
+ const UPID& to,
+ const std::string& name,
+ const char* data = NULL,
+ size_t length = 0);
+
+ // Links with the specified PID. Linking with a process from within
+ // the same "operating system process" is gauranteed to give you
+ // perfect monitoring of that process. However, linking with a
+ // process on another machine might result in receiving lost
+ // callbacks due to the nature of a distributed environment.
+ UPID link(const UPID& pid);
+
+ // The default visit implementation for message events invokes
+ // installed message handlers, or delegates the message to another
+ // process (a delegate can be installed below but a message handler
+ // always takes precedence over delegating). A message handler is
+ // any function which takes two arguments, the "from" pid and the
+ // message body.
+ typedef std::tr1::function<void(const UPID&, const std::string&)>
+ MessageHandler;
+
+ // Setup a handler for a message.
+ void install(
+ const std::string& name,
+ const MessageHandler& handler)
+ {
+ handlers.message[name] = handler;
+ }
+
+ template <typename T>
+ void install(
+ const std::string& name,
+ void (T::*method)(const UPID&, const std::string&))
+ {
+ // Note that we use dynamic_cast here so a process can use
+ // multiple inheritance if it sees so fit (e.g., to implement
+ // multiple callback interfaces).
+ MessageHandler handler =
+ std::tr1::bind(method,
+ dynamic_cast<T*>(this),
+ std::tr1::placeholders::_1,
+ std::tr1::placeholders::_2);
+ install(name, handler);
+ }
+
+ // Delegate incoming message's with the specified name to pid.
+ void delegate(const std::string& name, const UPID& pid)
+ {
+ delegates[name] = pid;
+ }
+
+ // The default visit implementation for HTTP events invokes
+ // installed HTTP handlers. A HTTP handler is any function which
+ // takes an http::Request object and returns an http::Response.
+ typedef std::tr1::function<Future<http::Response>(const http::Request&)>
+ HttpRequestHandler;
+
+ // Setup a handler for an HTTP request.
+ bool route(
+ const std::string& name,
+ const HttpRequestHandler& handler)
+ {
+ if (name.find('/') != 0) {
+ return false;
+ }
+ handlers.http[name.substr(1)] = handler;
+ return true;
+ }
+
+ template <typename T>
+ bool route(
+ const std::string& name,
+ Future<http::Response> (T::*method)(const http::Request&))
+ {
+ // Note that we use dynamic_cast here so a process can use
+ // multiple inheritance if it sees so fit (e.g., to implement
+ // multiple callback interfaces).
+ HttpRequestHandler handler =
+ std::tr1::bind(method, dynamic_cast<T*>(this),
+ std::tr1::placeholders::_1);
+ return route(name, handler);
+ }
+
+ // Provide the static asset(s) at the specified _absolute_ path for
+ // the specified name. For example, assuming the process named
+ // "server" invoked 'provide("name", "path")' then an HTTP request
+ // for '/server/name' would return the asset found at 'path'. If the
+ // specified path is a directory then an HTTP request for
+ // '/server/name/file' would return the asset found at
+ // '/path/file'. The 'Content-Type' header of the HTTP response will
+ // be set to the specified type given the file extension (you can
+ // manipulate this via the optional 'types' parameter).
+ void provide(
+ const std::string& name,
+ const std::string& path,
+ const std::map<std::string, std::string>& types = mime::types)
+ {
+ // TODO(benh): Check that name is only alphanumeric (i.e., has no
+ // '/') and that path is absolute.
+ Asset asset;
+ asset.path = path;
+ asset.types = types;
+ assets[name] = asset;
+ }
+
+private:
+ friend class SocketManager;
+ friend class ProcessManager;
+ friend class ProcessReference;
+ friend void* schedule(void*);
+
+ // Process states.
+ enum { BOTTOM,
+ READY,
+ RUNNING,
+ BLOCKED,
+ TERMINATING,
+ TERMINATED } state;
+
+ // Mutex protecting internals.
+ // TODO(benh): Consider replacing with a spinlock, on multi-core systems.
+ pthread_mutex_t m;
+ void lock() { pthread_mutex_lock(&m); }
+ void unlock() { pthread_mutex_unlock(&m); }
+
+ // Enqueue the specified message, request, or function call.
+ void enqueue(Event* event, bool inject = false);
+
+ // Queue of received events.
+ std::deque<Event*> events;
+
+ // Delegates for messages.
+ std::map<std::string, UPID> delegates;
+
+ // Handlers for messages and HTTP requests.
+ struct {
+ std::map<std::string, MessageHandler> message;
+ std::map<std::string, HttpRequestHandler> http;
+ } handlers;
+
+ // Definition of a static asset.
+ struct Asset
+ {
+ std::string path;
+ std::map<std::string, std::string> types;
+ };
+
+ // Static assets(s) to provide.
+ std::map<std::string, Asset> assets;
+
+ // Active references.
+ int refs;
+
+ // Process PID.
+ UPID pid;
+};
+
+
+template <typename T>
+class Process : public virtual ProcessBase {
+public:
+ virtual ~Process() {}
+
+ // Returns pid of process; valid even before calling spawn.
+ PID<T> self() const { return PID<T>(dynamic_cast<const T*>(this)); }
+
+protected:
+ // Useful typedefs for dispatch/delay/defer to self()/this.
+ typedef T Self;
+ typedef T This;
+};
+
+
+/**
+ * Initialize the library. Note that libprocess uses Google's glog and
+ * you can specify options for it (e.g., a logging directory) via
+ * environment variables (see the glog documentation for more
+ * information).
+ *
+ * @param delegate process to receive root HTTP requests
+ */
+void initialize(const std::string& delegate = "");
+
+
+/**
+ * Returns the IP address associated with this instance of the
+ * library.
+ */
+uint32_t ip();
+
+
+/**
+ * Returns the port associated with this instance of the library.
+ */
+uint16_t port();
+
+
+/**
+ * Spawn a new process.
+ *
+ * @param process process to be spawned
+ * @param manage boolean whether process should get garbage collected
+ */
+UPID spawn(ProcessBase* process, bool manage = false);
+
+template <typename T>
+PID<T> spawn(T* t, bool manage = false)
+{
+ // We save the pid before spawn is called because it's possible that
+ // the process has already been deleted after spawn returns (e.g.,
+ // if 'manage' is true).
+ PID<T> pid(t);
+
+ if (!spawn(static_cast<ProcessBase*>(t), manage)) {
+ return PID<T>();
+ }
+
+ return pid;
+}
+
+template <typename T>
+PID<T> spawn(T& t, bool manage = false)
+{
+ return spawn(&t, manage);
+}
+
+
+/**
+ * Send a TERMINATE message to a process, injecting the message ahead
+ * of all other messages queued up for that process if requested. Note
+ * that currently terminate only works for local processes (in the
+ * future we plan to make this more explicit via the use of a PID
+ * instead of a UPID).
+ *
+ * @param inject if true message will be put on front of message queue
+ */
+void terminate(const UPID& pid, bool inject = true);
+void terminate(const ProcessBase& process, bool inject = true);
+void terminate(const ProcessBase* process, bool inject = true);
+
+
+/**
+ * Wait for process to exit no more than specified seconds (returns
+ * true if actually waited on a process).
+ *
+ * @param PID id of the process
+ * @param secs max time to wait, 0 implies wait for ever
+ */
+bool wait(const UPID& pid, const Duration& duration = Seconds(-1));
+bool wait(const ProcessBase& process, const Duration& duration = Seconds(-1));
+bool wait(const ProcessBase* process, const Duration& duration = Seconds(-1));
+
+
+/**
+ * Sends a message with data without a return address.
+ *
+ * @param to receiver
+ * @param name message name
+ * @param data data to send (gets copied)
+ * @param length length of data
+ */
+void post(const UPID& to,
+ const std::string& name,
+ const char* data = NULL,
+ size_t length = 0);
+
+
+// Inline implementations of above.
+inline void terminate(const ProcessBase& process, bool inject)
+{
+ terminate(process.self(), inject);
+}
+
+
+inline void terminate(const ProcessBase* process, bool inject)
+{
+ terminate(process->self(), inject);
+}
+
+
+inline bool wait(const ProcessBase& process, const Duration& duration)
+{
+ return process::wait(process.self(), duration); // Explicit to disambiguate.
+}
+
+
+inline bool wait(const ProcessBase* process, const Duration& duration)
+{
+ return process::wait(process->self(), duration); // Explicit to disambiguate.
+}
+
+
+// Per thread process pointer. The extra level of indirection from
+// _process_ to __process__ is used in order to take advantage of the
+// ThreadLocal operators without needing the extra dereference.
+extern ThreadLocal<ProcessBase>* _process_;
+
+#define __process__ (*_process_)
+
+} // namespace process {
+
+#endif // __PROCESS_PROCESS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/profiler.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/profiler.hpp b/3rdparty/libprocess/include/process/profiler.hpp
new file mode 100644
index 0000000..64cf622
--- /dev/null
+++ b/3rdparty/libprocess/include/process/profiler.hpp
@@ -0,0 +1,116 @@
+#ifndef __PROCESS_PROFILER_HPP__
+#define __PROCESS_PROFILER_HPP__
+
+#include <glog/logging.h>
+
+#ifdef HAS_GPERFTOOLS
+#include <gperftools/profiler.h>
+#endif
+
+#include <string>
+
+#include <process/future.hpp>
+#include <process/http.hpp>
+#include <process/process.hpp>
+
+#include <stout/format.hpp>
+#include <stout/os.hpp>
+
+namespace process {
+
+const std::string PROFILE_FILE = "perftools.out";
+
+class Profiler : public Process<Profiler>
+{
+public:
+ Profiler() : ProcessBase("profiler"), started(false) {}
+
+ virtual ~Profiler() {}
+
+protected:
+ virtual void initialize()
+ {
+ route("/start", &Profiler::start);
+ route("/stop", &Profiler::stop);
+ }
+
+private:
+ // HTTP endpoints.
+
+ // Starts the profiler. There are no request parameters.
+ Future<http::Response> start(const http::Request& request)
+ {
+#ifdef HAS_GPERFTOOLS
+ if (os::getenv("LIBPROCESS_ENABLE_PROFILER", false) != "1") {
+ return http::BadRequest(
+ "The profiler is not enabled. To enable the profiler, libprocess "
+ "must be started with LIBPROCESS_ENABLE_PROFILER=1 in the "
+ "environment.\n");
+ }
+
+ if (started) {
+ return http::BadRequest("Profiler already started.\n");
+ }
+
+ LOG(INFO) << "Starting Profiler";
+
+ // WARNING: If using libunwind < 1.0.1, profiling should not be used, as
+ // there are reports of crashes.
+ // WARNING: If using libunwind 1.0.1, profiling should not be turned on
+ // when it's possible for new threads to be created.
+ // This may cause a deadlock. The workaround used in libprocess is described
+ // here:
+ // https://groups.google.com/d/topic/google-perftools/Df10Uy4Djrg/discussion
+ // NOTE: We have not tested this with libunwind > 1.0.1.
+ if (!ProfilerStart(PROFILE_FILE.c_str())) {
+ std::string error =
+ strings::format("Failed to start profiler: %s", strerror(errno)).get();
+ LOG(ERROR) << error;
+ return http::InternalServerError(error);
+ }
+
+ started = true;
+ return http::OK("Profiler started.\n");
+#else
+ return http::BadRequest(
+ "Perftools is disabled. To enable perftools, "
+ "configure libprocess with --enable-perftools.\n");
+#endif
+ }
+
+ // Stops the profiler. There are no request parameters.
+ // This returns the profile output, it will also remain present
+ // in the working directory.
+ Future<http::Response> stop(const http::Request& request)
+ {
+#ifdef HAS_GPERFTOOLS
+ if (!started) {
+ return http::BadRequest("Profiler not running.\n");
+ }
+
+ LOG(INFO) << "Stopping Profiler";
+
+ ProfilerStop();
+
+ http::OK response;
+ response.type = response.PATH;
+ response.path = "perftools.out";
+ response.headers["Content-Type"] = "application/octet-stream";
+ response.headers["Content-Disposition"] =
+ strings::format("attachment; filename=%s", PROFILE_FILE).get();
+
+ started = false;
+ return response;
+#else
+ return http::BadRequest(
+ "Perftools is disabled. To enable perftools, "
+ "configure libprocess with --enable-perftools.\n");
+#endif
+ }
+
+ bool started;
+};
+
+} // namespace process {
+
+#endif // __PROCESS_PROCESS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/protobuf.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/protobuf.hpp b/3rdparty/libprocess/include/process/protobuf.hpp
new file mode 100644
index 0000000..580c87a
--- /dev/null
+++ b/3rdparty/libprocess/include/process/protobuf.hpp
@@ -0,0 +1,415 @@
+#ifndef __PROCESS_PROTOBUF_HPP__
+#define __PROCESS_PROTOBUF_HPP__
+
+#include <glog/logging.h>
+
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>
+
+#include <set>
+#include <vector>
+
+#include <tr1/functional>
+#include <tr1/unordered_map>
+
+#include <process/dispatch.hpp>
+#include <process/process.hpp>
+
+
+// Provides an implementation of process::post that for a protobuf.
+namespace process {
+
+inline void post(const process::UPID& to,
+ const google::protobuf::Message& message)
+{
+ std::string data;
+ message.SerializeToString(&data);
+ post(to, message.GetTypeName(), data.data(), data.size());
+}
+
+} // namespace process {
+
+
+// The rest of this file provides libprocess "support" for using
+// protocol buffers. In particular, this file defines a subclass of
+// Process (ProtobufProcess) that allows you to install protocol
+// buffer handlers in addition to normal message and HTTP
+// handlers. Note that this header file assumes you will be linking
+// against BOTH libprotobuf and libglog.
+
+namespace google { namespace protobuf {
+
+// Type conversions helpful for changing between protocol buffer types
+// and standard C++ types (for parameters).
+template <typename T>
+const T& convert(const T& t)
+{
+ return t;
+}
+
+
+template <typename T>
+std::vector<T> convert(const google::protobuf::RepeatedPtrField<T>& items)
+{
+ std::vector<T> result;
+ for (int i = 0; i < items.size(); i++) {
+ result.push_back(items.Get(i));
+ }
+
+ return result;
+}
+
+}} // namespace google { namespace protobuf {
+
+
+template <typename T>
+class ProtobufProcess : public process::Process<T>
+{
+public:
+ virtual ~ProtobufProcess() {}
+
+protected:
+ virtual void visit(const process::MessageEvent& event)
+ {
+ if (protobufHandlers.count(event.message->name) > 0) {
+ from = event.message->from; // For 'reply'.
+ protobufHandlers[event.message->name](event.message->body);
+ from = process::UPID();
+ } else {
+ process::Process<T>::visit(event);
+ }
+ }
+
+ void send(const process::UPID& to,
+ const google::protobuf::Message& message)
+ {
+ std::string data;
+ message.SerializeToString(&data);
+ process::Process<T>::send(to, message.GetTypeName(),
+ data.data(), data.size());
+ }
+
+ using process::Process<T>::send;
+
+ void reply(const google::protobuf::Message& message)
+ {
+ CHECK(from) << "Attempting to reply without a sender";
+ std::string data;
+ message.SerializeToString(&data);
+ send(from, message);
+ }
+
+ template <typename M>
+ void install(void (T::*method)(const M&))
+ {
+ google::protobuf::Message* m = new M();
+ T* t = static_cast<T*>(this);
+ protobufHandlers[m->GetTypeName()] =
+ std::tr1::bind(&handlerM<M>,
+ t, method,
+ std::tr1::placeholders::_1);
+ delete m;
+ }
+
+ template <typename M>
+ void install(void (T::*method)())
+ {
+ google::protobuf::Message* m = new M();
+ T* t = static_cast<T*>(this);
+ protobufHandlers[m->GetTypeName()] =
+ std::tr1::bind(&handler0,
+ t, method,
+ std::tr1::placeholders::_1);
+ delete m;
+ }
+
+ template <typename M,
+ typename P1, typename P1C>
+ void install(void (T::*method)(P1C),
+ P1 (M::*param1)() const)
+ {
+ google::protobuf::Message* m = new M();
+ T* t = static_cast<T*>(this);
+ protobufHandlers[m->GetTypeName()] =
+ std::tr1::bind(&handler1<M, P1, P1C>,
+ t, method, param1,
+ std::tr1::placeholders::_1);
+ delete m;
+ }
+
+ template <typename M,
+ typename P1, typename P1C,
+ typename P2, typename P2C>
+ void install(void (T::*method)(P1C, P2C),
+ P1 (M::*p1)() const,
+ P2 (M::*p2)() const)
+ {
+ google::protobuf::Message* m = new M();
+ T* t = static_cast<T*>(this);
+ protobufHandlers[m->GetTypeName()] =
+ std::tr1::bind(&handler2<M, P1, P1C, P2, P2C>,
+ t, method, p1, p2,
+ std::tr1::placeholders::_1);
+ delete m;
+ }
+
+ template <typename M,
+ typename P1, typename P1C,
+ typename P2, typename P2C,
+ typename P3, typename P3C>
+ void install(void (T::*method)(P1C, P2C, P3C),
+ P1 (M::*p1)() const,
+ P2 (M::*p2)() const,
+ P3 (M::*p3)() const)
+ {
+ google::protobuf::Message* m = new M();
+ T* t = static_cast<T*>(this);
+ protobufHandlers[m->GetTypeName()] =
+ std::tr1::bind(&handler3<M, P1, P1C, P2, P2C, P3, P3C>,
+ t, method, p1, p2, p3,
+ std::tr1::placeholders::_1);
+ delete m;
+ }
+
+ template <typename M,
+ typename P1, typename P1C,
+ typename P2, typename P2C,
+ typename P3, typename P3C,
+ typename P4, typename P4C>
+ void install(void (T::*method)(P1C, P2C, P3C, P4C),
+ P1 (M::*p1)() const,
+ P2 (M::*p2)() const,
+ P3 (M::*p3)() const,
+ P4 (M::*p4)() const)
+ {
+ google::protobuf::Message* m = new M();
+ T* t = static_cast<T*>(this);
+ protobufHandlers[m->GetTypeName()] =
+ std::tr1::bind(&handler4<M, P1, P1C, P2, P2C, P3, P3C, P4, P4C>,
+ t, method, p1, p2, p3, p4,
+ std::tr1::placeholders::_1);
+ delete m;
+ }
+
+ template <typename M,
+ typename P1, typename P1C,
+ typename P2, typename P2C,
+ typename P3, typename P3C,
+ typename P4, typename P4C,
+ typename P5, typename P5C>
+ void install(void (T::*method)(P1C, P2C, P3C, P4C, P5C),
+ P1 (M::*p1)() const,
+ P2 (M::*p2)() const,
+ P3 (M::*p3)() const,
+ P4 (M::*p4)() const,
+ P5 (M::*p5)() const)
+ {
+ google::protobuf::Message* m = new M();
+ T* t = static_cast<T*>(this);
+ protobufHandlers[m->GetTypeName()] =
+ std::tr1::bind(&handler5<M, P1, P1C, P2, P2C, P3, P3C, P4, P4C, P5, P5C>,
+ t, method, p1, p2, p3, p4, p5,
+ std::tr1::placeholders::_1);
+ delete m;
+ }
+
+ using process::Process<T>::install;
+
+ process::UPID from; // Sender of "current" message, accessible by subclasses.
+
+private:
+ template <typename M>
+ static void handlerM(T* t, void (T::*method)(const M&),
+ const std::string& data)
+ {
+ M m;
+ m.ParseFromString(data);
+ if (m.IsInitialized()) {
+ (t->*method)(m);
+ } else {
+ LOG(WARNING) << "Initialization errors: "
+ << m.InitializationErrorString();
+ }
+ }
+
+ static void handler0(T* t, void (T::*method)(),
+ const std::string& data)
+ {
+ (t->*method)();
+ }
+
+ template <typename M,
+ typename P1, typename P1C>
+ static void handler1(T* t, void (T::*method)(P1C),
+ P1 (M::*p1)() const,
+ const std::string& data)
+ {
+ M m;
+ m.ParseFromString(data);
+ if (m.IsInitialized()) {
+ (t->*method)(google::protobuf::convert((&m->*p1)()));
+ } else {
+ LOG(WARNING) << "Initialization errors: "
+ << m.InitializationErrorString();
+ }
+ }
+
+ template <typename M,
+ typename P1, typename P1C,
+ typename P2, typename P2C>
+ static void handler2(T* t, void (T::*method)(P1C, P2C),
+ P1 (M::*p1)() const,
+ P2 (M::*p2)() const,
+ const std::string& data)
+ {
+ M m;
+ m.ParseFromString(data);
+ if (m.IsInitialized()) {
+ (t->*method)(google::protobuf::convert((&m->*p1)()),
+ google::protobuf::convert((&m->*p2)()));
+ } else {
+ LOG(WARNING) << "Initialization errors: "
+ << m.InitializationErrorString();
+ }
+ }
+
+ template <typename M,
+ typename P1, typename P1C,
+ typename P2, typename P2C,
+ typename P3, typename P3C>
+ static void handler3(T* t, void (T::*method)(P1C, P2C, P3C),
+ P1 (M::*p1)() const,
+ P2 (M::*p2)() const,
+ P3 (M::*p3)() const,
+ const std::string& data)
+ {
+ M m;
+ m.ParseFromString(data);
+ if (m.IsInitialized()) {
+ (t->*method)(google::protobuf::convert((&m->*p1)()),
+ google::protobuf::convert((&m->*p2)()),
+ google::protobuf::convert((&m->*p3)()));
+ } else {
+ LOG(WARNING) << "Initialization errors: "
+ << m.InitializationErrorString();
+ }
+ }
+
+ template <typename M,
+ typename P1, typename P1C,
+ typename P2, typename P2C,
+ typename P3, typename P3C,
+ typename P4, typename P4C>
+ static void handler4(T* t, void (T::*method)(P1C, P2C, P3C, P4C),
+ P1 (M::*p1)() const,
+ P2 (M::*p2)() const,
+ P3 (M::*p3)() const,
+ P4 (M::*p4)() const,
+ const std::string& data)
+ {
+ M m;
+ m.ParseFromString(data);
+ if (m.IsInitialized()) {
+ (t->*method)(google::protobuf::convert((&m->*p1)()),
+ google::protobuf::convert((&m->*p2)()),
+ google::protobuf::convert((&m->*p3)()),
+ google::protobuf::convert((&m->*p4)()));
+ } else {
+ LOG(WARNING) << "Initialization errors: "
+ << m.InitializationErrorString();
+ }
+ }
+
+ template <typename M,
+ typename P1, typename P1C,
+ typename P2, typename P2C,
+ typename P3, typename P3C,
+ typename P4, typename P4C,
+ typename P5, typename P5C>
+ static void handler5(T* t, void (T::*method)(P1C, P2C, P3C, P4C, P5C),
+ P1 (M::*p1)() const,
+ P2 (M::*p2)() const,
+ P3 (M::*p3)() const,
+ P4 (M::*p4)() const,
+ P5 (M::*p5)() const,
+ const std::string& data)
+ {
+ M m;
+ m.ParseFromString(data);
+ if (m.IsInitialized()) {
+ (t->*method)(google::protobuf::convert((&m->*p1)()),
+ google::protobuf::convert((&m->*p2)()),
+ google::protobuf::convert((&m->*p3)()),
+ google::protobuf::convert((&m->*p4)()),
+ google::protobuf::convert((&m->*p5)()));
+ } else {
+ LOG(WARNING) << "Initialization errors: "
+ << m.InitializationErrorString();
+ }
+ }
+
+ typedef std::tr1::function<void(const std::string&)> handler;
+ std::tr1::unordered_map<std::string, handler> protobufHandlers;
+};
+
+
+// Implements a process for sending protobuf "requests" to a process
+// and waiting for a protobuf "response", but uses futures so that
+// this can be done without needing to implement a process.
+template <typename Req, typename Res>
+class ReqResProcess : public ProtobufProcess<ReqResProcess<Req, Res> >
+{
+public:
+ ReqResProcess(const process::UPID& _pid, const Req& _req)
+ : pid(_pid), req(_req)
+ {
+ ProtobufProcess<ReqResProcess<Req, Res> >::template
+ install<Res>(&ReqResProcess<Req, Res>::response);
+ }
+
+ process::Future<Res> run()
+ {
+ // Terminate this process if no one cares about the response
+ // (note, we need to disambiguate the process::terminate).
+ void (*terminate)(const process::UPID&, bool) = &process::terminate;
+ promise.future().onDiscarded(
+ std::tr1::bind(terminate, process::ProcessBase::self(), true));
+
+ ProtobufProcess<ReqResProcess<Req, Res> >::send(pid, req);
+
+ return promise.future();
+ }
+
+private:
+ void response(const Res& res)
+ {
+ promise.set(res);
+ process::terminate(process::ProcessBase::self());
+ }
+
+ const process::UPID pid;
+ const Req req;
+ process::Promise<Res> promise;
+};
+
+
+// Allows you to describe request/response protocols and then use
+// those for sending requests and getting back responses.
+template <typename Req, typename Res>
+struct Protocol
+{
+ process::Future<Res> operator () (
+ const process::UPID& pid,
+ const Req& req) const
+ {
+ // Help debugging by adding some "type constraints".
+ { Req* req = NULL; google::protobuf::Message* m = req; (void)m; }
+ { Res* res = NULL; google::protobuf::Message* m = res; (void)m; }
+
+ ReqResProcess<Req, Res>* process = new ReqResProcess<Req, Res>(pid, req);
+ process::spawn(process, true);
+ return process::dispatch(process, &ReqResProcess<Req, Res>::run);
+ }
+};
+
+#endif // __PROCESS_PROTOBUF_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/run.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/run.hpp b/3rdparty/libprocess/include/process/run.hpp
new file mode 100644
index 0000000..a245b70
--- /dev/null
+++ b/3rdparty/libprocess/include/process/run.hpp
@@ -0,0 +1,80 @@
+#ifndef __PROCESS_RUN_HPP__
+#define __PROCESS_RUN_HPP__
+
+#include <tr1/memory> // TODO(benh): Replace shared_ptr with unique_ptr.
+
+#include <process/process.hpp>
+
+#include <stout/preprocessor.hpp>
+
+namespace process {
+
+namespace internal {
+
+template <typename R>
+class ThunkProcess : public Process<ThunkProcess<R> >
+{
+public:
+ ThunkProcess(std::tr1::shared_ptr<std::tr1::function<R(void)> > _thunk,
+ std::tr1::shared_ptr<Promise<R> > _promise)
+ : thunk(_thunk),
+ promise(_promise) {}
+
+ virtual ~ThunkProcess() {}
+
+protected:
+ virtual void serve(const Event& event)
+ {
+ promise->set((*thunk)());
+ }
+
+private:
+ std::tr1::shared_ptr<std::tr1::function<R(void)> > thunk;
+ std::tr1::shared_ptr<Promise<R> > promise;
+};
+
+} // namespace internal {
+
+
+template <typename R>
+Future<R> run(R (*method)(void))
+{
+ std::tr1::shared_ptr<std::tr1::function<R(void)> > thunk(
+ new std::tr1::function<R(void)>(
+ std::tr1::bind(method)));
+
+ std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
+ Future<R> future = promise->future();
+
+ terminate(spawn(new internal::ThunkProcess<R>(thunk, promise), true));
+
+ return future;
+}
+
+
+#define TEMPLATE(Z, N, DATA) \
+ template <typename R, \
+ ENUM_PARAMS(N, typename P), \
+ ENUM_PARAMS(N, typename A)> \
+ Future<R> run( \
+ R (*method)(ENUM_PARAMS(N, P)), \
+ ENUM_BINARY_PARAMS(N, A, a)) \
+ { \
+ std::tr1::shared_ptr<std::tr1::function<R(void)> > thunk( \
+ new std::tr1::function<R(void)>( \
+ std::tr1::bind(method, ENUM_PARAMS(N, a)))); \
+ \
+ std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>()); \
+ Future<R> future = promise->future(); \
+ \
+ terminate(spawn(new internal::ThunkProcess<R>(thunk, promise), true)); \
+ \
+ return future; \
+ }
+
+ REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
+#undef TEMPLATE
+
+} // namespace process {
+
+#endif // __PROCESS_RUN_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/socket.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/socket.hpp b/3rdparty/libprocess/include/process/socket.hpp
new file mode 100644
index 0000000..669a333
--- /dev/null
+++ b/3rdparty/libprocess/include/process/socket.hpp
@@ -0,0 +1,84 @@
+#ifndef __PROCESS_SOCKET_HPP__
+#define __PROCESS_SOCKET_HPP__
+
+#include <assert.h>
+#include <unistd.h> // For close.
+
+#include <iostream>
+
+#include <stout/nothing.hpp>
+#include <stout/os.hpp>
+#include <stout/try.hpp>
+
+// An abstraction around a socket (file descriptor) that provides
+// reference counting such that the socket is only closed (and thus,
+// has the possiblity of being reused) after there are no more
+// references.
+
+class Socket
+{
+public:
+ Socket()
+ : refs(new int(1)), s(-1) {}
+
+ explicit Socket(int _s)
+ : refs(new int(1)), s(_s) {}
+
+ ~Socket()
+ {
+ cleanup();
+ }
+
+ Socket(const Socket& that)
+ {
+ copy(that);
+ }
+
+ Socket& operator = (const Socket& that)
+ {
+ if (this != &that) {
+ cleanup();
+ copy(that);
+ }
+ return *this;
+ }
+
+ bool operator == (const Socket& that) const
+ {
+ return s == that.s && refs == that.refs;
+ }
+
+ operator int () const
+ {
+ return s;
+ }
+
+private:
+ void copy(const Socket& that)
+ {
+ assert(that.refs > 0);
+ __sync_fetch_and_add(that.refs, 1);
+ refs = that.refs;
+ s = that.s;
+ }
+
+ void cleanup()
+ {
+ assert(refs != NULL);
+ if (__sync_sub_and_fetch(refs, 1) == 0) {
+ delete refs;
+ if (s >= 0) {
+ Try<Nothing> close = os::close(s);
+ if (close.isError()) {
+ std::cerr << "Failed to close socket: " << close.error() << std::endl;
+ abort();
+ }
+ }
+ }
+ }
+
+ int* refs;
+ int s;
+};
+
+#endif // __PROCESS_SOCKET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/statistics.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/statistics.hpp b/3rdparty/libprocess/include/process/statistics.hpp
new file mode 100644
index 0000000..fbae641
--- /dev/null
+++ b/3rdparty/libprocess/include/process/statistics.hpp
@@ -0,0 +1,160 @@
+#ifndef __PROCESS_STATISTICS_HPP__
+#define __PROCESS_STATISTICS_HPP__
+
+#include <process/clock.hpp>
+#include <process/future.hpp>
+#include <process/time.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/owned.hpp>
+
+namespace process {
+
+// Forward declarations.
+class Statistics;
+class StatisticsProcess;
+
+namespace meters {
+ class Meter;
+ class TimeRate;
+}
+
+
+// Libprocess statistics handle.
+// To be used from anywhere to manage statistics.
+//
+// Ex: process::statistics->increment("http", "num_requests");
+// process::statistics->set("http", "response_size", response.size());
+//
+// Statistics are exposed via JSON for external visibility.
+extern Statistics* statistics;
+
+const Duration STATISTICS_TRUNCATION_INTERVAL = Minutes(5);
+
+// Provides an in-memory time series of statistics over some window
+// (values are truncated outside of the window, but no limit is
+// currently placed on the number of values within a window).
+//
+// TODO(bmahler): Time series granularity should be coarsened over
+// time. This means, for high-frequency statistics, we keep a lot of
+// recent data points (fine granularity), and keep fewer older data
+// points (coarse granularity). The tunable bit here could be the
+// total number of data points to keep around, which informs how
+// often to delete older data points, while still keeping a window
+// worth of data.
+class Statistics
+{
+public:
+ Statistics(const Duration& window);
+ ~Statistics();
+
+ // Returns the time series of a statistic.
+ process::Future<std::map<Time, double> > timeseries(
+ const std::string& context,
+ const std::string& name,
+ const Option<Time>& start = None(),
+ const Option<Time>& stop = None());
+
+ // Returns the latest value of a statistic.
+ process::Future<Option<double> > get(
+ const std::string& context,
+ const std::string& name);
+
+ // Returns the latest values of all statistics in the context.
+ process::Future<std::map<std::string, double> > get(
+ const std::string& context);
+
+ // Adds a meter for the statistic with the provided context and name.
+ // get(context, meter->name) will return the metered time series.
+ // Returns an error if:
+ // -meter->name == name, or
+ // -The meter already exists.
+ Future<Try<Nothing> > meter(
+ const std::string& context,
+ const std::string& name,
+ Owned<meters::Meter> meter);
+
+ // Sets the current value of a statistic at the current clock time
+ // or at a specified time.
+ void set(
+ const std::string& context,
+ const std::string& name,
+ double value,
+ const Time& time = Clock::now());
+
+ // Archives the provided statistic time series, and any meters associated
+ // with it. This means three things:
+ // 1. The statistic will no longer be part of the snapshot.
+ // 2. However, the time series will be retained until the window expiration.
+ // 3. All meters associated with this statistic will be removed, both
+ // (1) and (2) will apply to the metered time series as well.
+ void archive(const std::string& context, const std::string& name);
+
+ // Increments the current value of a statistic. If no statistic was
+ // previously present, an initial value of 0.0 is used.
+ void increment(const std::string& context, const std::string& name);
+
+ // Decrements the current value of a statistic. If no statistic was
+ // previously present, an initial value of 0.0 is used.
+ void decrement(const std::string& context, const std::string& name);
+
+private:
+ StatisticsProcess* process;
+};
+
+
+namespace meters {
+
+// This is the interface for statistical meters.
+// Meters provide additional metering on top of the raw statistical
+// value. Ex: Track the maximum, average, rate, etc.
+class Meter
+{
+protected:
+ Meter(const std::string& _name) : name(_name) {}
+
+public:
+ virtual ~Meter() {}
+
+ // Updates the meter with another input value.
+ // Returns the new metered value, or none if no metered value can be produced.
+ virtual Option<double> update(const Time& time, double value) = 0;
+
+ const std::string name;
+};
+
+
+// Tracks the percent of time 'used' since the last update.
+// Input values to this meter must be in seconds.
+class TimeRate : public Meter
+{
+public:
+ TimeRate(const std::string& name)
+ : Meter(name), time(None()), value(0) {}
+
+ virtual ~TimeRate() {}
+
+ virtual Option<double> update(const Time& _time, double _value)
+ {
+ Option<double> rate;
+ if (time.isSome()) {
+ rate = (_value - value) / (_time - time.get()).secs();
+ }
+
+ time = _time;
+ value = _value;
+ return rate;
+ }
+
+private:
+ Option<Time> time;
+ double value;
+};
+
+} // namespace meters {
+} // namespace process {
+
+#endif // __PROCESS_STATISTICS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/thread.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/thread.hpp b/3rdparty/libprocess/include/process/thread.hpp
new file mode 100644
index 0000000..3e3b5d2
--- /dev/null
+++ b/3rdparty/libprocess/include/process/thread.hpp
@@ -0,0 +1,49 @@
+#ifndef __PROCESS_THREAD_HPP__
+#define __PROCESS_THREAD_HPP__
+
+#include <pthread.h>
+#include <stdio.h> // For perror.
+#include <stdlib.h> // For abort.
+
+template <typename T>
+struct ThreadLocal
+{
+ ThreadLocal()
+ {
+ if (pthread_key_create(&key, NULL) != 0) {
+ perror("Failed to create thread local, pthread_key_create");
+ abort();
+ }
+ }
+
+ ThreadLocal<T>& operator = (T* t)
+ {
+ if (pthread_setspecific(key, t) != 0) {
+ perror("Failed to set thread local, pthread_setspecific");
+ abort();
+ }
+ return *this;
+ }
+
+ operator T* () const
+ {
+ return reinterpret_cast<T*>(pthread_getspecific(key));
+ }
+
+ T* operator -> () const
+ {
+ return reinterpret_cast<T*>(pthread_getspecific(key));
+ }
+
+private:
+ // Not expecting any other operators to be used (and the rest?).
+ bool operator * (const ThreadLocal<T>&) const;
+ bool operator == (const ThreadLocal<T>&) const;
+ bool operator != (const ThreadLocal<T>&) const;
+ bool operator < (const ThreadLocal<T>&) const;
+ bool operator > (const ThreadLocal<T>&) const;
+
+ pthread_key_t key;
+};
+
+#endif // __PROCESS_THREAD_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/time.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/time.hpp b/3rdparty/libprocess/include/process/time.hpp
new file mode 100644
index 0000000..307fd2c
--- /dev/null
+++ b/3rdparty/libprocess/include/process/time.hpp
@@ -0,0 +1,124 @@
+#ifndef __PROCESS_TIME_HPP__
+#define __PROCESS_TIME_HPP__
+
+#include <iomanip>
+
+#include <glog/logging.h>
+
+#include <stout/duration.hpp>
+
+namespace process {
+
+// Represents an instant in time.
+class Time
+{
+public:
+ // Constructs a time at the Epoch. It is needed because collections
+ // (e.g., std::map) require a default constructor to construct
+ // empty values.
+ Time() : sinceEpoch(Duration::zero()) {}
+
+ static Time EPOCH;
+ static Time MAX;
+
+ static Try<Time> create(double secs)
+ {
+ Try<Duration> duration = Duration::create(secs);
+ if (duration.isSome()) {
+ return Time(duration.get());
+ } else {
+ return Error("Argument too large for Time: " + duration.error());
+ }
+ }
+
+ Duration duration() const { return sinceEpoch; }
+
+ double secs() const { return sinceEpoch.secs(); }
+
+ bool operator < (const Time& t) const { return sinceEpoch < t.sinceEpoch; }
+ bool operator <= (const Time& t) const { return sinceEpoch <= t.sinceEpoch; }
+ bool operator > (const Time& t) const { return sinceEpoch > t.sinceEpoch; }
+ bool operator >= (const Time& t) const { return sinceEpoch >= t.sinceEpoch; }
+ bool operator == (const Time& t) const { return sinceEpoch == t.sinceEpoch; }
+ bool operator != (const Time& t) const { return sinceEpoch != t.sinceEpoch; }
+
+ Time& operator += (const Duration& d)
+ {
+ sinceEpoch += d;
+ return *this;
+ }
+
+ Time& operator -= (const Duration& d)
+ {
+ sinceEpoch -= d;
+ return *this;
+ }
+
+ Duration operator - (const Time& that) const
+ {
+ return sinceEpoch - that.sinceEpoch;
+ }
+
+ Time operator + (const Duration& duration) const
+ {
+ Time new_ = *this;
+ new_ += duration;
+ return new_;
+ }
+
+ Time operator - (const Duration& duration) const
+ {
+ Time new_ = *this;
+ new_ -= duration;
+ return new_;
+ }
+
+private:
+ Duration sinceEpoch;
+
+ // Made it private to avoid the confusion between Time and Duration.
+ // Users should explicitly use Clock::now() and Time::create() to
+ // create a new time instance.
+ Time(const Duration& _sinceEpoch) : sinceEpoch(_sinceEpoch) {}
+};
+
+
+// Outputs the time in RFC 3339 Format.
+inline std::ostream& operator << (std::ostream& stream, const Time& time)
+{
+ // Round down the secs to use it with strftime and then append the
+ // fraction part.
+ long secs = static_cast<long>(time.secs());
+ char date[64];
+
+ // The RFC 3339 Format.
+ tm* tm_ = gmtime(&secs);
+ if (tm_ == NULL) {
+ LOG(ERROR) << "Cannot convert the 'time' to a tm struct using gmtime(): "
+ << errno;
+ return stream;
+ }
+
+ strftime(date, 64, "%Y-%m-%d %H:%M:%S", tm_);
+ stream << date;
+
+ // Append the fraction part in nanoseconds.
+ int64_t nsecs = (time.duration() - Seconds(secs)).ns();
+
+ if (nsecs != 0) {
+ char prev = stream.fill();
+
+ // 9 digits for nanosecond level precision.
+ stream << "." << std::setfill('0') << std::setw(9) << nsecs;
+
+ // Return the stream to original formatting state.
+ stream.fill(prev);
+ }
+
+ stream << "+00:00";
+ return stream;
+}
+
+} // namespace process {
+
+#endif // __PROCESS_TIME_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/3rdparty/libprocess/include/process/timeout.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/timeout.hpp b/3rdparty/libprocess/include/process/timeout.hpp
new file mode 100644
index 0000000..4634b9f
--- /dev/null
+++ b/3rdparty/libprocess/include/process/timeout.hpp
@@ -0,0 +1,84 @@
+#ifndef __PROCESS_TIMEOUT_HPP__
+#define __PROCESS_TIMEOUT_HPP__
+
+#include <process/process.hpp>
+
+#include <process/time.hpp>
+
+#include <stout/duration.hpp>
+
+
+namespace process {
+
+class Timeout
+{
+public:
+ Timeout() : timeout(Clock::now()) {}
+
+ Timeout(const Time& time) : timeout(time) {}
+
+ Timeout(const Timeout& that) : timeout(that.timeout) {}
+
+ // Constructs a Timeout instance from a Time that is the 'duration'
+ // from now.
+ static Timeout in(const Duration& duration)
+ {
+ return Timeout(Clock::now() + duration);
+ }
+
+ Timeout& operator = (const Timeout& that)
+ {
+ if (this != &that) {
+ timeout = that.timeout;
+ }
+
+ return *this;
+ }
+
+ Timeout& operator = (const Duration& duration)
+ {
+ timeout = Clock::now() + duration;
+ return *this;
+ }
+
+ bool operator == (const Timeout& that) const
+ {
+ return timeout == that.timeout;
+ }
+
+ bool operator < (const Timeout& that) const
+ {
+ return timeout < that.timeout;
+ }
+
+ bool operator <= (const Timeout& that) const
+ {
+ return timeout <= that.timeout;
+ }
+
+ // Returns the value of the timeout as a Time object.
+ Time time() const
+ {
+ return timeout;
+ }
+
+ // Returns the amount of time remaining.
+ Duration remaining() const
+ {
+ Duration remaining = timeout - Clock::now();
+ return remaining > Duration::zero() ? remaining : Duration::zero();
+ }
+
+ // Returns true if the timeout expired.
+ bool expired() const
+ {
+ return timeout <= Clock::now();
+ }
+
+private:
+ Time timeout;
+};
+
+} // namespace process {
+
+#endif // __PROCESS_TIMEOUT_HPP__
[07/35] git commit: Updated libprocess to use '3rdparty' instead of
'third_party'.
Posted by be...@apache.org.
Updated libprocess to use '3rdparty' instead of 'third_party'.
Review: https://reviews.apache.org/r/11469
Project: http://git-wip-us.apache.org/repos/asf/incubator-mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mesos/commit/bc531d3c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mesos/tree/bc531d3c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mesos/diff/bc531d3c
Branch: refs/heads/master
Commit: bc531d3c5b01e76f05143f538172174a1b1b35e1
Parents: 6ff3edf
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 26 23:47:55 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:18:39 2013 -0700
----------------------------------------------------------------------
third_party/libprocess/3rdparty/Makefile.am | 170 +++
.../libprocess/3rdparty/boost-1.53.0.tar.gz | Bin 0 -> 988528 bytes
third_party/libprocess/3rdparty/glog-0.3.1.tar.gz | Bin 0 -> 1018372 bytes
third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz | Bin 0 -> 1798225 bytes
.../libprocess/3rdparty/gperftools-2.0.tar.gz | Bin 0 -> 1261243 bytes
third_party/libprocess/3rdparty/libev-4.15.patch | 11 +
third_party/libprocess/3rdparty/libev-4.15.tar.gz | Bin 0 -> 513919 bytes
.../libprocess/3rdparty/protobuf-2.4.1.tar.gz | Bin 0 -> 1935301 bytes
.../3rdparty/ry-http-parser-1c3624a.tar.gz | Bin 0 -> 24625 bytes
third_party/libprocess/3rdparty/stout/LICENSE | 177 +++
third_party/libprocess/3rdparty/stout/Makefile.am | 61 +
third_party/libprocess/3rdparty/stout/README | 32 +
third_party/libprocess/3rdparty/stout/bootstrap | 11 +
third_party/libprocess/3rdparty/stout/configure.ac | 14 +
.../3rdparty/stout/include/stout/bytes.hpp | 160 +++
.../3rdparty/stout/include/stout/cache.hpp | 131 ++
.../3rdparty/stout/include/stout/duration.hpp | 297 ++++
.../3rdparty/stout/include/stout/error.hpp | 72 +
.../3rdparty/stout/include/stout/exit.hpp | 37 +
.../3rdparty/stout/include/stout/fatal.hpp | 43 +
.../3rdparty/stout/include/stout/flags.hpp | 70 +
.../3rdparty/stout/include/stout/flags/flag.hpp | 26 +
.../3rdparty/stout/include/stout/flags/flags.hpp | 481 +++++++
.../3rdparty/stout/include/stout/flags/loader.hpp | 109 ++
.../3rdparty/stout/include/stout/flags/parse.hpp | 55 +
.../3rdparty/stout/include/stout/foreach.hpp | 51 +
.../3rdparty/stout/include/stout/format.hpp | 343 +++++
.../libprocess/3rdparty/stout/include/stout/fs.hpp | 53 +
.../3rdparty/stout/include/stout/gtest.hpp | 122 ++
.../3rdparty/stout/include/stout/gzip.hpp | 149 ++
.../3rdparty/stout/include/stout/hashmap.hpp | 102 ++
.../3rdparty/stout/include/stout/hashset.hpp | 57 +
.../3rdparty/stout/include/stout/json.hpp | 202 +++
.../3rdparty/stout/include/stout/lambda.hpp | 14 +
.../3rdparty/stout/include/stout/multihashmap.hpp | 109 ++
.../3rdparty/stout/include/stout/multimap.hpp | 107 ++
.../3rdparty/stout/include/stout/net.hpp | 102 ++
.../3rdparty/stout/include/stout/none.hpp | 56 +
.../3rdparty/stout/include/stout/nothing.hpp | 6 +
.../3rdparty/stout/include/stout/numify.hpp | 40 +
.../3rdparty/stout/include/stout/option.hpp | 85 ++
.../libprocess/3rdparty/stout/include/stout/os.hpp | 1081 +++++++++++++++
.../3rdparty/stout/include/stout/owned.hpp | 20 +
.../3rdparty/stout/include/stout/path.hpp | 76 +
.../3rdparty/stout/include/stout/preprocessor.hpp | 29 +
.../3rdparty/stout/include/stout/proc.hpp | 478 +++++++
.../3rdparty/stout/include/stout/protobuf.hpp | 159 +++
.../3rdparty/stout/include/stout/result.hpp | 99 ++
.../3rdparty/stout/include/stout/stopwatch.hpp | 70 +
.../3rdparty/stout/include/stout/stringify.hpp | 124 ++
.../3rdparty/stout/include/stout/strings.hpp | 263 ++++
.../3rdparty/stout/include/stout/try.hpp | 88 ++
.../3rdparty/stout/include/stout/utils.hpp | 11 +
.../3rdparty/stout/include/stout/uuid.hpp | 54 +
third_party/libprocess/3rdparty/stout/install-sh | 520 +++++++
.../libprocess/3rdparty/stout/m4/acx_pthread.m4 | 363 +++++
.../3rdparty/stout/tests/bytes_tests.cpp | 38 +
.../3rdparty/stout/tests/duration_tests.cpp | 82 ++
.../3rdparty/stout/tests/error_tests.cpp | 60 +
.../3rdparty/stout/tests/flags_tests.cpp | 349 +++++
.../libprocess/3rdparty/stout/tests/gzip_tests.cpp | 53 +
.../3rdparty/stout/tests/hashset_tests.cpp | 25 +
.../libprocess/3rdparty/stout/tests/json_tests.cpp | 19 +
.../libprocess/3rdparty/stout/tests/main.cpp | 11 +
.../3rdparty/stout/tests/multimap_tests.cpp | 168 +++
.../libprocess/3rdparty/stout/tests/none_tests.cpp | 59 +
.../libprocess/3rdparty/stout/tests/os_tests.cpp | 208 +++
.../libprocess/3rdparty/stout/tests/proc_tests.cpp | 162 +++
.../3rdparty/stout/tests/strings_tests.cpp | 255 ++++
.../libprocess/3rdparty/stout/tests/uuid_tests.cpp | 37 +
third_party/libprocess/3rdparty/versions.am | 11 +
third_party/libprocess/Makefile.am | 26 +-
third_party/libprocess/configure.ac | 12 +-
third_party/libprocess/third_party/Makefile.am | 170 ---
.../libprocess/third_party/boost-1.53.0.tar.gz | Bin 988528 -> 0 bytes
.../libprocess/third_party/glog-0.3.1.tar.gz | Bin 1018372 -> 0 bytes
.../libprocess/third_party/gmock-1.6.0.tar.gz | Bin 1798225 -> 0 bytes
.../libprocess/third_party/gperftools-2.0.tar.gz | Bin 1261243 -> 0 bytes
.../libprocess/third_party/libev-4.15.patch | 11 -
.../libprocess/third_party/libev-4.15.tar.gz | Bin 513919 -> 0 bytes
.../libprocess/third_party/protobuf-2.4.1.tar.gz | Bin 1935301 -> 0 bytes
.../third_party/ry-http-parser-1c3624a.tar.gz | Bin 24625 -> 0 bytes
third_party/libprocess/third_party/stout/LICENSE | 177 ---
.../libprocess/third_party/stout/Makefile.am | 61 -
third_party/libprocess/third_party/stout/README | 32 -
third_party/libprocess/third_party/stout/bootstrap | 11 -
.../libprocess/third_party/stout/configure.ac | 14 -
.../third_party/stout/include/stout/bytes.hpp | 160 ---
.../third_party/stout/include/stout/cache.hpp | 131 --
.../third_party/stout/include/stout/duration.hpp | 297 ----
.../third_party/stout/include/stout/error.hpp | 72 -
.../third_party/stout/include/stout/exit.hpp | 37 -
.../third_party/stout/include/stout/fatal.hpp | 43 -
.../third_party/stout/include/stout/flags.hpp | 70 -
.../third_party/stout/include/stout/flags/flag.hpp | 26 -
.../stout/include/stout/flags/flags.hpp | 481 -------
.../stout/include/stout/flags/loader.hpp | 109 --
.../stout/include/stout/flags/parse.hpp | 55 -
.../third_party/stout/include/stout/foreach.hpp | 51 -
.../third_party/stout/include/stout/format.hpp | 343 -----
.../third_party/stout/include/stout/fs.hpp | 53 -
.../third_party/stout/include/stout/gtest.hpp | 122 --
.../third_party/stout/include/stout/gzip.hpp | 149 --
.../third_party/stout/include/stout/hashmap.hpp | 102 --
.../third_party/stout/include/stout/hashset.hpp | 57 -
.../third_party/stout/include/stout/json.hpp | 202 ---
.../third_party/stout/include/stout/lambda.hpp | 14 -
.../stout/include/stout/multihashmap.hpp | 109 --
.../third_party/stout/include/stout/multimap.hpp | 107 --
.../third_party/stout/include/stout/net.hpp | 102 --
.../third_party/stout/include/stout/none.hpp | 56 -
.../third_party/stout/include/stout/nothing.hpp | 6 -
.../third_party/stout/include/stout/numify.hpp | 40 -
.../third_party/stout/include/stout/option.hpp | 85 --
.../third_party/stout/include/stout/os.hpp | 1081 ---------------
.../third_party/stout/include/stout/owned.hpp | 20 -
.../third_party/stout/include/stout/path.hpp | 76 -
.../stout/include/stout/preprocessor.hpp | 29 -
.../third_party/stout/include/stout/proc.hpp | 478 -------
.../third_party/stout/include/stout/protobuf.hpp | 159 ---
.../third_party/stout/include/stout/result.hpp | 99 --
.../third_party/stout/include/stout/stopwatch.hpp | 70 -
.../third_party/stout/include/stout/stringify.hpp | 124 --
.../third_party/stout/include/stout/strings.hpp | 263 ----
.../third_party/stout/include/stout/try.hpp | 88 --
.../third_party/stout/include/stout/utils.hpp | 11 -
.../third_party/stout/include/stout/uuid.hpp | 54 -
.../libprocess/third_party/stout/install-sh | 520 -------
.../libprocess/third_party/stout/m4/acx_pthread.m4 | 363 -----
.../third_party/stout/tests/bytes_tests.cpp | 38 -
.../third_party/stout/tests/duration_tests.cpp | 82 --
.../third_party/stout/tests/error_tests.cpp | 60 -
.../third_party/stout/tests/flags_tests.cpp | 349 -----
.../third_party/stout/tests/gzip_tests.cpp | 53 -
.../third_party/stout/tests/hashset_tests.cpp | 25 -
.../third_party/stout/tests/json_tests.cpp | 19 -
.../libprocess/third_party/stout/tests/main.cpp | 11 -
.../third_party/stout/tests/multimap_tests.cpp | 168 ---
.../third_party/stout/tests/none_tests.cpp | 59 -
.../third_party/stout/tests/os_tests.cpp | 208 ---
.../third_party/stout/tests/proc_tests.cpp | 162 ---
.../third_party/stout/tests/strings_tests.cpp | 255 ----
.../third_party/stout/tests/uuid_tests.cpp | 37 -
third_party/libprocess/third_party/versions.am | 11 -
144 files changed, 8546 insertions(+), 8546 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/Makefile.am b/third_party/libprocess/3rdparty/Makefile.am
new file mode 100644
index 0000000..20599ec
--- /dev/null
+++ b/third_party/libprocess/3rdparty/Makefile.am
@@ -0,0 +1,170 @@
+# This Makefile is for building third-party packages from
+# tarballs. For autotools-based packages, we configure each of the
+# packages to build static PIC binaries which we can safely link into
+# a shared libmesos, and build it in-place without installing it (even
+# if one runs 'make install' in this directory). Non-autotools based
+# packages may be special cases; this Makefile is responsible for
+# passing any special make or configure flags that might be required.
+
+SUBDIRS = stout
+
+BUILT_SOURCES = # Initialized to enable using +=.
+
+# We need to add '--srcdir=.' needed because 'make distcheck' adds
+# '--srcdir=...' when configuring.
+CONFIGURE_ARGS = @CONFIGURE_ARGS@ --enable-shared=no --with-pic --srcdir=.
+
+include versions.am
+
+STOUT = stout
+BOOST = boost-$(BOOST_VERSION)
+GLOG = glog-$(GLOG_VERSION)
+GMOCK = gmock-$(GMOCK_VERSION)
+GPERFTOOLS = gperftools-$(GPERFTOOLS_VERSION)
+GTEST = $(GMOCK)/gtest
+RY_HTTP_PARSER = ry-http-parser-$(RY_HTTP_PARSER_VERSION)
+LIBEV = libev-$(LIBEV_VERSION)
+PROTOBUF = protobuf-$(PROTOBUF_VERSION)
+
+
+EXTRA_DIST = \
+ $(BOOST).tar.gz \
+ $(GLOG).tar.gz \
+ $(GMOCK).tar.gz \
+ $(GPERFTOOLS).tar.gz \
+ $(LIBEV).tar.gz \
+ $(LIBEV).patch \
+ $(PROTOBUF).tar.gz \
+ $(RY_HTTP_PARSER).tar.gz
+
+CLEAN_EXTRACTED = \
+ $(BOOST) \
+ $(GLOG) \
+ $(GMOCK) \
+ $(GPERFTOOLS) \
+ $(LIBEV) \
+ $(PROTOBUF) \
+ $(RY_HTTP_PARSER)
+
+
+# This is where the magic happens: we use stamp files as dependencies
+# which cause the packages to get extracted as necessary. We also
+# apply any patches as appropriate.
+%-stamp: %.tar.gz
+ gzip -d -c $^ | tar xf -
+ test ! -e $(srcdir)/$*.patch || patch -d $* -p1 <$(srcdir)/$*.patch
+ touch $@
+
+
+# Convenience library for Ryan Dahl's HTTP parser.
+noinst_LTLIBRARIES = libry_http_parser.la
+nodist_libry_http_parser_la_SOURCES = $(RY_HTTP_PARSER)/http_parser.c
+libry_http_parser_la_CPPFLAGS = -I$(RY_HTTP_PARSER)
+
+# We list the sources in BUILT_SOURCES to make sure that the package
+# gets unarchived first.
+BUILT_SOURCES += $(nodist_libry_http_parser_la_SOURCES)
+
+
+# Convenience library for gmock/gtest.
+check_LTLIBRARIES = libgmock.la
+nodist_libgmock_la_SOURCES = \
+ $(GTEST)/src/gtest-all.cc \
+ $(GMOCK)/src/gmock-all.cc
+libgmock_la_CPPFLAGS = \
+ -I$(GTEST)/include -I$(GTEST) \
+ -I$(GMOCK)/include -I$(GMOCK)
+
+# We list the sources in BUILT_SOURCES to make sure that the package
+# gets unarchived first.
+BUILT_SOURCES += $(nodist_libgmock_la_SOURCES)
+
+$(GMOCK)/src/gmock-all.cc: $(GMOCK)-stamp
+$(GTEST)/src/gtest-all.cc: $(GMOCK)-stamp
+
+
+$(BOOST)/boost: $(BOOST)-stamp
+
+$(GLOG)/libglog.la: $(GLOG)-stamp
+ cd $(GLOG) && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+
+if HAS_GPERFTOOLS
+$(GPERFTOOLS)/libprofiler.la: $(GPERFTOOLS)-build-stamp
+
+$(GPERFTOOLS)-build-stamp: $(GPERFTOOLS)-stamp
+ cd $(GPERFTOOLS) && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+ touch $@
+endif
+
+$(LIBEV)/libev.la: $(LIBEV)-stamp
+ cd $(LIBEV) && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+
+$(PROTOBUF)/src/protoc $(PROTOBUF)/src/libprotobuf.la: $(PROTOBUF)-build-stamp
+
+$(PROTOBUF)-build-stamp: $(PROTOBUF)-stamp
+ cd $(PROTOBUF) && ./configure $(CONFIGURE_ARGS) && \
+ $(MAKE) $(AM_MAKEFLAGS)
+ touch $@
+
+$(RY_HTTP_PARSER)/http_parser.c: $(RY_HTTP_PARSER)-stamp
+
+
+# Tests for stout.
+check_PROGRAMS = stout-tests
+
+stout_tests_SOURCES = \
+ $(STOUT)/tests/bytes_tests.cpp \
+ $(STOUT)/tests/duration_tests.cpp \
+ $(STOUT)/tests/error_tests.cpp \
+ $(STOUT)/tests/flags_tests.cpp \
+ $(STOUT)/tests/gzip_tests.cpp \
+ $(STOUT)/tests/hashset_tests.cpp \
+ $(STOUT)/tests/json_tests.cpp \
+ $(STOUT)/tests/main.cpp \
+ $(STOUT)/tests/multimap_tests.cpp \
+ $(STOUT)/tests/none_tests.cpp \
+ $(STOUT)/tests/os_tests.cpp \
+ $(STOUT)/tests/strings_tests.cpp \
+ $(STOUT)/tests/uuid_tests.cpp
+
+if OS_LINUX
+ stout_tests_SOURCES += $(STOUT)/tests/proc_tests.cpp
+endif
+
+stout_tests_CPPFLAGS = \
+ -I$(srcdir)/$(STOUT)/include \
+ -I$(BOOST) \
+ -I$(GLOG)/src \
+ -I$(GTEST)/include \
+ -I$(GMOCK)/include \
+ -I$(PROTOBUF)/src \
+ $(AM_CPPFLAGS)
+
+stout_tests_LDADD = \
+ libgmock.la \
+ $(GLOG)/libglog.la \
+ $(PROTOBUF)/src/libprotobuf.la
+
+TESTS = stout-tests
+
+# Dependencies for all-local.
+ALL_LOCAL = \
+ $(STOUT)/Makefile \
+ $(BOOST)-stamp \
+ $(GLOG)/libglog.la \
+ $(LIBEV)/libev.la \
+ $(PROTOBUF)/src/libprotobuf.la \
+ $(PROTOBUF)/src/protoc
+
+if HAS_GPERFTOOLS
+ ALL_LOCAL += $(GPERFTOOLS)/libprofiler.la
+endif
+
+all-local: $(ALL_LOCAL)
+
+clean-local:
+ rm -r -f $(CLEAN_EXTRACTED)
+ rm -f *-stamp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/boost-1.53.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/boost-1.53.0.tar.gz b/third_party/libprocess/3rdparty/boost-1.53.0.tar.gz
new file mode 100644
index 0000000..770d837
Binary files /dev/null and b/third_party/libprocess/3rdparty/boost-1.53.0.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/glog-0.3.1.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/glog-0.3.1.tar.gz b/third_party/libprocess/3rdparty/glog-0.3.1.tar.gz
new file mode 100644
index 0000000..19b4b94
Binary files /dev/null and b/third_party/libprocess/3rdparty/glog-0.3.1.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz b/third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz
new file mode 100644
index 0000000..d45d989
Binary files /dev/null and b/third_party/libprocess/3rdparty/gmock-1.6.0.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/gperftools-2.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/gperftools-2.0.tar.gz b/third_party/libprocess/3rdparty/gperftools-2.0.tar.gz
new file mode 100644
index 0000000..13b03ca
Binary files /dev/null and b/third_party/libprocess/3rdparty/gperftools-2.0.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/libev-4.15.patch
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/libev-4.15.patch b/third_party/libprocess/3rdparty/libev-4.15.patch
new file mode 100644
index 0000000..2b94532
--- /dev/null
+++ b/third_party/libprocess/3rdparty/libev-4.15.patch
@@ -0,0 +1,11 @@
+diff -rupN libev-4.15/ev.h libev-4.15-patched/ev.h
+--- libev-4.15/ev.h 2013-03-01 03:05:29.000000000 -0800
++++ libev-4.15-patched/ev.h 2013-05-20 16:01:47.000000000 -0700
+@@ -121,7 +121,7 @@ EV_CPP(extern "C" {)
+ # ifdef _WIN32
+ # define EV_CHILD_ENABLE 0
+ # else
+-# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
++# define EV_CHILD_ENABLE 0
+ #endif
+ #endif
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/libev-4.15.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/libev-4.15.tar.gz b/third_party/libprocess/3rdparty/libev-4.15.tar.gz
new file mode 100644
index 0000000..4c282b5
Binary files /dev/null and b/third_party/libprocess/3rdparty/libev-4.15.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/protobuf-2.4.1.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/protobuf-2.4.1.tar.gz b/third_party/libprocess/3rdparty/protobuf-2.4.1.tar.gz
new file mode 100644
index 0000000..38ec4de
Binary files /dev/null and b/third_party/libprocess/3rdparty/protobuf-2.4.1.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz b/third_party/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz
new file mode 100644
index 0000000..b811b63
Binary files /dev/null and b/third_party/libprocess/3rdparty/ry-http-parser-1c3624a.tar.gz differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/LICENSE
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/LICENSE b/third_party/libprocess/3rdparty/stout/LICENSE
new file mode 100644
index 0000000..f433b1a
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/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/bc531d3c/third_party/libprocess/3rdparty/stout/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/Makefile.am b/third_party/libprocess/3rdparty/stout/Makefile.am
new file mode 100644
index 0000000..fdd3482
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/Makefile.am
@@ -0,0 +1,61 @@
+# Makefile for stout.
+
+ACLOCAL_AMFLAGS = -I m4
+
+AUTOMAKE_OPTIONS = foreign
+
+EXTRA_DIST = \
+ include/stout/bytes.hpp \
+ include/stout/cache.hpp \
+ include/stout/duration.hpp \
+ include/stout/error.hpp \
+ include/stout/exit.hpp \
+ include/stout/fatal.hpp \
+ include/stout/flags.hpp \
+ include/stout/flags/flag.hpp \
+ include/stout/flags/flags.hpp \
+ include/stout/flags/loader.hpp \
+ include/stout/flags/parse.hpp \
+ include/stout/foreach.hpp \
+ include/stout/format.hpp \
+ include/stout/fs.hpp \
+ include/stout/gtest.hpp \
+ include/stout/gzip.hpp \
+ include/stout/hashmap.hpp \
+ include/stout/hashset.hpp \
+ include/stout/json.hpp \
+ include/stout/lambda.hpp \
+ include/stout/multihashmap.hpp \
+ include/stout/multimap.hpp \
+ include/stout/net.hpp \
+ include/stout/none.hpp \
+ include/stout/nothing.hpp \
+ include/stout/numify.hpp \
+ include/stout/option.hpp \
+ include/stout/os.hpp \
+ include/stout/owned.hpp \
+ include/stout/path.hpp \
+ include/stout/preprocessor.hpp \
+ include/stout/proc.hpp \
+ include/stout/protobuf.hpp \
+ include/stout/result.hpp \
+ include/stout/stopwatch.hpp \
+ include/stout/stringify.hpp \
+ include/stout/strings.hpp \
+ include/stout/try.hpp \
+ include/stout/utils.hpp \
+ include/stout/uuid.hpp \
+ tests/bytes_tests.cpp \
+ tests/duration_tests.cpp \
+ tests/error_tests.cpp \
+ tests/flags_tests.cpp \
+ tests/gzip_tests.cpp \
+ tests/hashset_tests.cpp \
+ tests/json_tests.cpp \
+ tests/main.cpp \
+ tests/multimap_tests.cpp \
+ tests/none_tests.cpp \
+ tests/os_tests.cpp \
+ tests/proc_tests.cpp \
+ tests/strings_tests.cpp \
+ tests/uuid_tests.cpp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/README
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/README b/third_party/libprocess/3rdparty/stout/README
new file mode 100644
index 0000000..685a4ae
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/README
@@ -0,0 +1,32 @@
+Stout is a header-only C++ library.
+
+No action is needed if you would like to use this library in your
+project. Simply add the include folder to your include path during
+compilation.
+
+Depending on which headers you'd like to use, you may require the
+following third party libraries:
+
+ - Boost
+ - Google's glog (this dependency will be removed in the future).
+ - Google's protobuf.
+ - Google's gmock/gtest.
+
+
+Building Tests
+==============
+
+We'll assume you've got a distribution of gmock and have already built
+a static archive called libgmock.a (see gmock's README to learn
+how). We'll also assume the Boost and glog headers can be found via
+the include paths and libglog.* can be found via the library search
+paths. You can then build the tests via:
+
+$ g++ -I${STOUT}/include -I$(GMOCK)/gtest/include -I$(GMOCK)/include \
+ ${STOUT}/tests/tests.cpp libgmock.a -lglog -o tests
+
+Note that if you want to test the gzip headers you'll need to define
+HAVE_LIBZ and link against libz:
+
+$ g++ -I${STOUT}/include -I$(GMOCK)/gtest/include -I$(GMOCK)/include \
+ -DHAVE_LIBZ ${STOUT}/tests/tests.cpp libgmock.a -lglog -lz -o tests
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/bootstrap
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/bootstrap b/third_party/libprocess/3rdparty/stout/bootstrap
new file mode 100755
index 0000000..89b9bc8
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/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 "${@}"
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/configure.ac
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/configure.ac b/third_party/libprocess/3rdparty/stout/configure.ac
new file mode 100644
index 0000000..86e1ff3
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/configure.ac
@@ -0,0 +1,14 @@
+# Generated with autoscan, then modified appropriately.
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.61])
+AC_INIT([stout], [0.1.0])
+
+AC_LANG([C++])
+
+# Initialize automake.
+AM_INIT_AUTOMAKE([1.10])
+
+AC_CONFIG_FILES([Makefile])
+
+AC_OUTPUT
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/bytes.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/bytes.hpp b/third_party/libprocess/3rdparty/stout/include/stout/bytes.hpp
new file mode 100644
index 0000000..754fbb2
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/bytes.hpp
@@ -0,0 +1,160 @@
+#ifndef __STOUT_BYTES_HPP__
+#define __STOUT_BYTES_HPP__
+
+#include <ctype.h> // For 'isdigit'.
+#include <stdint.h>
+
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+#include "numify.hpp"
+#include "strings.hpp"
+#include "try.hpp"
+
+
+class Bytes
+{
+public:
+ static Try<Bytes> parse(const std::string& s)
+ {
+ size_t index = 0;
+
+ while (index < s.size()) {
+ if (isdigit(s[index])) {
+ index++;
+ continue;
+ } else if (s[index] == '.') {
+ return Error("Fractional bytes '" + s + "'");
+ }
+
+ Try<uint64_t> value = numify<uint64_t>(s.substr(0, index));
+
+ if (value.isError()) {
+ return Error(value.error());
+ }
+
+ const std::string& unit = strings::upper(s.substr(index));
+
+ if (unit == "B") {
+ return Bytes(value.get(), BYTES);
+ } else if (unit == "KB") {
+ return Bytes(value.get(), KILOBYTES);
+ } else if (unit == "MB") {
+ return Bytes(value.get(), MEGABYTES);
+ } else if (unit == "GB") {
+ return Bytes(value.get(), GIGABYTES);
+ } else if (unit == "TB") {
+ return Bytes(value.get(), TERABYTES);
+ } else {
+ return Error("Unknown bytes unit '" + unit + "'");
+ }
+ }
+ return Error("Invalid bytes '" + s + "'");
+ }
+
+ Bytes(uint64_t bytes = 0) : value(bytes) {}
+ Bytes(uint64_t _value, uint64_t _unit) : value(_value * _unit) {}
+
+ // TODO(bmahler): Consider killing kilobytes to terabyte helpers, given
+ // they implicitly lose precision if not careful.
+ uint64_t bytes() const { return value; }
+ uint64_t kilobytes() const { return value / KILOBYTES; }
+ uint64_t megabytes() const { return value / MEGABYTES; }
+ uint64_t gigabytes() const { return value / GIGABYTES; }
+ uint64_t terabytes() const { return value / TERABYTES; }
+
+ bool operator < (const Bytes& that) const { return value < that.value; }
+ bool operator <= (const Bytes& that) const { return value <= that.value; }
+ bool operator > (const Bytes& that) const { return value > that.value; }
+ bool operator >= (const Bytes& that) const { return value >= that.value; }
+ bool operator == (const Bytes& that) const { return value == that.value; }
+ bool operator != (const Bytes& that) const { return value != that.value; }
+
+ Bytes& operator += (const Bytes& that)
+ {
+ value += that.value;
+ return *this;
+ }
+
+ Bytes& operator -= (const Bytes& that)
+ {
+ value -= that.value;
+ return *this;
+ }
+
+protected:
+ static const uint64_t BYTES = 1;
+ static const uint64_t KILOBYTES = 1024 * BYTES;
+ static const uint64_t MEGABYTES = 1024 * KILOBYTES;
+ static const uint64_t GIGABYTES = 1024 * MEGABYTES;
+ static const uint64_t TERABYTES = 1024 * GIGABYTES;
+
+private:
+ uint64_t value;
+};
+
+
+class Kilobytes : public Bytes
+{
+public:
+ explicit Kilobytes(uint64_t value) : Bytes(value, KILOBYTES) {}
+};
+
+
+class Megabytes : public Bytes
+{
+public:
+ explicit Megabytes(uint64_t value) : Bytes(value, MEGABYTES) {}
+};
+
+
+class Gigabytes : public Bytes
+{
+public:
+ explicit Gigabytes(uint64_t value) : Bytes(value, GIGABYTES) {}
+};
+
+
+class Terabytes : public Bytes
+{
+public:
+ explicit Terabytes(uint64_t value) : Bytes(value, TERABYTES) {}
+};
+
+
+inline std::ostream& operator << (std::ostream& stream, const Bytes& bytes)
+{
+ // Only raise the unit when there is no loss of information.
+ if (bytes.bytes() == 0) {
+ return stream << bytes.bytes() << "B";
+ } else if (bytes.bytes() % 1024 != 0) {
+ return stream << bytes.bytes() << "B";
+ } else if (bytes.kilobytes() % 1024 != 0) {
+ return stream << bytes.kilobytes() << "KB";
+ } else if (bytes.megabytes() % 1024 != 0) {
+ return stream << bytes.megabytes() << "MB";
+ } else if (bytes.gigabytes() % 1024 != 0) {
+ return stream << bytes.gigabytes() << "GB";
+ } else {
+ return stream << bytes.terabytes() << "TB";
+ }
+}
+
+
+inline Bytes operator + (const Bytes& lhs, const Bytes& rhs)
+{
+ Bytes sum = lhs;
+ sum += rhs;
+ return sum;
+}
+
+
+inline Bytes operator - (const Bytes& lhs, const Bytes& rhs)
+{
+ Bytes diff = lhs;
+ diff -= rhs;
+ return diff;
+}
+
+#endif // __STOUT_BYTES_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/cache.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/cache.hpp b/third_party/libprocess/3rdparty/stout/include/stout/cache.hpp
new file mode 100644
index 0000000..653507c
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/cache.hpp
@@ -0,0 +1,131 @@
+#ifndef __STOUT_CACHE_HPP__
+#define __STOUT_CACHE_HPP__
+
+#include <functional>
+#include <iostream>
+#include <list>
+#include <map>
+
+#include <tr1/functional>
+#include <tr1/unordered_map>
+
+#include "none.hpp"
+#include "option.hpp"
+
+// Forward declaration.
+template <typename Key, typename Value>
+class cache;
+
+// Outputs the key/value pairs from least to most-recently used.
+template <typename Key, typename Value>
+std::ostream& operator << (
+ std::ostream& stream,
+ const cache<Key, Value>& c);
+
+
+// Provides a least-recently used (LRU) cache of some predefined
+// capacity. A "write" and a "read" both count as uses.
+template <typename Key, typename Value>
+class cache
+{
+public:
+ typedef std::list<Key> list;
+ typedef std::tr1::unordered_map<
+ Key, std::pair<Value, typename list::iterator> > map;
+
+ explicit cache(int _capacity) : capacity(_capacity) {}
+
+ void put(const Key& key, const Value& value)
+ {
+ typename map::iterator i = values.find(key);
+ if (i == values.end()) {
+ insert(key, value);
+ } else {
+ (*i).second.first = value;
+ use(i);
+ }
+ }
+
+ Option<Value> get(const Key& key)
+ {
+ typename map::iterator i = values.find(key);
+
+ if (i != values.end()) {
+ use(i);
+ return (*i).second.first;
+ }
+
+ return None();
+ }
+
+private:
+ // Not copyable, not assignable.
+ cache(const cache&);
+ cache& operator = (const cache&);
+
+ // Give the operator access to our internals.
+ friend std::ostream& operator << <>(
+ std::ostream& stream,
+ const cache<Key, Value>& c);
+
+ // Insert key/value into the cache.
+ void insert(const Key& key, const Value& value)
+ {
+ if (keys.size() == capacity) {
+ evict();
+ }
+
+ // Get a "pointer" into the lru list for efficient update.
+ typename list::iterator i = keys.insert(keys.end(), key);
+
+ // Save key/value and "pointer" into lru list.
+ values.insert(std::make_pair(key, std::make_pair(value, i)));
+ }
+
+ // Updates the LRU ordering in the cache for the given iterator.
+ void use(const typename map::iterator& i)
+ {
+ // Move the "pointer" to the end of the lru list.
+ keys.splice(keys.end(), keys, (*i).second.second);
+
+ // Now update the "pointer" so we can do this again.
+ (*i).second.second = --keys.end();
+ }
+
+ // Evict the least-recently used element from the cache.
+ void evict()
+ {
+ const typename map::iterator& i = values.find(keys.front());
+ CHECK(i != values.end());
+ values.erase(i);
+ keys.pop_front();
+ }
+
+ // Size of the cache.
+ int capacity;
+
+ // Cache of values and "pointers" into the least-recently used list.
+ map values;
+
+ // Keys ordered by least-recently used.
+ list keys;
+};
+
+
+template <typename Key, typename Value>
+std::ostream& operator << (
+ std::ostream& stream,
+ const cache<Key, Value>& c)
+{
+ typename cache<Key, Value>::list::const_iterator i1;
+ for (i1 = c.keys.begin(); i1 != c.keys.end(); i1++) {
+ stream << *i1 << ": ";
+ typename cache<Key, Value>::map::const_iterator i2;
+ i2 = c.values.find(*i1);
+ CHECK(i2 != c.values.end());
+ stream << *i2 << std::endl;
+ }
+ return stream;
+}
+
+#endif // __STOUT_CACHE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/duration.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/duration.hpp b/third_party/libprocess/3rdparty/stout/include/stout/duration.hpp
new file mode 100644
index 0000000..47e85ff
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/duration.hpp
@@ -0,0 +1,297 @@
+#ifndef __STOUT_DURATION_HPP__
+#define __STOUT_DURATION_HPP__
+
+#include <ctype.h> // For 'isdigit'.
+#include <limits.h> // For 'LLONG_(MAX|MIN)'
+
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+#include "error.hpp"
+#include "numify.hpp"
+#include "try.hpp"
+
+class Duration
+{
+public:
+ static Try<Duration> parse(const std::string& s)
+ {
+ // TODO(benh): Support negative durations (i.e., starts with '-').
+ size_t index = 0;
+ while (index < s.size()) {
+ if (isdigit(s[index]) || s[index] == '.') {
+ index++;
+ continue;
+ }
+
+ Try<double> value = numify<double>(s.substr(0, index));
+
+ if (value.isError()) {
+ return Error(value.error());
+ }
+
+ const std::string& unit = s.substr(index);
+
+ if (unit == "ns") {
+ return Duration(value.get(), NANOSECONDS);
+ } else if (unit == "us") {
+ return Duration(value.get(), MICROSECONDS);
+ } else if (unit == "ms") {
+ return Duration(value.get(), MILLISECONDS);
+ } else if (unit == "secs") {
+ return Duration(value.get(), SECONDS);
+ } else if (unit == "mins") {
+ return Duration(value.get(), MINUTES);
+ } else if (unit == "hrs") {
+ return Duration(value.get(), HOURS);
+ } else if (unit == "days") {
+ return Duration(value.get(), DAYS);
+ } else if (unit == "weeks") {
+ return Duration(value.get(), WEEKS);
+ } else {
+ return Error("Unknown duration unit '" + unit + "'");
+ }
+ }
+ return Error("Invalid duration '" + s + "'");
+ }
+
+ static Try<Duration> create(double seconds);
+
+ Duration() : nanos(0) {}
+
+ int64_t ns() const { return nanos; }
+ double us() const { return static_cast<double>(nanos) / MICROSECONDS; }
+ double ms() const { return static_cast<double>(nanos) / MILLISECONDS; }
+ double secs() const { return static_cast<double>(nanos) / SECONDS; }
+ double mins() const { return static_cast<double>(nanos) / MINUTES; }
+ double hrs() const { return static_cast<double>(nanos) / HOURS; }
+ double days() const { return static_cast<double>(nanos) / DAYS; }
+ double weeks() const { return static_cast<double>(nanos) / WEEKS; }
+
+ bool operator < (const Duration& d) const { return nanos < d.nanos; }
+ bool operator <= (const Duration& d) const { return nanos <= d.nanos; }
+ bool operator > (const Duration& d) const { return nanos > d.nanos; }
+ bool operator >= (const Duration& d) const { return nanos >= d.nanos; }
+ bool operator == (const Duration& d) const { return nanos == d.nanos; }
+ bool operator != (const Duration& d) const { return nanos != d.nanos; }
+
+ Duration& operator += (const Duration& that)
+ {
+ nanos += that.nanos;
+ return *this;
+ }
+
+ Duration& operator -= (const Duration& that)
+ {
+ nanos -= that.nanos;
+ return *this;
+ }
+
+ Duration& operator *= (double multiplier)
+ {
+ nanos = static_cast<int64_t>(nanos * multiplier);
+ return *this;
+ }
+
+ Duration& operator /= (double divisor)
+ {
+ nanos = static_cast<int64_t>(nanos / divisor);
+ return *this;
+ }
+
+ Duration operator + (const Duration& that) const
+ {
+ Duration sum = *this;
+ sum += that;
+ return sum;
+ }
+
+ Duration operator - (const Duration& that) const
+ {
+ Duration diff = *this;
+ diff -= that;
+ return diff;
+ }
+
+ Duration operator * (double multiplier) const
+ {
+ Duration product = *this;
+ product *= multiplier;
+ return product;
+ }
+
+ Duration operator / (double divisor) const
+ {
+ Duration quotient = *this;
+ quotient /= divisor;
+ return quotient;
+ }
+
+ // TODO(xujyan): Use constexpr for the following variables after
+ // switching to C++11.
+ // A constant holding the maximum value a Duration can have.
+ static Duration max();
+ // A constant holding the minimum (negative) value a Duration can
+ // have.
+ static Duration min();
+ // A constant holding a Duration of a "zero" value.
+ static Duration zero() { return Duration(); }
+
+protected:
+ static const int64_t NANOSECONDS = 1;
+ static const int64_t MICROSECONDS = 1000 * NANOSECONDS;
+ static const int64_t MILLISECONDS = 1000 * MICROSECONDS;
+ static const int64_t SECONDS = 1000 * MILLISECONDS;
+ static const int64_t MINUTES = 60 * SECONDS;
+ static const int64_t HOURS = 60 * MINUTES;
+ static const int64_t DAYS = 24 * HOURS;
+ static const int64_t WEEKS = 7 * DAYS;
+
+ // For the Seconds, Minutes, Hours, Days & Weeks constructor.
+ Duration(int32_t value, int64_t unit)
+ : nanos(value * unit) {}
+
+ // For the Nanoseconds, Microseconds, Milliseconds constructor.
+ Duration(int64_t value, int64_t unit)
+ : nanos(value * unit) {}
+
+private:
+ // Used only by "parse".
+ Duration(double value, int64_t unit)
+ : nanos(static_cast<int64_t>(value * unit)) {}
+
+ int64_t nanos;
+};
+
+
+class Nanoseconds : public Duration
+{
+public:
+ explicit Nanoseconds(int64_t nanoseconds)
+ : Duration(nanoseconds, NANOSECONDS) {}
+
+ Nanoseconds(const Duration& d) : Duration(d) {}
+};
+
+
+class Microseconds : public Duration
+{
+public:
+ explicit Microseconds(int64_t microseconds)
+ : Duration(microseconds, MICROSECONDS) {}
+
+ Microseconds(const Duration& d) : Duration(d) {}
+};
+
+
+class Milliseconds : public Duration
+{
+public:
+ explicit Milliseconds(int64_t milliseconds)
+ : Duration(milliseconds, MILLISECONDS) {}
+
+ Milliseconds(const Duration& d) : Duration(d) {}
+};
+
+
+class Seconds : public Duration
+{
+public:
+ explicit Seconds(int64_t seconds)
+ : Duration(seconds, SECONDS) {}
+
+ Seconds(const Duration& d) : Duration(d) {}
+};
+
+
+class Minutes : public Duration
+{
+public:
+ explicit Minutes(int32_t minutes)
+ : Duration(minutes, MINUTES) {}
+
+ Minutes(const Duration& d) : Duration(d) {}
+};
+
+
+class Hours : public Duration
+{
+public:
+ explicit Hours(int32_t hours)
+ : Duration(hours, HOURS) {}
+
+ Hours(const Duration& d) : Duration(d) {}
+};
+
+
+class Days : public Duration
+{
+public:
+ explicit Days(int32_t days)
+ : Duration(days, DAYS) {}
+
+ Days(const Duration& d) : Duration(d) {}
+};
+
+
+class Weeks : public Duration
+{
+public:
+ explicit Weeks(int32_t value) : Duration(value, WEEKS) {}
+
+ Weeks(const Duration& d) : Duration(d) {}
+};
+
+
+inline std::ostream& operator << (
+ std::ostream& stream,
+ const Duration& duration)
+{
+ long precision = stream.precision();
+
+ // Output the duration in full double precision.
+ stream.precision(std::numeric_limits<double>::digits10);
+
+ if (duration < Microseconds(1)) {
+ stream << duration.ns() << "ns";
+ } else if (duration < Milliseconds(1)) {
+ stream << duration.us() << "us";
+ } else if (duration < Seconds(1)) {
+ stream << duration.ms() << "ms";
+ } else if (duration < Minutes(1)) {
+ stream << duration.secs() << "secs";
+ } else if (duration < Hours(1)) {
+ stream << duration.mins() << "mins";
+ } else if (duration < Days(1)) {
+ stream << duration.hrs() << "hrs";
+ } else if (duration < Weeks(1)) {
+ stream << duration.days() << "days";
+ } else {
+ stream << duration.weeks() << "weeks";
+ }
+
+ // Return the stream to original formatting state.
+ stream.precision(precision);
+
+ return stream;
+}
+
+
+inline Try<Duration> Duration::create(double seconds)
+{
+ if (seconds * SECONDS > LLONG_MAX) {
+ return Error("Argument larger than the maximum number of seconds that "
+ "a Duration can represent due to int64_t's size limit.");
+ }
+
+ return Nanoseconds(static_cast<int64_t>(seconds * SECONDS));
+}
+
+
+inline Duration Duration::max() { return Nanoseconds(LLONG_MAX); }
+
+
+inline Duration Duration::min() { return Nanoseconds(LLONG_MIN); }
+
+#endif // __STOUT_DURATION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/error.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/error.hpp b/third_party/libprocess/3rdparty/stout/include/stout/error.hpp
new file mode 100644
index 0000000..97a5cec
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/error.hpp
@@ -0,0 +1,72 @@
+#ifndef __STOUT_ERROR_HPP__
+#define __STOUT_ERROR_HPP__
+
+#include <errno.h>
+#include <string.h> // For strerror.
+
+#include <string>
+
+#include "result.hpp"
+#include "try.hpp"
+
+// An "error" type that is implicitly convertible to a Try<T> or
+// Result<T> for any T (effectively "syntactic sugar" to make code
+// more readable). The implementation uses cast operators to perform
+// the conversions instead of adding constructors to Try/Result
+// directly. One could imagine revisiting that decision for C++11
+// because the use of rvalue reference could eliminate some
+// unnecessary copies. However, performance is not critical since
+// Error should not get called very often in practice (if so, it's
+// probably being used for things that aren't really errors or there
+// is a more serious problem during execution).
+
+class Error
+{
+public:
+ explicit Error(const std::string& _message) : message(_message) {}
+
+ template <typename T>
+ operator Try<T> () const
+ {
+ return Try<T>::error(message);
+ }
+
+ // Give the compiler some help for nested Try<T>. For example,
+ // enable converting Error to an Option<Try<T>>. Note that this will
+ // bind to the innermost Try<T>.
+ template <template <typename> class S, typename T>
+ operator S<Try<T> > () const
+ {
+ return S<Try<T> >(Try<T>::error(message));
+ }
+
+ template <typename T>
+ operator Result<T> () const
+ {
+ return Result<T>::error(message);
+ }
+
+ // Give the compiler some help for nested Result<T>. For example,
+ // enable converting Error to an Option<Result<T>>. Note that this
+ // will bind to the innermost Result<T>.
+ template <template <typename> class S, typename T>
+ operator S<Result<T> > () const
+ {
+ return S<Result<T> >(Result<T>::error(message));
+ }
+
+ const std::string message;
+};
+
+
+class ErrnoError : public Error
+{
+public:
+ ErrnoError()
+ : Error(std::string(strerror(errno))) {}
+
+ ErrnoError(const std::string& message)
+ : Error(message + ": " + std::string(strerror(errno))) {}
+};
+
+#endif // __STOUT_ERROR_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/exit.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/exit.hpp b/third_party/libprocess/3rdparty/stout/include/stout/exit.hpp
new file mode 100644
index 0000000..e8da726
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/exit.hpp
@@ -0,0 +1,37 @@
+#ifndef __STOUT_EXIT_HPP__
+#define __STOUT_EXIT_HPP__
+
+#include <stdlib.h>
+
+#include <iostream> // For std::cerr.
+#include <ostream>
+#include <sstream>
+#include <string>
+
+// Exit takes an exit status and provides a stream for output prior to
+// exiting. This is like glog's LOG(FATAL) or CHECK, except that it
+// does _not_ print a stack trace.
+//
+// Ex: EXIT(1) << "Cgroups are not present in this system.";
+#define EXIT(status) __Exit(status).stream()
+
+struct __Exit
+{
+ __Exit(int _status) : status(_status) {}
+
+ ~__Exit()
+ {
+ std::cerr << out.str() << std::endl;
+ exit(status);
+ }
+
+ std::ostream& stream()
+ {
+ return out;
+ }
+
+ std::ostringstream out;
+ const int status;
+};
+
+#endif // __STOUT_EXIT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/fatal.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/fatal.hpp b/third_party/libprocess/3rdparty/stout/include/stout/fatal.hpp
new file mode 100644
index 0000000..eabee3e
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/fatal.hpp
@@ -0,0 +1,43 @@
+#ifndef __STOUT_FATAL_HPP__
+#define __STOUT_FATAL_HPP__
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*
+ * Like the non-debug version except includes the file name and line
+ * number in the output.
+ */
+#define fatal(fmt...) __fatal(__FILE__, __LINE__, fmt)
+inline void __fatal(const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, " (%s:%u)\n", file, line);
+ fflush(stderr);
+ va_end(args);
+ exit(1);
+}
+
+
+/*
+ * Like the non-debug version except includes the file name and line
+ * number in the output.
+ */
+#define fatalerror(fmt...) __fatalerror(__FILE__, __LINE__, fmt)
+inline void __fatalerror(const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, " (%s:%u): ", file, line);
+ perror(NULL);
+ fflush(stderr);
+ va_end(args);
+ exit(1);
+}
+
+#endif // __STOUT_FATAL_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/flags.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags.hpp
new file mode 100644
index 0000000..0efd079
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/flags.hpp
@@ -0,0 +1,70 @@
+#ifndef __STOUT_FLAGS_HPP__
+#define __STOUT_FLAGS_HPP__
+
+#include <stout/flags/flags.hpp>
+
+// An abstraction for application/library "flags". An example is
+// probably best:
+// -------------------------------------------------------------
+// class MyFlags : public virtual FlagsBase // Use 'virtual' for composition!
+// {
+// public:
+// Flags()
+// {
+// add(&debug,
+// "debug",
+// "Help string for debug",
+// false);
+//
+// add(&name,
+// "name",
+// "Help string for name");
+// }
+
+// bool debug;
+// Option<string> name;
+// };
+//
+// ...
+//
+// map<string, Option<string> > values;
+// values["no-debug"] = None(); // --no-debug
+// values["debug"] = None(); // --debug
+// values["debug"] = Option<string>::some("true"); // --debug=true
+// values["debug"] = Option<string>::some("false"); // --debug=false
+// values["name"] = Option<string>::some("frank"); // --name=frank
+//
+// MyFlags flags;
+// flags.load(values);
+// flags.name.isSome() ...
+// flags.debug ...
+// -------------------------------------------------------------
+//
+// You can also compose flags provided that each has used "virtual
+// inheritance":
+// -------------------------------------------------------------
+// Flags<MyFlags1, MyFlags2> flags;
+// flags.add(...); // Any other flags you want to throw in there.
+// flags.load(values);
+// flags.flag_from_myflags1 ...
+// flags.flag_from_myflags2 ...
+// -------------------------------------------------------------
+//
+// "Fail early, fail often":
+//
+// You can not add duplicate flags, this is checked for you at compile
+// time for composite flags (e.g., Flag<MyFlags1, MyFlags2>) and also
+// checked at runtime for any other flags added via inheritance or
+// Flags::add(...).
+//
+// Flags that can not be loaded (e.g., attempting to use the 'no-'
+// prefix for a flag that is not boolean) will print a message to
+// standard error and abort the process.
+
+// TODO(benh): Provide a boolean which specifies whether or not to
+// abort on duplicates or load errors.
+
+// TODO(benh): Make prefix for environment variables configurable
+// (e.g., "MESOS_").
+
+#endif // __STOUT_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags/flag.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
new file mode 100644
index 0000000..d31c984
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/flags/flag.hpp
@@ -0,0 +1,26 @@
+#ifndef __STOUT_FLAGS_FLAG_HPP__
+#define __STOUT_FLAGS_FLAG_HPP__
+
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+namespace flags {
+
+// Forward declaration.
+class FlagsBase;
+
+struct Flag
+{
+ std::string name;
+ std::string help;
+ bool boolean;
+ std::tr1::function<Try<Nothing>(FlagsBase*, const std::string&)> loader;
+};
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_FLAG_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags/flags.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
new file mode 100644
index 0000000..77d36e6
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
@@ -0,0 +1,481 @@
+#ifndef __STOUT_FLAGS_FLAGS_HPP__
+#define __STOUT_FLAGS_FLAGS_HPP__
+
+#include <stdlib.h> // For abort.
+
+#include <map>
+#include <string>
+#include <typeinfo> // For typeid.
+
+#include <tr1/functional>
+
+#include <stout/error.hpp>
+#include <stout/exit.hpp>
+#include <stout/foreach.hpp>
+#include <stout/none.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/os.hpp>
+#include <stout/stringify.hpp>
+#include <stout/strings.hpp>
+#include <stout/try.hpp>
+
+#include <stout/flags/flag.hpp>
+#include <stout/flags/loader.hpp>
+#include <stout/flags/parse.hpp>
+
+namespace flags {
+
+class FlagsBase
+{
+public:
+ virtual ~FlagsBase() {}
+
+ // Load any flags from the environment given the variable prefix,
+ // i.e., given prefix 'STOUT_' will load a flag named 'foo' via
+ // environment variables 'STOUT_foo' or 'STOUT_FOO'.
+ virtual Try<Nothing> load(
+ const std::string& prefix,
+ bool unknowns = false);
+
+ // Load any flags from the environment given the variable prefix
+ // (see above) followed by loading from the command line (via 'argc'
+ // and 'argv'). If 'unknowns' is true then we'll ignore unknown
+ // flags we see while loading. If 'duplicates' is true then we'll
+ // ignore any duplicates we see while loading.
+ virtual Try<Nothing> load(
+ const Option<std::string>& prefix,
+ int argc,
+ char** argv,
+ bool unknowns = false,
+ bool duplicates = false);
+
+ Try<Nothing> load(
+ const std::string& prefix,
+ int argc,
+ char** argv,
+ bool unknowns = false,
+ bool duplicates = false);
+
+ virtual Try<Nothing> load(
+ const std::map<std::string, Option<std::string> >& values,
+ bool unknowns = false);
+
+ virtual Try<Nothing> load(
+ const std::map<std::string, std::string>& values,
+ bool unknowns = false);
+
+ // Returns a string describing the flags.
+ std::string usage() const;
+
+ typedef std::map<std::string, Flag>::const_iterator const_iterator;
+
+ const_iterator begin() const { return flags.begin(); }
+ const_iterator end() const { return flags.end(); }
+
+ template <typename T1, typename T2>
+ void add(T1* t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2);
+
+ template <typename T>
+ void add(Option<T>* option,
+ const std::string& name,
+ const std::string& help);
+
+protected:
+ template <typename Flags, typename T1, typename T2>
+ void add(T1 Flags::*t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2);
+
+ template <typename Flags, typename T>
+ void add(Option<T> Flags::*option,
+ const std::string& name,
+ const std::string& help);
+
+ void add(const Flag& flag);
+
+private:
+ std::map<std::string, Flag> flags;
+};
+
+
+// Need to declare/define some explicit subclasses of FlagsBase so
+// that we can overload the 'Flags::operator FlagsN () const'
+// functions for each possible type.
+class _Flags1 : public virtual FlagsBase {};
+class _Flags2 : public virtual FlagsBase {};
+class _Flags3 : public virtual FlagsBase {};
+class _Flags4 : public virtual FlagsBase {};
+class _Flags5 : public virtual FlagsBase {};
+
+
+// TODO(benh): Add some "type constraints" for template paramters to
+// make sure they are all of type FlagsBase.
+template <typename Flags1 = _Flags1,
+ typename Flags2 = _Flags2,
+ typename Flags3 = _Flags3,
+ typename Flags4 = _Flags4,
+ typename Flags5 = _Flags5>
+class Flags : public virtual Flags1,
+ public virtual Flags2,
+ public virtual Flags3,
+ public virtual Flags4,
+ public virtual Flags5 {};
+
+
+template <typename T1, typename T2>
+void FlagsBase::add(
+ T1* t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2)
+{
+ *t1 = t2; // Set the default.
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T1) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &Loader<T1>::load,
+ t1,
+ std::tr1::function<Try<T1>(const std::string&)>(
+ std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
+
+ // Update the help string to include the default value.
+ flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
+ ? " (default: " // On same line, add space.
+ : "(default: "; // On newline.
+ flag.help += stringify(t2);
+ flag.help += ")";
+
+ FlagsBase::add(flag);
+}
+
+
+template <typename T>
+void FlagsBase::add(
+ Option<T>* option,
+ const std::string& name,
+ const std::string& help)
+{
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &OptionLoader<T>::load,
+ option,
+ std::tr1::function<Try<T>(const std::string&)>(
+ std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
+
+ FlagsBase::add(flag);
+}
+
+
+template <typename Flags, typename T1, typename T2>
+void FlagsBase::add(
+ T1 Flags::*t1,
+ const std::string& name,
+ const std::string& help,
+ const T2& t2)
+{
+ Flags* flags = dynamic_cast<Flags*>(this);
+ if (flags == NULL) {
+ std::cerr << "Attempted to add flag '" << name
+ << "' with incompatible type" << std::endl;
+ abort();
+ } else {
+ flags->*t1 = t2; // Set the default.
+ }
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T1) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &MemberLoader<Flags, T1>::load,
+ std::tr1::placeholders::_1,
+ t1,
+ std::tr1::function<Try<T1>(const std::string&)>(
+ std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2);
+
+ // Update the help string to include the default value.
+ flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
+ ? " (default: " // On same line, add space.
+ : "(default: "; // On newline.
+ flag.help += stringify(t2);
+ flag.help += ")";
+
+ add(flag);
+}
+
+
+template <typename Flags, typename T>
+void FlagsBase::add(
+ Option<T> Flags::*option,
+ const std::string& name,
+ const std::string& help)
+{
+ Flags* flags = dynamic_cast<Flags*>(this);
+ if (flags == NULL) {
+ std::cerr << "Attempted to add flag '" << name
+ << "' with incompatible type" << std::endl;
+ abort();
+ }
+
+ Flag flag;
+ flag.name = name;
+ flag.help = help;
+ flag.boolean = typeid(T) == typeid(bool);
+ flag.loader = std::tr1::bind(
+ &OptionMemberLoader<Flags, T>::load,
+ std::tr1::placeholders::_1,
+ option,
+ std::tr1::function<Try<T>(const std::string&)>(
+ std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
+ name,
+ std::tr1::placeholders::_2);
+
+ add(flag);
+}
+
+
+inline void FlagsBase::add(const Flag& flag)
+{
+ if (flags.count(flag.name) > 0) {
+ EXIT(1) << "Attempted to add duplicate flag '" << flag.name << "'";
+ } else if (flag.name.find("no-") == 0) {
+ EXIT(1) << "Attempted to add flag '" << flag.name
+ << "' that starts with the reserved 'no-' prefix";
+ }
+
+ flags[flag.name] = flag;
+}
+
+
+// Extract environment variable "flags" with the specified prefix.
+inline std::map<std::string, Option<std::string> > extract(
+ const std::string& prefix)
+{
+ char** environ = os::environ();
+
+ std::map<std::string, Option<std::string> > values;
+
+ for (int i = 0; environ[i] != NULL; i++) {
+ std::string variable = environ[i];
+ if (variable.find(prefix) == 0) {
+ size_t eq = variable.find_first_of("=");
+ if (eq == std::string::npos) {
+ continue; // Not expecting a missing '=', but ignore anyway.
+ }
+ std::string name = variable.substr(prefix.size(), eq - prefix.size());
+ name = strings::lower(name); // Allow PREFIX_NAME or PREFIX_name.
+ std::string value = variable.substr(eq + 1);
+ values[name] = Option<std::string>::some(value);
+ }
+ }
+
+ return values;
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::string& prefix,
+ bool unknowns)
+{
+ return load(extract(prefix), unknowns);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const Option<std::string>& prefix,
+ int argc,
+ char** argv,
+ bool unknowns,
+ bool duplicates)
+{
+ std::map<std::string, Option<std::string> > values;
+
+ if (prefix.isSome()) {
+ values = extract(prefix.get());
+ }
+
+ // Read flags from the command line.
+ for (int i = 1; i < argc; i++) {
+ const std::string arg(argv[i]);
+
+ std::string name;
+ Option<std::string> value = None();
+ if (arg.find("--") == 0) {
+ size_t eq = arg.find_first_of("=");
+ if (eq == std::string::npos && arg.find("--no-") == 0) { // --no-name
+ name = arg.substr(2);
+ } else if (eq == std::string::npos) { // --name
+ name = arg.substr(2);
+ } else { // --name=value
+ name = arg.substr(2, eq - 2);
+ value = arg.substr(eq + 1);
+ }
+ }
+ name = strings::lower(name);
+
+ if (!duplicates) {
+ if (values.count(name) > 0 ||
+ (name.find("no-") == 0 && values.count(name.substr(3)) > 0)) {
+ return Error("Duplicate flag '" + name + "' on command line");
+ }
+ }
+
+ values[name] = value;
+ }
+
+ return load(values, unknowns);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::string& prefix,
+ int argc,
+ char** argv,
+ bool unknowns,
+ bool duplicates)
+{
+ return load(Option<std::string>::some(prefix),
+ argc,
+ argv,
+ unknowns,
+ duplicates);
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::map<std::string, Option<std::string> >& values,
+ bool unknowns)
+{
+ std::map<std::string, Option<std::string> >::const_iterator iterator;
+
+ for (iterator = values.begin(); iterator != values.end(); ++iterator) {
+ const std::string& name = iterator->first;
+ const Option<std::string>& value = iterator->second;
+
+ if (flags.count(name) > 0) {
+ if (value.isSome()) { // --name=value
+ if (flags[name].boolean && value.get() == "") {
+ flags[name].loader(this, "true"); // Should never fail.
+ } else {
+ Try<Nothing> loader = flags[name].loader(this, value.get());
+ if (loader.isError()) {
+ return Error(
+ "Failed to load flag '" + name + "': " + loader.error());
+ }
+ }
+ } else { // --name
+ if (flags[name].boolean) {
+ flags[name].loader(this, "true"); // Should never fail.
+ } else {
+ return Error(
+ "Failed to load non-boolean flag '" + name + "': Missing value");
+ }
+ }
+ } else if (name.find("no-") == 0) {
+ if (flags.count(name.substr(3)) > 0) { // --no-name
+ if (flags[name.substr(3)].boolean) {
+ if (value.isNone() || value.get() == "") {
+ flags[name.substr(3)].loader(this, "false"); // Should never fail.
+ } else {
+ return Error(
+ "Failed to load boolean flag '" + name.substr(3) +
+ "' via '" + name + "' with value '" + value.get() + "'");
+ }
+ } else {
+ return Error(
+ "Failed to load non-boolean flag '" + name.substr(3) +
+ "' via '" + name + "'");
+ }
+ } else {
+ return Error(
+ "Failed to load unknown flag '" + name.substr(3) +
+ "' via '" + name + "'");
+ }
+ } else if (!unknowns) {
+ return Error("Failed to load unknown flag '" + name + "'");
+ }
+ }
+
+ return Nothing();
+}
+
+
+inline Try<Nothing> FlagsBase::load(
+ const std::map<std::string, std::string>& _values,
+ bool unknowns)
+{
+ std::map<std::string, Option<std::string> > values;
+ std::map<std::string, std::string>::const_iterator iterator;
+ for (iterator = _values.begin(); iterator != _values.end(); ++iterator) {
+ const std::string& name = iterator->first;
+ const std::string& value = iterator->second;
+ values[name] = Option<std::string>::some(value);
+ }
+ return load(values, unknowns);
+}
+
+
+inline std::string FlagsBase::usage() const
+{
+ const int PAD = 5;
+
+ std::string usage;
+
+ std::map<std::string, std::string> col1; // key -> col 1 string
+
+ // Construct string for the first column and store width of column.
+ size_t width = 0;
+
+ foreachvalue (const flags::Flag& flag, *this) {
+ if (flag.boolean) {
+ col1[flag.name] = " --[no-]" + flag.name;
+ } else {
+ col1[flag.name] = " --" + flag.name + "=VALUE";
+ }
+ width = std::max(width, col1[flag.name].size());
+ }
+
+ foreachvalue (const flags::Flag& flag, *this) {
+ std::string line = col1[flag.name];
+
+ std::string pad(PAD + width - line.size(), ' ');
+ line += pad;
+
+ size_t pos1 = 0, pos2 = 0;
+ pos2 = flag.help.find_first_of("\n\r", pos1);
+ line += flag.help.substr(pos1, pos2 - pos1) + "\n";
+ usage += line;
+
+ while (pos2 != std::string::npos) { // Handle multi-line help strings.
+ line = "";
+ pos1 = pos2 + 1;
+ std::string pad2(PAD + width, ' ');
+ line += pad2;
+ pos2 = flag.help.find_first_of("\n\r", pos1);
+ line += flag.help.substr(pos1, pos2 - pos1) + "\n";
+ usage += line;
+ }
+ }
+ return usage;
+}
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags/loader.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
new file mode 100644
index 0000000..e5eaf24
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/flags/loader.hpp
@@ -0,0 +1,109 @@
+#ifndef __STOUT_FLAGS_LOADER_HPP__
+#define __STOUT_FLAGS_LOADER_HPP__
+
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+#include <stout/flags/parse.hpp>
+
+namespace flags {
+
+// Forward declaration.
+class FlagsBase;
+
+template <typename T>
+struct Loader
+{
+ static Try<Nothing> load(
+ T* flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ *flag = t.get();
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename T>
+struct OptionLoader
+{
+ static Try<Nothing> load(
+ Option<T>* flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ *flag = Option<T>::some(t.get());
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename F, typename T>
+struct MemberLoader
+{
+ static Try<Nothing> load(
+ FlagsBase* base,
+ T F::*flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ F* f = dynamic_cast<F*>(base);
+ if (f != NULL) {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ f->*flag = t.get();
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ }
+ return Nothing();
+ }
+};
+
+
+template <typename F, typename T>
+struct OptionMemberLoader
+{
+ static Try<Nothing> load(
+ FlagsBase* base,
+ Option<T> F::*flag,
+ const std::tr1::function<Try<T>(const std::string&)>& parse,
+ const std::string& name,
+ const std::string& value)
+ {
+ F* f = dynamic_cast<F*>(base);
+ if (f != NULL) {
+ Try<T> t = parse(value);
+ if (t.isSome()) {
+ f->*flag = Option<T>::some(t.get());
+ } else {
+ return Error("Failed to load value '" + value + "': " + t.error());
+ }
+ }
+ return Nothing();
+ }
+};
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_LOADER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/flags/parse.hpp b/third_party/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
new file mode 100644
index 0000000..54eb35c
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/flags/parse.hpp
@@ -0,0 +1,55 @@
+#ifndef __STOUT_FLAGS_PARSE_HPP__
+#define __STOUT_FLAGS_PARSE_HPP__
+
+#include <sstream> // For istringstream.
+#include <string>
+
+#include <tr1/functional>
+
+#include <stout/duration.hpp>
+#include <stout/error.hpp>
+#include <stout/try.hpp>
+
+namespace flags {
+
+template <typename T>
+Try<T> parse(const std::string& value)
+{
+ T t;
+ std::istringstream in(value);
+ in >> t;
+ if (!in.good() && !in.eof()) {
+ return Error("Failed to convert into required type");
+ }
+ return t;
+}
+
+
+template <>
+inline Try<std::string> parse(const std::string& value)
+{
+ return value;
+}
+
+
+template <>
+inline Try<bool> parse(const std::string& value)
+{
+ if (value == "true" || value == "1") {
+ return true;
+ } else if (value == "false" || value == "0") {
+ return false;
+ }
+ return Error("Expecting a boolean (e.g., true or false)");
+}
+
+
+template <>
+inline Try<Duration> parse(const std::string& value)
+{
+ return Duration::parse(value);
+}
+
+} // namespace flags {
+
+#endif // __STOUT_FLAGS_PARSE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/include/stout/foreach.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/include/stout/foreach.hpp b/third_party/libprocess/3rdparty/stout/include/stout/foreach.hpp
new file mode 100644
index 0000000..0afe285
--- /dev/null
+++ b/third_party/libprocess/3rdparty/stout/include/stout/foreach.hpp
@@ -0,0 +1,51 @@
+#ifndef __STOUT_FOREACH_HPP__
+#define __STOUT_FOREACH_HPP__
+
+#include <boost/foreach.hpp>
+
+#include <boost/tuple/tuple.hpp>
+
+namespace __foreach__ {
+
+// NOTE: This is a copied from Boost
+// (boost/tuple/detail/tuple_basic_no_partial_spec.hpp) because the
+// new 'boost::tuples::ignore' does not work in our 'foreachkey' and
+// 'foreachvalue'.
+struct swallow_assign {
+ template<typename T>
+ swallow_assign const& operator=(const T&) const {
+ return *this;
+ }
+};
+
+swallow_assign const ignore = swallow_assign();
+
+} // namespace __foreach__ {
+
+#define BOOST_FOREACH_PAIR(VARFIRST, VARSECOND, COL) \
+ BOOST_FOREACH_PREAMBLE() \
+ if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \
+ if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else \
+ if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_END(COL)) {} else \
+ for (bool BOOST_FOREACH_ID(_foreach_continue) = true, BOOST_FOREACH_ID(_foreach_onetime) = true; \
+ BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_DONE(COL); \
+ BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0) \
+ if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_onetime))) {} else \
+ for (VARFIRST = BOOST_FOREACH_DEREF(COL).first; \
+ !BOOST_FOREACH_ID(_foreach_onetime); \
+ BOOST_FOREACH_ID(_foreach_onetime) = true) \
+ if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \
+ for (VARSECOND = BOOST_FOREACH_DEREF(COL).second; \
+ !BOOST_FOREACH_ID(_foreach_continue); \
+ BOOST_FOREACH_ID(_foreach_continue) = true)
+
+#define foreach BOOST_FOREACH
+#define foreachpair BOOST_FOREACH_PAIR
+
+#define foreachkey(VAR, COL) \
+ foreachpair (VAR, __foreach__::ignore, COL)
+
+#define foreachvalue(VAR, COL) \
+ foreachpair (__foreach__::ignore, VAR, COL)
+
+#endif // __STOUT_FOREACH_HPP__
[18/35] Renamed 'third_party' to '3rdparty'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/delay.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/delay.hpp b/third_party/libprocess/include/process/delay.hpp
deleted file mode 100644
index 97acd76..0000000
--- a/third_party/libprocess/include/process/delay.hpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef __PROCESS_DELAY_HPP__
-#define __PROCESS_DELAY_HPP__
-
-#include <tr1/functional>
-
-#include <process/dispatch.hpp>
-#include <process/timer.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/preprocessor.hpp>
-
-namespace process {
-
-// The 'delay' mechanism enables you to delay a dispatch to a process
-// for some specified number of seconds. Returns a Timer instance that
-// can be cancelled (but it might have already executed or be
-// executing concurrently).
-
-template <typename T>
-Timer delay(const Duration& duration,
- const PID<T>& pid,
- void (T::*method)())
-{
- std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(
- new std::tr1::function<void(T*)>(
- std::tr1::bind(method, std::tr1::placeholders::_1)));
-
- std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
- new std::tr1::function<void(ProcessBase*)>(
- std::tr1::bind(&internal::vdispatcher<T>,
- std::tr1::placeholders::_1,
- thunk)));
-
- std::tr1::function<void(void)> dispatch =
- std::tr1::bind(internal::dispatch,
- pid,
- dispatcher,
- internal::canonicalize(method));
-
- return Timer::create(duration, dispatch);
-}
-
-
-template <typename T>
-Timer delay(const Duration& duration,
- const Process<T>& process,
- void (T::*method)())
-{
- return delay(duration, process.self(), method);
-}
-
-
-template <typename T>
-Timer delay(const Duration& duration,
- const Process<T>* process,
- void (T::*method)())
-{
- return delay(duration, process->self(), method);
-}
-
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Timer delay(const Duration& duration, \
- const PID<T>& pid, \
- void (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk( \
- new std::tr1::function<void(T*)>( \
- std::tr1::bind(method, \
- std::tr1::placeholders::_1, \
- ENUM_PARAMS(N, a)))); \
- \
- std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher( \
- new std::tr1::function<void(ProcessBase*)>( \
- std::tr1::bind(&internal::vdispatcher<T>, \
- std::tr1::placeholders::_1, \
- thunk))); \
- \
- std::tr1::function<void(void)> dispatch = \
- std::tr1::bind(internal::dispatch, \
- pid, \
- dispatcher, \
- internal::canonicalize(method)); \
- \
- return Timer::create(duration, dispatch); \
- } \
- \
- template <typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Timer delay(const Duration& duration, \
- const Process<T>& process, \
- void (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- return delay(duration, process.self(), method, ENUM_PARAMS(N, a)); \
- } \
- \
- template <typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Timer delay(const Duration& duration, \
- const Process<T>* process, \
- void (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- return delay(duration, process->self(), method, ENUM_PARAMS(N, a)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
-} // namespace process {
-
-#endif // __PROCESS_DELAY_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/dispatch.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/dispatch.hpp b/third_party/libprocess/include/process/dispatch.hpp
deleted file mode 100644
index b337a87..0000000
--- a/third_party/libprocess/include/process/dispatch.hpp
+++ /dev/null
@@ -1,478 +0,0 @@
-#ifndef __PROCESS_DISPATCH_HPP__
-#define __PROCESS_DISPATCH_HPP__
-
-#include <string>
-
-#include <tr1/functional>
-#include <tr1/memory> // TODO(benh): Replace all shared_ptr with unique_ptr.
-
-#include <process/process.hpp>
-
-#include <stout/preprocessor.hpp>
-
-namespace process {
-
-// The dispatch mechanism enables you to "schedule" a method to get
-// invoked on a process. The result of that method invocation is
-// accessible via the future that is returned by the dispatch method
-// (note, however, that it might not be the _same_ future as the one
-// returned from the method, if the method even returns a future, see
-// below). Assuming some class 'Fibonacci' has a (visible) method
-// named 'compute' that takes an integer, N (and returns the Nth
-// fibonacci number) you might use dispatch like so:
-//
-// PID<Fibonacci> pid = spawn(new Fibonacci(), true); // Use the GC.
-// Future<int> f = dispatch(pid, &Fibonacci::compute, 10);
-//
-// Because the pid argument is "typed" we can ensure that methods are
-// only invoked on processes that are actually of that type. Providing
-// this mechanism for varying numbers of function types and arguments
-// requires support for variadic templates, slated to be released in
-// C++11. Until then, we use the Boost preprocessor macros to
-// accomplish the same thing (all be it less cleanly). See below for
-// those definitions.
-//
-// Dispatching is done via a level of indirection. The dispatch
-// routine itself creates a promise that is passed as an argument to a
-// partially applied 'dispatcher' function (defined below). The
-// dispatcher routines get passed to the actual process via an
-// internal routine called, not suprisingly, 'dispatch', defined
-// below:
-
-namespace internal {
-
-// The internal dispatch routine schedules a function to get invoked
-// within the context of the process associated with the specified pid
-// (first argument), unless that process is no longer valid. Note that
-// this routine does not expect anything in particular about the
-// specified function (second argument). The semantics are simple: the
-// function gets applied/invoked with the process as its first
-// argument. Currently we wrap the function in a shared_ptr but this
-// will probably change in the future to unique_ptr (or a variant).
-void dispatch(
- const UPID& pid,
- const std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> >& f,
- const std::string& method = std::string());
-
-// For each return type (void, future, value) there is a dispatcher
-// function which should complete the picture. Given the process
-// argument these routines downcast the process to the correct subtype
-// and invoke the thunk using the subtype as the argument
-// (receiver). Note that we must use dynamic_cast because we permit a
-// process to use multiple inheritance (e.g., to expose multiple
-// callback interfaces).
-
-template <typename T>
-void vdispatcher(
- ProcessBase* process,
- std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk)
-{
- assert(process != NULL);
- T* t = dynamic_cast<T*>(process);
- assert(t != NULL);
- (*thunk)(t);
-}
-
-
-template <typename R, typename T>
-void pdispatcher(
- ProcessBase* process,
- std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk,
- std::tr1::shared_ptr<Promise<R> > promise)
-{
- assert(process != NULL);
- T* t = dynamic_cast<T*>(process);
- assert(t != NULL);
- promise->associate((*thunk)(t));
-}
-
-
-template <typename R, typename T>
-void rdispatcher(
- ProcessBase* process,
- std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk,
- std::tr1::shared_ptr<Promise<R> > promise)
-{
- assert(process != NULL);
- T* t = dynamic_cast<T*>(process);
- assert(t != NULL);
- promise->set((*thunk)(t));
-}
-
-
-// Canonicalizes a pointer to a member function (i.e., method) into a
-// bytes representation for comparison (e.g., in tests).
-template <typename Method>
-std::string canonicalize(Method method)
-{
- return std::string(reinterpret_cast<const char*>(&method), sizeof(method));
-}
-
-} // namespace internal {
-
-
-// Okay, now for the definition of the dispatch routines
-// themselves. For each routine we provide the version in C++11 using
-// variadic templates so the reader can see what the Boost
-// preprocessor macros are effectively providing. Using C++11 closures
-// would shorten these definitions even more.
-//
-// First, definitions of dispatch for methods returning void:
-//
-// template <typename T, typename ...P>
-// void dispatch(
-// const PID<T>& pid,
-// void (T::*method)(P...),
-// P... p)
-// {
-// std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(
-// new std::tr1::function<void(T*)>(
-// std::tr1::bind(method,
-// std::tr1::placeholders::_1,
-// std::forward<P>(p)...)));
-//
-// std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
-// new std::tr1::function<void(ProcessBase*)>(
-// std::tr1::bind(&internal::vdispatcher<T>,
-// std::tr1::placeholders::_1,
-// thunk)));
-//
-// internal::dispatch(pid, dispatcher, internal::canonicalize(method));
-// }
-
-template <typename T>
-void dispatch(
- const PID<T>& pid,
- void (T::*method)(void))
-{
- std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk(
- new std::tr1::function<void(T*)>(
- std::tr1::bind(method, std::tr1::placeholders::_1)));
-
- std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
- new std::tr1::function<void(ProcessBase*)>(
- std::tr1::bind(&internal::vdispatcher<T>,
- std::tr1::placeholders::_1,
- thunk)));
-
- internal::dispatch(pid, dispatcher, internal::canonicalize(method));
-}
-
-template <typename T>
-void dispatch(
- const Process<T>& process,
- void (T::*method)(void))
-{
- dispatch(process.self(), method);
-}
-
-template <typename T>
-void dispatch(
- const Process<T>* process,
- void (T::*method)(void))
-{
- dispatch(process->self(), method);
-}
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- void dispatch( \
- const PID<T>& pid, \
- void (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- std::tr1::shared_ptr<std::tr1::function<void(T*)> > thunk( \
- new std::tr1::function<void(T*)>( \
- std::tr1::bind(method, \
- std::tr1::placeholders::_1, \
- ENUM_PARAMS(N, a)))); \
- \
- std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher( \
- new std::tr1::function<void(ProcessBase*)>( \
- std::tr1::bind(&internal::vdispatcher<T>, \
- std::tr1::placeholders::_1, \
- thunk))); \
- \
- internal::dispatch(pid, dispatcher, internal::canonicalize(method)); \
- } \
- \
- template <typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- void dispatch( \
- const Process<T>& process, \
- void (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- dispatch(process.self(), method, ENUM_PARAMS(N, a)); \
- } \
- \
- template <typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- void dispatch( \
- const Process<T>* process, \
- void (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- dispatch(process->self(), method, ENUM_PARAMS(N, a)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
-
-// Next, definitions of methods returning a future:
-//
-// template <typename R, typename T, typename ...P>
-// Future<R> dispatch(
-// const PID<T>& pid,
-// Future<R> (T::*method)(P...),
-// P... p)
-// {
-// std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk(
-// new std::tr1::function<Future<R>(T*)>(
-// std::tr1::bind(method,
-// std::tr1::placeholders::_1,
-// std::forward<P>(p)...)));
-//
-// std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
-// Future<R> future = promise->future();
-//
-// std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
-// new std::tr1::function<void(ProcessBase*)>(
-// std::tr1::bind(&internal::pdispatcher<R, T>,
-// std::tr1::placeholders::_1,
-// thunk, promise)));
-//
-// internal::dispatch(pid, dispatcher, internal::canonicalize(method));
-//
-// return future;
-// }
-
-template <typename R, typename T>
-Future<R> dispatch(
- const PID<T>& pid,
- Future<R> (T::*method)(void))
-{
- std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk(
- new std::tr1::function<Future<R>(T*)>(
- std::tr1::bind(method, std::tr1::placeholders::_1)));
-
- std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
- Future<R> future = promise->future();
-
- std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
- new std::tr1::function<void(ProcessBase*)>(
- std::tr1::bind(&internal::pdispatcher<R, T>,
- std::tr1::placeholders::_1,
- thunk, promise)));
-
- internal::dispatch(pid, dispatcher, internal::canonicalize(method));
-
- return future;
-}
-
-template <typename R, typename T>
-Future<R> dispatch(
- const Process<T>& process,
- Future<R> (T::*method)(void))
-{
- return dispatch(process.self(), method);
-}
-
-template <typename R, typename T>
-Future<R> dispatch(
- const Process<T>* process,
- Future<R> (T::*method)(void))
-{
- return dispatch(process->self(), method);
-}
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename R, \
- typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<R> dispatch( \
- const PID<T>& pid, \
- Future<R> (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- std::tr1::shared_ptr<std::tr1::function<Future<R>(T*)> > thunk( \
- new std::tr1::function<Future<R>(T*)>( \
- std::tr1::bind(method, \
- std::tr1::placeholders::_1, \
- ENUM_PARAMS(N, a)))); \
- \
- std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>()); \
- Future<R> future = promise->future(); \
- \
- std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher( \
- new std::tr1::function<void(ProcessBase*)>( \
- std::tr1::bind(&internal::pdispatcher<R, T>, \
- std::tr1::placeholders::_1, \
- thunk, promise))); \
- \
- internal::dispatch(pid, dispatcher, internal::canonicalize(method)); \
- \
- return future; \
- } \
- \
- template <typename R, \
- typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<R> dispatch( \
- const Process<T>& process, \
- Future<R> (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- return dispatch(process.self(), method, ENUM_PARAMS(N, a)); \
- } \
- \
- template <typename R, \
- typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<R> dispatch( \
- const Process<T>* process, \
- Future<R> (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- return dispatch(process->self(), method, ENUM_PARAMS(N, a)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
-
-// Next, definitions of methods returning a value.
-//
-// template <typename R, typename T, typename ...P>
-// Future<R> dispatch(
-// const PID<T>& pid,
-// R (T::*method)(P...),
-// P... p)
-// {
-// std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk(
-// new std::tr1::function<R(T*)>(
-// std::tr1::bind(method,
-// std::tr1::placeholders::_1,
-// std::forward<P>(p)...)));
-//
-// std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
-// Future<R> future = promise->future();
-//
-// std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
-// new std::tr1::function<void(ProcessBase*)>(
-// std::tr1::bind(&internal::rdispatcher<R, T>,
-// std::tr1::placeholders::_1,
-// thunk, promise)));
-//
-// internal::dispatch(pid, dispatcher, internal::canonicalize(method));
-//
-// return future;
-// }
-
-template <typename R, typename T>
-Future<R> dispatch(
- const PID<T>& pid,
- R (T::*method)(void))
-{
- std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk(
- new std::tr1::function<R(T*)>(
- std::tr1::bind(method, std::tr1::placeholders::_1)));
-
- std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>());
- Future<R> future = promise->future();
-
- std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher(
- new std::tr1::function<void(ProcessBase*)>(
- std::tr1::bind(&internal::rdispatcher<R, T>,
- std::tr1::placeholders::_1,
- thunk, promise)));
-
- internal::dispatch(pid, dispatcher, internal::canonicalize(method));
-
- return future;
-}
-
-template <typename R, typename T>
-Future<R> dispatch(
- const Process<T>& process,
- R (T::*method)(void))
-{
- return dispatch(process.self(), method);
-}
-
-template <typename R, typename T>
-Future<R> dispatch(
- const Process<T>* process,
- R (T::*method)(void))
-{
- return dispatch(process->self(), method);
-}
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename R, \
- typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<R> dispatch( \
- const PID<T>& pid, \
- R (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- std::tr1::shared_ptr<std::tr1::function<R(T*)> > thunk( \
- new std::tr1::function<R(T*)>( \
- std::tr1::bind(method, \
- std::tr1::placeholders::_1, \
- ENUM_PARAMS(N, a)))); \
- \
- std::tr1::shared_ptr<Promise<R> > promise(new Promise<R>()); \
- Future<R> future = promise->future(); \
- \
- std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > dispatcher( \
- new std::tr1::function<void(ProcessBase*)>( \
- std::tr1::bind(&internal::rdispatcher<R, T>, \
- std::tr1::placeholders::_1, \
- thunk, promise))); \
- \
- internal::dispatch(pid, dispatcher, internal::canonicalize(method)); \
- \
- return future; \
- } \
- \
- template <typename R, \
- typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<R> dispatch( \
- const Process<T>& process, \
- R (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- return dispatch(process.self(), method, ENUM_PARAMS(N, a)); \
- } \
- \
- template <typename R, \
- typename T, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<R> dispatch( \
- const Process<T>* process, \
- R (T::*method)(ENUM_PARAMS(N, P)), \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- return dispatch(process->self(), method, ENUM_PARAMS(N, a)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
-} // namespace process {
-
-#endif // __PROCESS_DISPATCH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/event.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/event.hpp b/third_party/libprocess/include/process/event.hpp
deleted file mode 100644
index 84a8790..0000000
--- a/third_party/libprocess/include/process/event.hpp
+++ /dev/null
@@ -1,199 +0,0 @@
-#ifndef __PROCESS_EVENT_HPP__
-#define __PROCESS_EVENT_HPP__
-
-#include <tr1/functional>
-#include <tr1/memory> // TODO(benh): Replace all shared_ptr with unique_ptr.
-
-#include <process/future.hpp>
-#include <process/http.hpp>
-#include <process/message.hpp>
-#include <process/socket.hpp>
-
-namespace process {
-
-// Forward declarations.
-struct ProcessBase;
-struct MessageEvent;
-struct DispatchEvent;
-struct HttpEvent;
-struct ExitedEvent;
-struct TerminateEvent;
-
-
-struct EventVisitor
-{
- virtual ~EventVisitor() {}
- virtual void visit(const MessageEvent& event) {}
- virtual void visit(const DispatchEvent& event) {}
- virtual void visit(const HttpEvent& event) {}
- virtual void visit(const ExitedEvent& event) {}
- virtual void visit(const TerminateEvent& event) {}
-};
-
-
-struct Event
-{
- virtual ~Event() {}
-
- virtual void visit(EventVisitor* visitor) const = 0;
-
- template <typename T>
- bool is() const
- {
- bool result = false;
- struct IsVisitor : EventVisitor
- {
- IsVisitor(bool* _result) : result(_result) {}
- virtual void visit(const T& t) { *result = true; }
- bool* result;
- } visitor(&result);
- visit(&visitor);
- return result;
- }
-
- template <typename T>
- const T& as() const
- {
- const T* result = NULL;
- struct AsVisitor : EventVisitor
- {
- AsVisitor(const T** _result) : result(_result) {}
- virtual void visit(const T& t) { *result = &t; }
- const T** result;
- } visitor(&result);
- visit(&visitor);
- if (result == NULL) {
- std::cerr << "Attempting to \"cast\" event incorrectly!" << std::endl;
- abort();
- }
- return *result;
- }
-};
-
-
-struct MessageEvent : Event
-{
- MessageEvent(Message* _message)
- : message(_message) {}
-
- virtual ~MessageEvent()
- {
- delete message;
- }
-
- virtual void visit(EventVisitor* visitor) const
- {
- visitor->visit(*this);
- }
-
- Message* const message;
-
-private:
- // Not copyable, not assignable.
- MessageEvent(const MessageEvent&);
- MessageEvent& operator = (const MessageEvent&);
-};
-
-
-struct HttpEvent : Event
-{
- HttpEvent(const Socket& _socket, http::Request* _request)
- : socket(_socket), request(_request) {}
-
- virtual ~HttpEvent()
- {
- delete request;
- }
-
- virtual void visit(EventVisitor* visitor) const
- {
- visitor->visit(*this);
- }
-
- const Socket socket;
- http::Request* const request;
-
-private:
- // Not copyable, not assignable.
- HttpEvent(const HttpEvent&);
- HttpEvent& operator = (const HttpEvent&);
-};
-
-
-struct DispatchEvent : Event
-{
- DispatchEvent(
- const UPID& _pid,
- const std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> >& _f,
- const std::string& _method)
- : pid(_pid),
- f(_f),
- method(_method)
- {}
-
- virtual void visit(EventVisitor* visitor) const
- {
- visitor->visit(*this);
- }
-
- // PID receiving the dispatch.
- const UPID pid;
-
- // Function to get invoked as a result of this dispatch event.
- const std::tr1::shared_ptr<std::tr1::function<void(ProcessBase*)> > f;
-
- // Canonical "byte" representation of a pointer to a member function
- // (i.e., method) encapsulated in the above function (or empty if
- // not applicable). Note that we use a byte representation because a
- // pointer to a member function is not actually a pointer, but
- // instead a POD.
- // TODO(benh): Perform canonicalization lazily.
- const std::string method;
-
-private:
- // Not copyable, not assignable.
- DispatchEvent(const DispatchEvent&);
- DispatchEvent& operator = (const DispatchEvent&);
-};
-
-
-struct ExitedEvent : Event
-{
- ExitedEvent(const UPID& _pid)
- : pid(_pid) {}
-
- virtual void visit(EventVisitor* visitor) const
- {
- visitor->visit(*this);
- }
-
- const UPID pid;
-
-private:
- // Not copyable, not assignable.
- ExitedEvent(const ExitedEvent&);
- ExitedEvent& operator = (const ExitedEvent&);
-};
-
-
-struct TerminateEvent : Event
-{
- TerminateEvent(const UPID& _from)
- : from(_from) {}
-
- virtual void visit(EventVisitor* visitor) const
- {
- visitor->visit(*this);
- }
-
- const UPID from;
-
-private:
- // Not copyable, not assignable.
- TerminateEvent(const TerminateEvent&);
- TerminateEvent& operator = (const TerminateEvent&);
-};
-
-} // namespace event {
-
-#endif // __PROCESS_EVENT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/executor.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/executor.hpp b/third_party/libprocess/include/process/executor.hpp
deleted file mode 100644
index 72fb2f1..0000000
--- a/third_party/libprocess/include/process/executor.hpp
+++ /dev/null
@@ -1,260 +0,0 @@
-#ifndef __PROCESS_EXECUTOR_HPP__
-#define __PROCESS_EXECUTOR_HPP__
-
-#include <process/deferred.hpp>
-#include <process/dispatch.hpp>
-#include <process/id.hpp>
-#include <process/thread.hpp>
-
-#include <stout/preprocessor.hpp>
-
-namespace process {
-
-// Underlying "process" which handles invoking actual callbacks
-// created through an Executor.
-class ExecutorProcess : public Process<ExecutorProcess>
-{
-private:
- friend class Executor;
-
- ExecutorProcess() : ProcessBase(ID::generate("__executor__")) {}
- virtual ~ExecutorProcess() {}
-
- // Not copyable, not assignable.
- ExecutorProcess(const ExecutorProcess&);
- ExecutorProcess& operator = (const ExecutorProcess&);
-
- // No arg invoke.
- void invoke(const std::tr1::function<void(void)>& f) { f(); }
-
- // Args invoke.
-#define TEMPLATE(Z, N, DATA) \
- template <ENUM_PARAMS(N, typename A)> \
- void CAT(invoke, N)( \
- const std::tr1::function<void(ENUM_PARAMS(N, A))>& f, \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- f(ENUM_PARAMS(N, a)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-};
-
-
-// Provides an abstraction that can take a standard function object
-// and convert it to a 'Deferred'. Each converted function object will
-// get invoked serially with respect to one another.
-class Executor
-{
-public:
- Executor()
- {
- spawn(process);
- }
-
- ~Executor()
- {
- terminate(process);
- wait(process);
- }
-
- void stop()
- {
- terminate(process);
-
- // TODO(benh): Note that this doesn't wait because that could
- // cause a deadlock ... thus, the semantics here are that no more
- // dispatches will occur after this function returns but one may
- // be occuring concurrently.
- }
-
- // 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.
-private:
-#define TEMPLATE(Z, N, DATA) \
- typedef std::tr1::_Placeholder<INC(N)> _ ## N;
-
- REPEAT(10, TEMPLATE, _)
-#undef TEMPLATE
-
-public:
- // We provide wrappers for all standard function objects.
- Deferred<void(void)> defer(
- const std::tr1::function<void(void)>& f)
- {
- return Deferred<void(void)>(
- std::tr1::bind(
- &Executor::dispatcher,
- process.self(), 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) \
- { \
- return Deferred<void(ENUM_PARAMS(N, A))>( \
- std::tr1::bind( \
- &Executor::CAT(dispatcher, N)<ENUM_PARAMS(N, A)>, \
- process.self(), f, \
- ENUM_BINARY_PARAMS(N, _, () INTERCEPT))); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
- // Unfortunately, it is currently difficult to "forward" type
- // information from one result to another, so we must explicilty
- // define wrappers for all std::tr1::bind results. First we start
- // with the non-member std::tr1::bind results.
- Deferred<void(void)> defer(
- const std::tr1::_Bind<void(*(void))(void)>& b)
- {
- return defer(std::tr1::function<void(void)>(b));
- }
-
-#define TEMPLATE(Z, N, DATA) \
- template <ENUM_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind< \
- void(*(ENUM_PARAMS(N, _))) \
- (ENUM_PARAMS(N, A))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
- // Now the member std::tr1::bind results:
- // 1. Non-const member (function), non-const pointer (receiver).
- // 2. Const member, non-const pointer.
- // 3. Const member, const pointer.
- // 4. Non-const member, non-const reference.
- // 5. Const member, non-const reference.
- // 6. Const member, const reference.
- // 7. Non-const member, value.
- // 8. Const member, value.
-#define TEMPLATE(Z, N, DATA) \
- template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind<std::tr1::_Mem_fn< \
- void(T::*)(ENUM_PARAMS(N, A))> \
- (T* ENUM_TRAILING_PARAMS(N, _))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- } \
- \
- template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind<std::tr1::_Mem_fn< \
- void(T::*)(ENUM_PARAMS(N, A)) const> \
- (T* ENUM_TRAILING_PARAMS(N, _))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- } \
- \
- template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind<std::tr1::_Mem_fn< \
- void(T::*)(ENUM_PARAMS(N, A)) const> \
- (const T* ENUM_TRAILING_PARAMS(N, _))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- } \
- \
- template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind<std::tr1::_Mem_fn< \
- void(T::*)(ENUM_PARAMS(N, A))> \
- (std::tr1::reference_wrapper<T> ENUM_TRAILING_PARAMS(N, _))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- } \
- \
- template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind<std::tr1::_Mem_fn< \
- void(T::*)(ENUM_PARAMS(N, A)) const> \
- (std::tr1::reference_wrapper<T> ENUM_TRAILING_PARAMS(N, _))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- } \
- \
- template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind<std::tr1::_Mem_fn< \
- void(T::*)(ENUM_PARAMS(N, A)) const> \
- (std::tr1::reference_wrapper<const T> ENUM_TRAILING_PARAMS(N, _))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- } \
- \
- template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind<std::tr1::_Mem_fn< \
- void(T::*)(ENUM_PARAMS(N, A))> \
- (T ENUM_TRAILING_PARAMS(N, _))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- } \
- \
- template <typename T ENUM_TRAILING_PARAMS(N, typename A)> \
- Deferred<void(ENUM_PARAMS(N, A))> defer( \
- const std::tr1::_Bind<std::tr1::_Mem_fn< \
- void(T::*)(ENUM_PARAMS(N, A)) const> \
- (T ENUM_TRAILING_PARAMS(N, _))>& b) \
- { \
- return defer(std::tr1::function<void(ENUM_PARAMS(N, A))>(b)); \
- }
-
- REPEAT(11, TEMPLATE, _) // No args and args A0 -> A9.
-#undef TEMPLATE
-
-private:
- // Not copyable, not assignable.
- Executor(const Executor&);
- Executor& operator = (const Executor&);
-
- static void dispatcher(
- const PID<ExecutorProcess>& pid,
- const std::tr1::function<void(void)>& f)
- {
- // TODO(benh): Why not just use internal::dispatch?
- dispatch(pid, &ExecutorProcess::invoke, f);
- }
-
-#define TEMPLATE(Z, N, DATA) \
- template <ENUM_PARAMS(N, typename A)> \
- static void CAT(dispatcher, N)( \
- const PID<ExecutorProcess>& pid, \
- const std::tr1::function<void(ENUM_PARAMS(N, A))>& f, \
- ENUM_BINARY_PARAMS(N, A, a)) \
- { \
- dispatch( \
- pid, \
- &ExecutorProcess::CAT(invoke, N)<ENUM_PARAMS(N, A)>, \
- f, ENUM_PARAMS(N, a)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
- ExecutorProcess process;
-};
-
-
-// Per thread executor pointer. The extra level of indirection from
-// _executor_ to __executor__ is used in order to take advantage of
-// the ThreadLocal operators without needing the extra dereference as
-// well as lazily construct the actual executor.
-extern ThreadLocal<Executor>* _executor_;
-
-#define __executor__ \
- (*_executor_ == NULL ? *_executor_ = new Executor() : *_executor_)
-
-} // namespace process {
-
-#endif // __PROCESS_EXECUTOR_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/filter.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/filter.hpp b/third_party/libprocess/include/process/filter.hpp
deleted file mode 100644
index aa0c91b..0000000
--- a/third_party/libprocess/include/process/filter.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef __PROCESS_FILTER_HPP__
-#define __PROCESS_FILTER_HPP__
-
-#include <process/event.hpp>
-
-namespace process {
-
-class Filter {
-public:
- virtual ~Filter() {}
- virtual bool filter(const MessageEvent& event) { return false; }
- virtual bool filter(const DispatchEvent& event) { return false; }
- virtual bool filter(const HttpEvent& event) { return false; }
- virtual bool filter(const ExitedEvent& event) { return false; }
-};
-
-
-// Use the specified filter on messages that get enqueued (note,
-// however, that you cannot filter timeout messages).
-void filter(Filter* filter);
-
-} // namespace process {
-
-#endif // __PROCESS_FILTER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/future.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/future.hpp b/third_party/libprocess/include/process/future.hpp
deleted file mode 100644
index daf4b92..0000000
--- a/third_party/libprocess/include/process/future.hpp
+++ /dev/null
@@ -1,1060 +0,0 @@
-#ifndef __PROCESS_FUTURE_HPP__
-#define __PROCESS_FUTURE_HPP__
-
-#include <assert.h>
-#include <stdlib.h> // For abort.
-
-#include <iostream>
-#include <list>
-#include <queue>
-#include <set>
-
-#include <glog/logging.h>
-
-#include <tr1/functional>
-#include <tr1/memory> // TODO(benh): Replace shared_ptr with unique_ptr.
-
-#include <process/latch.hpp>
-#include <process/pid.hpp>
-
-#include <stout/duration.hpp>
-#include <stout/option.hpp>
-#include <stout/preprocessor.hpp>
-
-namespace process {
-
-// Forward declaration (instead of include to break circular dependency).
-template <typename _F> struct _Defer;
-
-namespace internal {
-
-template <typename T>
-struct wrap;
-
-template <typename T>
-struct unwrap;
-
-} // namespace internal {
-
-
-// Forward declaration of Promise.
-template <typename T>
-class Promise;
-
-
-// Definition of a "shared" future. A future can hold any
-// copy-constructible value. A future is considered "shared" because
-// by default a future can be accessed concurrently.
-template <typename T>
-class Future
-{
-public:
- // Constructs a failed future.
- static Future<T> failed(const std::string& message);
-
- Future();
- Future(const T& _t);
- Future(const Future<T>& that);
- ~Future();
-
- // Futures are assignable (and copyable). This results in the
- // reference to the previous future data being decremented and a
- // reference to 'that' being incremented.
- Future<T>& operator = (const Future<T>& that);
-
- // Comparision operators useful for using futures in collections.
- bool operator == (const Future<T>& that) const;
- bool operator < (const Future<T>& that) const;
-
- // Helpers to get the current state of this future.
- bool isPending() const;
- bool isReady() const;
- bool isDiscarded() const;
- bool isFailed() const;
-
- // Discards this future. This is similar to cancelling a future,
- // however it also occurs when the last reference to this future
- // gets cleaned up. Returns false if the future could not be
- // discarded (for example, because it is ready or failed).
- bool discard();
-
- // Waits for this future to become ready, discarded, or failed.
- bool await(const Duration& duration = Seconds(-1)) const;
-
- // Return the value associated with this future, waits indefinitely
- // until a value gets associated or until the future is discarded.
- T get() const;
-
- // Returns the failure message associated with this future.
- std::string failure() const;
-
- // Type of the callback functions that can get invoked when the
- // future gets set, fails, or is discarded.
- typedef std::tr1::function<void(const T&)> ReadyCallback;
- typedef std::tr1::function<void(const std::string&)> FailedCallback;
- typedef std::tr1::function<void(void)> DiscardedCallback;
- typedef std::tr1::function<void(const Future<T>&)> AnyCallback;
-
- // Installs callbacks for the specified events and returns a const
- // reference to 'this' in order to easily support chaining.
- const Future<T>& onReady(const ReadyCallback& callback) const;
- const Future<T>& onFailed(const FailedCallback& callback) const;
- const Future<T>& onDiscarded(const DiscardedCallback& callback) const;
- const Future<T>& onAny(const AnyCallback& callback) const;
-
- // Installs callbacks that get executed when this future is ready
- // and associates the result of the callback with the future that is
- // returned to the caller (which may be of a different type).
- template <typename X>
- Future<X> then(const std::tr1::function<Future<X>(const T&)>& f) const;
-
- template <typename X>
- Future<X> then(const std::tr1::function<X(const T&)>& f) const;
-
- // Helpers for the compiler to be able to forward std::tr1::bind results.
- template <typename X>
- Future<X> then(const std::tr1::_Bind<X(*(void))(void)>& b) const
- {
- return then(std::tr1::function<X(const T&)>(b));
- }
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename X, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<X> then( \
- const std::tr1::_Bind<X(*(ENUM_PARAMS(N, A))) \
- (ENUM_PARAMS(N, P))>& b) const \
- { \
- return then(std::tr1::function<X(const T&)>(b)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
- template <typename X>
- Future<X> then(const std::tr1::_Bind<Future<X>(*(void))(void)>& b) const
- {
- return then(std::tr1::function<Future<X>(const T&)>(b));
- }
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename X, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<X> then( \
- const std::tr1::_Bind<Future<X>(*(ENUM_PARAMS(N, A))) \
- (ENUM_PARAMS(N, P))>& b) const \
- { \
- return then(std::tr1::function<Future<X>(const T&)>(b)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
- // Helpers for the compiler to be able to forward 'defer' results.
- template <typename X, typename U>
- Future<X> then(const _Defer<Future<X>(*(PID<U>, X(U::*)(void)))
- (const PID<U>&, X(U::*)(void))>& d) const
- {
- return then(std::tr1::function<Future<X>(const T&)>(d));
- }
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename X, \
- typename U, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<X> then( \
- const _Defer<Future<X>(*(PID<U>, \
- X(U::*)(ENUM_PARAMS(N, P)), \
- ENUM_PARAMS(N, A))) \
- (const PID<U>&, \
- X(U::*)(ENUM_PARAMS(N, P)), \
- ENUM_PARAMS(N, P))>& d) const \
- { \
- return then(std::tr1::function<Future<X>(const T&)>(d)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
- template <typename X, typename U>
- Future<X> then(const _Defer<Future<X>(*(PID<U>, Future<X>(U::*)(void)))
- (const PID<U>&, Future<X>(U::*)(void))>& d) const
- {
- return then(std::tr1::function<Future<X>(const T&)>(d));
- }
-
-#define TEMPLATE(Z, N, DATA) \
- template <typename X, \
- typename U, \
- ENUM_PARAMS(N, typename P), \
- ENUM_PARAMS(N, typename A)> \
- Future<X> then( \
- const _Defer<Future<X>(*(PID<U>, \
- Future<X>(U::*)(ENUM_PARAMS(N, P)), \
- ENUM_PARAMS(N, A))) \
- (const PID<U>&, \
- Future<X>(U::*)(ENUM_PARAMS(N, P)), \
- ENUM_PARAMS(N, P))>& d) const \
- { \
- return then(std::tr1::function<Future<X>(const T&)>(d)); \
- }
-
- REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
-#undef TEMPLATE
-
- // C++11 implementation (covers all functors).
-#if __cplusplus >= 201103L
- template <typename F>
- auto then(F f) const
- -> typename internal::wrap<decltype(f(T()))>::Type;
-#endif
-
-private:
- friend class Promise<T>;
-
- // Sets the value for this future, unless the future is already set,
- // failed, or discarded, in which case it returns false.
- bool set(const T& _t);
-
- // Sets this future as failed, unless the future is already set,
- // failed, or discarded, in which case it returns false.
- bool fail(const std::string& _message);
-
- void copy(const Future<T>& that);
- void cleanup();
-
- enum State {
- PENDING,
- READY,
- FAILED,
- DISCARDED,
- };
-
- int* refs;
- int* lock;
- State* state;
- T** t;
- std::string** message; // Message associated with failure.
- std::queue<ReadyCallback>* onReadyCallbacks;
- std::queue<FailedCallback>* onFailedCallbacks;
- std::queue<DiscardedCallback>* onDiscardedCallbacks;
- std::queue<AnyCallback>* onAnyCallbacks;
- Latch* latch;
-};
-
-
-// TODO(benh): Make Promise a subclass of Future?
-template <typename T>
-class Promise
-{
-public:
- Promise();
- Promise(const T& t);
- ~Promise();
-
- bool set(const T& _t);
- bool set(const Future<T>& future); // Alias for associate.
- bool associate(const Future<T>& future);
- bool fail(const std::string& message);
-
- // Returns a copy of the future associated with this promise.
- Future<T> future() const;
-
-private:
- // Not copyable, not assignable.
- Promise(const Promise<T>&);
- Promise<T>& operator = (const Promise<T>&);
-
- Future<T> f;
-};
-
-
-template <>
-class Promise<void>;
-
-
-template <typename T>
-class Promise<T&>;
-
-
-template <typename T>
-Promise<T>::Promise() {}
-
-
-template <typename T>
-Promise<T>::Promise(const T& t)
- : f(t) {}
-
-
-template <typename T>
-Promise<T>::~Promise() {}
-
-
-template <typename T>
-bool Promise<T>::set(const T& t)
-{
- return f.set(t);
-}
-
-
-template <typename T>
-bool Promise<T>::set(const Future<T>& future)
-{
- return associate(future);
-}
-
-
-template <typename T>
-bool Promise<T>::associate(const Future<T>& future)
-{
- if (!f.isPending()) {
- return false;
- }
-
- future
- .onReady(std::tr1::bind(&Future<T>::set, f, std::tr1::placeholders::_1))
- .onFailed(std::tr1::bind(&Future<T>::fail, f, std::tr1::placeholders::_1))
- .onDiscarded(std::tr1::bind(&Future<T>::discard, f));
-
- return true;
-}
-
-
-template <typename T>
-bool Promise<T>::fail(const std::string& message)
-{
- return f.fail(message);
-}
-
-
-template <typename T>
-Future<T> Promise<T>::future() const
-{
- return f;
-}
-
-
-// Internal helper utilities.
-namespace internal {
-
-template <typename T>
-struct wrap
-{
- typedef Future<T> Type;
-};
-
-
-template <typename X>
-struct wrap<Future<X> >
-{
- typedef Future<X> Type;
-};
-
-
-template <typename T>
-struct unwrap
-{
- typedef T Type;
-};
-
-
-template <typename X>
-struct unwrap<Future<X> >
-{
- typedef X Type;
-};
-
-
-inline void acquire(int* lock)
-{
- while (!__sync_bool_compare_and_swap(lock, 0, 1)) {
- asm volatile ("pause");
- }
-}
-
-
-inline void release(int* lock)
-{
- // Unlock via a compare-and-swap so we get a memory barrier too.
- bool unlocked = __sync_bool_compare_and_swap(lock, 1, 0);
- assert(unlocked);
-}
-
-
-template <typename T>
-void select(
- const Future<T>& future,
- std::tr1::shared_ptr<Promise<Future<T > > > promise)
-{
- // We never fail the future associated with our promise.
- assert(!promise->future().isFailed());
-
- if (promise->future().isPending()) { // No-op if it's discarded.
- if (future.isReady()) { // We only set the promise if a future is ready.
- promise->set(future);
- }
- }
-}
-
-} // namespace internal {
-
-
-// TODO(benh): Move select and discard into 'futures' namespace.
-
-// Returns a future that captures any ready future in a set. Note that
-// select DOES NOT capture a future that has failed or been discarded.
-template <typename T>
-Future<Future<T> > select(const std::set<Future<T> >& futures)
-{
- std::tr1::shared_ptr<Promise<Future<T> > > promise(
- new Promise<Future<T> >());
-
- Future<Future<T> > future = promise->future();
-
- std::tr1::function<void(const Future<T>&)> select =
- std::tr1::bind(&internal::select<T>,
- std::tr1::placeholders::_1,
- promise);
-
- typename std::set<Future<T> >::iterator iterator;
- for (iterator = futures.begin(); iterator != futures.end(); ++iterator) {
- (*iterator).onAny(std::tr1::bind(select, std::tr1::placeholders::_1));
- }
-
- return future;
-}
-
-
-template <typename T>
-void discard(const std::set<Future<T> >& futures)
-{
- typename std::set<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();
- }
-}
-
-
-template <typename T>
-void discard(const std::list<Future<T> >& futures)
-{
- 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();
- }
-}
-
-
-template <class T>
-void fail(const std::vector<Promise<T>*>& promises, const std::string& message)
-{
- typename std::vector<Promise<T>*>::const_iterator iterator;
- for (iterator = promises.begin(); iterator != promises.end(); ++iterator) {
- Promise<T>* promise = *iterator;
- promise->fail(message);
- }
-}
-
-
-template <class T>
-void fail(const std::list<Promise<T>*>& promises, const std::string& message)
-{
- typename std::list<Promise<T>*>::const_iterator iterator;
- for (iterator = promises.begin(); iterator != promises.end(); ++iterator) {
- Promise<T>* promise = *iterator;
- promise->fail(message);
- }
-}
-
-
-template <typename T>
-Future<T> Future<T>::failed(const std::string& message)
-{
- Future<T> future;
- future.fail(message);
- return future;
-}
-
-
-template <typename T>
-Future<T>::Future()
- : refs(new int(1)),
- lock(new int(0)),
- state(new State(PENDING)),
- t(new T*(NULL)),
- message(new std::string*(NULL)),
- onReadyCallbacks(new std::queue<ReadyCallback>()),
- onFailedCallbacks(new std::queue<FailedCallback>()),
- onDiscardedCallbacks(new std::queue<DiscardedCallback>()),
- onAnyCallbacks(new std::queue<AnyCallback>()),
- latch(new Latch()) {}
-
-
-template <typename T>
-Future<T>::Future(const T& _t)
- : refs(new int(1)),
- lock(new int(0)),
- state(new State(PENDING)),
- t(new T*(NULL)),
- message(new std::string*(NULL)),
- onReadyCallbacks(new std::queue<ReadyCallback>()),
- onFailedCallbacks(new std::queue<FailedCallback>()),
- onDiscardedCallbacks(new std::queue<DiscardedCallback>()),
- onAnyCallbacks(new std::queue<AnyCallback>()),
- latch(new Latch())
-{
- set(_t);
-}
-
-
-template <typename T>
-Future<T>::Future(const Future<T>& that)
-{
- copy(that);
-}
-
-
-template <typename T>
-Future<T>::~Future()
-{
- cleanup();
-}
-
-
-template <typename T>
-Future<T>& Future<T>::operator = (const Future<T>& that)
-{
- if (this != &that) {
- cleanup();
- copy(that);
- }
- return *this;
-}
-
-
-template <typename T>
-bool Future<T>::operator == (const Future<T>& that) const
-{
- assert(latch != NULL);
- assert(that.latch != NULL);
- return *latch == *that.latch;
-}
-
-
-template <typename T>
-bool Future<T>::operator < (const Future<T>& that) const
-{
- assert(latch != NULL);
- assert(that.latch != NULL);
- return *latch < *that.latch;
-}
-
-
-template <typename T>
-bool Future<T>::discard()
-{
- bool result = false;
-
- assert(lock != NULL);
- internal::acquire(lock);
- {
- assert(state != NULL);
- if (*state == PENDING) {
- *state = DISCARDED;
- latch->trigger();
- result = true;
- }
- }
- internal::release(lock);
-
- // Invoke all callbacks associated with this future being
- // DISCARDED. We don't need a lock because the state is now in
- // DISCARDED so there should not be any concurrent modifications.
- if (result) {
- while (!onDiscardedCallbacks->empty()) {
- // TODO(*): Invoke callbacks in another execution context.
- onDiscardedCallbacks->front()();
- onDiscardedCallbacks->pop();
- }
-
- while (!onAnyCallbacks->empty()) {
- // TODO(*): Invoke callbacks in another execution context.
- onAnyCallbacks->front()(*this);
- onAnyCallbacks->pop();
- }
- }
-
- return result;
-}
-
-
-template <typename T>
-bool Future<T>::isPending() const
-{
- assert(state != NULL);
- return *state == PENDING;
-}
-
-
-template <typename T>
-bool Future<T>::isReady() const
-{
- assert(state != NULL);
- return *state == READY;
-}
-
-
-template <typename T>
-bool Future<T>::isDiscarded() const
-{
- assert(state != NULL);
- return *state == DISCARDED;
-}
-
-
-template <typename T>
-bool Future<T>::isFailed() const
-{
- assert(state != NULL);
- return *state == FAILED;
-}
-
-
-template <typename T>
-bool Future<T>::await(const Duration& duration) const
-{
- if (!isReady() && !isDiscarded() && !isFailed()) {
- assert(latch != NULL);
- return latch->await(duration);
- }
- return true;
-}
-
-
-template <typename T>
-T Future<T>::get() const
-{
- if (!isReady()) {
- await();
- }
-
- CHECK(!isPending()) << "Future was in PENDING after await()";
-
- if (!isReady()) {
- if (isFailed()) {
- std::cerr << "Future::get() but state == FAILED: "
- << failure() << std::endl;
- } else if (isDiscarded()) {
- std::cerr << "Future::get() but state == DISCARDED" << std::endl;
- }
- abort();
- }
-
- assert(t != NULL);
- assert(*t != NULL);
- return **t;
-}
-
-
-template <typename T>
-std::string Future<T>::failure() const
-{
- assert(message != NULL);
- if (*message != NULL) {
- return **message;
- }
-
- return "";
-}
-
-
-template <typename T>
-const Future<T>& Future<T>::onReady(const ReadyCallback& callback) const
-{
- bool run = false;
-
- assert(lock != NULL);
- internal::acquire(lock);
- {
- assert(state != NULL);
- if (*state == READY) {
- run = true;
- } else if (*state == PENDING) {
- onReadyCallbacks->push(callback);
- }
- }
- internal::release(lock);
-
- // TODO(*): Invoke callback in another execution context.
- if (run) {
- callback(**t);
- }
-
- return *this;
-}
-
-
-template <typename T>
-const Future<T>& Future<T>::onFailed(const FailedCallback& callback) const
-{
- bool run = false;
-
- assert(lock != NULL);
- internal::acquire(lock);
- {
- assert(state != NULL);
- if (*state == FAILED) {
- run = true;
- } else if (*state == PENDING) {
- onFailedCallbacks->push(callback);
- }
- }
- internal::release(lock);
-
- // TODO(*): Invoke callback in another execution context.
- if (run) {
- callback(**message);
- }
-
- return *this;
-}
-
-
-template <typename T>
-const Future<T>& Future<T>::onDiscarded(
- const DiscardedCallback& callback) const
-{
- bool run = false;
-
- assert(lock != NULL);
- internal::acquire(lock);
- {
- assert(state != NULL);
- if (*state == DISCARDED) {
- run = true;
- } else if (*state == PENDING) {
- onDiscardedCallbacks->push(callback);
- }
- }
- internal::release(lock);
-
- // TODO(*): Invoke callback in another execution context.
- if (run) {
- callback();
- }
-
- return *this;
-}
-
-
-template <typename T>
-const Future<T>& Future<T>::onAny(const AnyCallback& callback) const
-{
- bool run = false;
-
- assert(lock != NULL);
- internal::acquire(lock);
- {
- assert(state != NULL);
- if (*state != PENDING) {
- run = true;
- } else if (*state == PENDING) {
- onAnyCallbacks->push(callback);
- }
- }
- internal::release(lock);
-
- // TODO(*): Invoke callback in another execution context.
- if (run) {
- callback(*this);
- }
-
- return *this;
-}
-
-
-namespace internal {
-
-template <typename T, typename X>
-void thenf(const std::tr1::shared_ptr<Promise<X> >& promise,
- const std::tr1::function<Future<X>(const T&)>& f,
- const Future<T>& future)
-{
- if (future.isReady()) {
- promise->associate(f(future.get()));
- } else if (future.isFailed()) {
- promise->fail(future.failure());
- } else if (future.isDiscarded()) {
- promise->future().discard();
- }
-}
-
-
-template <typename T, typename X>
-void then(const std::tr1::shared_ptr<Promise<X> >& promise,
- const std::tr1::function<X(const T&)>& f,
- const Future<T>& future)
-{
- if (future.isReady()) {
- promise->set(f(future.get()));
- } else if (future.isFailed()) {
- promise->fail(future.failure());
- } else if (future.isDiscarded()) {
- promise->future().discard();
- }
-}
-
-} // namespace internal {
-
-
-template <typename T>
-template <typename X>
-Future<X> Future<T>::then(const std::tr1::function<Future<X>(const T&)>& f) const
-{
- std::tr1::shared_ptr<Promise<X> > promise(new Promise<X>());
-
- std::tr1::function<void(const Future<T>&)> thenf =
- std::tr1::bind(&internal::thenf<T, X>,
- promise,
- f,
- std::tr1::placeholders::_1);
-
- onAny(thenf);
-
- // Propagate discarding up the chain (note that we bind with a copy
- // of this future since 'this' might no longer be valid but other
- // references might still exist.
- // TODO(benh): Need to pass 'future' as a weak_ptr so that we can
- // avoid reference counting cycles!
- std::tr1::function<void(void)> discard =
- std::tr1::bind(&Future<T>::discard, *this);
-
- promise->future().onDiscarded(discard);
-
- return promise->future();
-}
-
-
-template <typename T>
-template <typename X>
-Future<X> Future<T>::then(const std::tr1::function<X(const T&)>& f) const
-{
- std::tr1::shared_ptr<Promise<X> > promise(new Promise<X>());
-
- std::tr1::function<void(const Future<T>&)> then =
- std::tr1::bind(&internal::then<T, X>,
- promise,
- f,
- std::tr1::placeholders::_1);
-
- onAny(then);
-
- // Propagate discarding up the chain (note that we bind with a copy
- // of this future since 'this' might no longer be valid but other
- // references might still exist.
- // TODO(benh): Need to pass 'future' as a weak_ptr so that we can
- // avoid reference counting cycles!
- std::tr1::function<void(void)> discard =
- std::tr1::bind(&Future<T>::discard, *this);
-
- promise->future().onDiscarded(discard);
-
- return promise->future();
-}
-
-
-#if __cplusplus >= 201103L
-template <typename T>
-template <typename F>
-auto Future<T>::then(F f) const
- -> typename internal::wrap<decltype(f(T()))>::Type
-{
- typedef typename internal::unwrap<decltype(f(T()))>::Type X;
-
- std::tr1::shared_ptr<Promise<X>> promise(new Promise<X>());
-
- onAny([=] (const Future<T>& future) {
- if (future.isReady()) {
- promise->set(f(future.get()));
- } else if (future.isFailed()) {
- promise->fail(future.failure());
- } else if (future.isDiscarded()) {
- promise->future().discard();
- }
- });
-
- // TODO(benh): Need to use weak_ptr here so that we can avoid
- // reference counting cycles!
- Future<T> future(*this);
-
- promise->future().onDiscarded([=] () {
- future.discard(); // Need a non-const copy to discard.
- });
-
- return promise->future();
-}
-#endif
-
-
-template <typename T>
-bool Future<T>::set(const T& _t)
-{
- bool result = false;
-
- assert(lock != NULL);
- internal::acquire(lock);
- {
- assert(state != NULL);
- if (*state == PENDING) {
- *t = new T(_t);
- *state = READY;
- latch->trigger();
- result = true;
- }
- }
- internal::release(lock);
-
- // Invoke all callbacks associated with this future being READY. We
- // don't need a lock because the state is now in READY so there
- // should not be any concurrent modications.
- if (result) {
- while (!onReadyCallbacks->empty()) {
- // TODO(*): Invoke callbacks in another execution context.
- onReadyCallbacks->front()(**t);
- onReadyCallbacks->pop();
- }
-
- while (!onAnyCallbacks->empty()) {
- // TODO(*): Invoke callbacks in another execution context.
- onAnyCallbacks->front()(*this);
- onAnyCallbacks->pop();
- }
- }
-
- return result;
-}
-
-
-template <typename T>
-bool Future<T>::fail(const std::string& _message)
-{
- bool result = false;
-
- assert(lock != NULL);
- internal::acquire(lock);
- {
- assert(state != NULL);
- if (*state == PENDING) {
- *message = new std::string(_message);
- *state = FAILED;
- latch->trigger();
- result = true;
- }
- }
- internal::release(lock);
-
- // Invoke all callbacks associated with this future being FAILED. We
- // don't need a lock because the state is now in FAILED so there
- // should not be any concurrent modications.
- if (result) {
- while (!onFailedCallbacks->empty()) {
- // TODO(*): Invoke callbacks in another execution context.
- onFailedCallbacks->front()(**message);
- onFailedCallbacks->pop();
- }
-
- while (!onAnyCallbacks->empty()) {
- // TODO(*): Invoke callbacks in another execution context.
- onAnyCallbacks->front()(*this);
- onAnyCallbacks->pop();
- }
- }
-
- return result;
-}
-
-
-template <typename T>
-void Future<T>::copy(const Future<T>& that)
-{
- assert(that.refs > 0);
- __sync_fetch_and_add(that.refs, 1);
- refs = that.refs;
- lock = that.lock;
- state = that.state;
- t = that.t;
- message = that.message;
- onReadyCallbacks = that.onReadyCallbacks;
- onFailedCallbacks = that.onFailedCallbacks;
- onDiscardedCallbacks = that.onDiscardedCallbacks;
- onAnyCallbacks = that.onAnyCallbacks;
- latch = that.latch;
-}
-
-
-template <typename T>
-void Future<T>::cleanup()
-{
- assert(refs != NULL);
- if (__sync_sub_and_fetch(refs, 1) == 0) {
- // Discard the future if it is still pending (so we invoke any
- // discarded callbacks that have been setup). Note that we put the
- // reference count back at 1 here in case one of the callbacks
- // decides it wants to keep a reference.
- assert(state != NULL);
- if (*state == PENDING) {
- *refs = 1;
- discard();
- __sync_sub_and_fetch(refs, 1);
- }
-
- // Now try and cleanup again (this time we know the future has
- // either been discarded or was not pending). Note that one of the
- // callbacks might have stored the future, in which case we'll
- // just return without doing anything, but the state will forever
- // be "discarded".
- assert(refs != NULL);
- if (*refs == 0) {
- delete refs;
- refs = NULL;
- assert(lock != NULL);
- delete lock;
- lock = NULL;
- assert(state != NULL);
- delete state;
- state = NULL;
- assert(t != NULL);
- delete *t;
- delete t;
- t = NULL;
- assert(message != NULL);
- delete *message;
- delete message;
- message = NULL;
- assert(onReadyCallbacks != NULL);
- delete onReadyCallbacks;
- onReadyCallbacks = NULL;
- assert(onFailedCallbacks != NULL);
- delete onFailedCallbacks;
- onFailedCallbacks = NULL;
- assert(onDiscardedCallbacks != NULL);
- delete onDiscardedCallbacks;
- onDiscardedCallbacks = NULL;
- assert(onAnyCallbacks != NULL);
- delete onAnyCallbacks;
- onAnyCallbacks = NULL;
- assert(latch != NULL);
- delete latch;
- latch = NULL;
- }
- }
-}
-
-} // namespace process {
-
-#endif // __PROCESS_FUTURE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/gc.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/gc.hpp b/third_party/libprocess/include/process/gc.hpp
deleted file mode 100644
index e83c636..0000000
--- a/third_party/libprocess/include/process/gc.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __PROCESS_GC_HPP__
-#define __PROCESS_GC_HPP__
-
-#include <map>
-
-#include <process/process.hpp>
-
-
-namespace process {
-
-class GarbageCollector : public Process<GarbageCollector>
-{
-public:
- GarbageCollector() : ProcessBase("__gc__") {}
- virtual ~GarbageCollector() {}
-
- template <typename T>
- void manage(const T* t)
- {
- const ProcessBase* process = t;
- if (process != NULL) {
- processes[process->self()] = process;
- link(process->self());
- }
- }
-
-protected:
- virtual void exited(const UPID& pid)
- {
- if (processes.count(pid) > 0) {
- const ProcessBase* process = processes[pid];
- processes.erase(pid);
- delete process;
- }
- }
-
-private:
- std::map<UPID, const ProcessBase*> processes;
-};
-
-
-extern PID<GarbageCollector> gc;
-
-} // namespace process {
-
-#endif // __PROCESS_GC_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/71a01bd9/third_party/libprocess/include/process/gmock.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/gmock.hpp b/third_party/libprocess/include/process/gmock.hpp
deleted file mode 100644
index a8cab4c..0000000
--- a/third_party/libprocess/include/process/gmock.hpp
+++ /dev/null
@@ -1,327 +0,0 @@
-#ifndef __PROCESS_GMOCK_HPP__
-#define __PROCESS_GMOCK_HPP__
-
-#include <pthread.h>
-
-#include <gmock/gmock.h>
-
-#include <tr1/tuple>
-
-#include <process/dispatch.hpp>
-#include <process/event.hpp>
-#include <process/filter.hpp>
-#include <process/pid.hpp>
-
-#include <stout/exit.hpp>
-#include <stout/nothing.hpp>
-
-
-// THIS IS DEPRECATED AND BROKEN! REPLACE ALL USES!
-#define EXPECT_MESSAGE(name, from, to) \
- EXPECT_CALL(*new process::MockFilter(), \
- filter(testing::A<const process::MessageEvent&>())) \
- .With(process::MessageMatcher(name, from, to))
-
-
-// THIS IS DEPRECATED AND BROKEN! REPLACE ALL USES!
-#define EXPECT_DISPATCH(pid, method) \
- EXPECT_CALL(*new process::MockFilter(), \
- filter(testing::A<const process::DispatchEvent&>())) \
- .With(process::DispatchMatcher(pid, method))
-
-
-#define FUTURE_MESSAGE(name, from, to) \
- process::FutureMessage(name, from, to)
-
-#define DROP_MESSAGE(name, from, to) \
- process::FutureMessage(name, from, to, true)
-
-#define FUTURE_DISPATCH(pid, method) \
- process::FutureDispatch(pid, method)
-
-#define DROP_DISPATCH(pid, method) \
- process::FutureDispatch(pid, method, true)
-
-#define DROP_MESSAGES(name, from, to) \
- process::DropMessages(name, from, to)
-
-#define DROP_DISPATCHES(pid, method) \
- process::DropDispatches(pid, method)
-
-
-ACTION_TEMPLATE(PromiseArg,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_1_VALUE_PARAMS(promise))
-{
- // TODO(benh): Use a shared_ptr for promise to defend against this
- // action getting invoked more than once (e.g., used via
- // WillRepeatedly). We won't be able to set it a second time but at
- // least we won't get a segmentation fault. We could also consider
- // warning users if they attempted to set it more than once.
- promise->set(std::tr1::get<k>(args));
- delete promise;
-}
-
-
-template <int index, typename T>
-PromiseArgActionP<index, process::Promise<T>*> FutureArg(
- process::Future<T>* future)
-{
- process::Promise<T>* promise = new process::Promise<T>();
- *future = promise->future();
- return PromiseArg<index>(promise);
-}
-
-
-ACTION_TEMPLATE(PromiseArgField,
- HAS_1_TEMPLATE_PARAMS(int, k),
- AND_2_VALUE_PARAMS(field, promise))
-{
- // TODO(benh): Use a shared_ptr for promise to defend against this
- // action getting invoked more than once (e.g., used via
- // WillRepeatedly). We won't be able to set it a second time but at
- // least we won't get a segmentation fault. We could also consider
- // warning users if they attempted to set it more than once.
- promise->set(*(std::tr1::get<k>(args).*field));
- delete promise;
-}
-
-
-template <int index, typename Field, typename T>
-PromiseArgFieldActionP2<index, Field, process::Promise<T>*> FutureArgField(
- Field field,
- process::Future<T>* future)
-{
- process::Promise<T>* promise = new process::Promise<T>();
- *future = promise->future();
- return PromiseArgField<index>(field, promise);
-}
-
-
-ACTION_P2(PromiseSatisfy, promise, value)
-{
- promise->set(value);
- delete promise;
-}
-
-
-template <typename T>
-PromiseSatisfyActionP2<process::Promise<T>*, T> FutureSatisfy(
- process::Future<T>* future,
- T t)
-{
- process::Promise<T>* promise = new process::Promise<T>();
- *future = promise->future();
- return PromiseSatisfy(promise, t);
-}
-
-
-inline PromiseSatisfyActionP2<process::Promise<Nothing>*, Nothing>
-FutureSatisfy(process::Future<Nothing>* future)
-{
- process::Promise<Nothing>* promise = new process::Promise<Nothing>();
- *future = promise->future();
- return PromiseSatisfy(promise, Nothing());
-}
-
-
-namespace process {
-
-class MockFilter : public Filter
-{
-public:
- MockFilter()
- {
- EXPECT_CALL(*this, filter(testing::A<const MessageEvent&>()))
- .WillRepeatedly(testing::Return(false));
- EXPECT_CALL(*this, filter(testing::A<const DispatchEvent&>()))
- .WillRepeatedly(testing::Return(false));
- EXPECT_CALL(*this, filter(testing::A<const HttpEvent&>()))
- .WillRepeatedly(testing::Return(false));
- EXPECT_CALL(*this, filter(testing::A<const ExitedEvent&>()))
- .WillRepeatedly(testing::Return(false));
- }
-
- MOCK_METHOD1(filter, bool(const MessageEvent&));
- MOCK_METHOD1(filter, bool(const DispatchEvent&));
- MOCK_METHOD1(filter, bool(const HttpEvent&));
- MOCK_METHOD1(filter, bool(const ExitedEvent&));
-};
-
-
-// A definition of a libprocess filter to enable waiting for events
-// (such as messages or dispatches) via in tests. This is not meant to
-// be used directly by tests; tests should use macros like
-// FUTURE_MESSAGE and FUTURE_DISPATCH instead.
-class TestsFilter : public Filter
-{
-public:
- TestsFilter()
- {
- // We use a recursive mutex here in the event that satisfying the
- // future created in FutureMessage or FutureDispatch via the
- // FutureArgField or FutureSatisfy actions invokes callbacks (from
- // Future::then or Future::onAny, etc) that themselves invoke
- // FutureDispatch or FutureMessage.
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&mutex, &attr);
- pthread_mutexattr_destroy(&attr);
- }
-
- virtual bool filter(const MessageEvent& event) { return handle(event); }
- virtual bool filter(const DispatchEvent& event) { return handle(event); }
- virtual bool filter(const HttpEvent& event) { return handle(event); }
- virtual bool filter(const ExitedEvent& event) { return handle(event); }
-
- template <typename T>
- bool handle(const T& t)
- {
- pthread_mutex_lock(&mutex);
- bool drop = mock.filter(t);
- pthread_mutex_unlock(&mutex);
- return drop;
- }
-
- MockFilter mock;
- pthread_mutex_t mutex;;
-};
-
-
-class FilterTestEventListener : public ::testing::EmptyTestEventListener
-{
-public:
- // Returns the singleton instance of the listener.
- static FilterTestEventListener* instance()
- {
- static FilterTestEventListener* listener = new FilterTestEventListener();
- return listener;
- }
-
- // Installs and returns the filter, creating it if necessary.
- TestsFilter* install()
- {
- if (!started) {
- EXIT(1)
- << "To use FUTURE/DROP_MESSAGE/DISPATCH, etc. you need to do the "
- << "following before you invoke RUN_ALL_TESTS():\n\n"
- << "\t::testing::TestEventListeners& listeners =\n"
- << "\t ::testing::UnitTest::GetInstance()->listeners();\n"
- << "\tlisteners.Append(process::FilterTestEventListener::instance());";
- }
-
- if (filter != NULL) {
- return filter;
- }
-
- filter = new TestsFilter();
-
- // Set the filter in libprocess.
- process::filter(filter);
-
- return filter;
- }
-
- virtual void OnTestProgramStart(const ::testing::UnitTest&)
- {
- started = true;
- }
-
- virtual void OnTestEnd(const ::testing::TestInfo&)
- {
- if (filter != NULL) {
- // Remove the filter in libprocess _before_ deleting.
- process::filter(NULL);
- delete filter;
- filter = NULL;
- }
- }
-
-private:
- FilterTestEventListener() : filter(NULL), started(false) {}
-
- TestsFilter* filter;
-
- // Indicates if we got the OnTestProgramStart callback in order to
- // detect if we have been properly added as a listener.
- bool started;
-};
-
-
-MATCHER_P3(MessageMatcher, name, from, to, "")
-{
- const MessageEvent& event = ::std::tr1::get<0>(arg);
- return (testing::Matcher<std::string>(name).Matches(event.message->name) &&
- testing::Matcher<UPID>(from).Matches(event.message->from) &&
- testing::Matcher<UPID>(to).Matches(event.message->to));
-}
-
-
-MATCHER_P2(DispatchMatcher, pid, method, "")
-{
- const DispatchEvent& event = ::std::tr1::get<0>(arg);
- return (testing::Matcher<UPID>(pid).Matches(event.pid) &&
- testing::Matcher<std::string>(internal::canonicalize(method))
- .Matches(event.method));
-}
-
-
-template <typename Name, typename From, typename To>
-Future<Message> FutureMessage(Name name, From from, To to, bool drop = false)
-{
- TestsFilter* filter = FilterTestEventListener::instance()->install();
- pthread_mutex_lock(&filter->mutex);
- Future<Message> future;
- EXPECT_CALL(filter->mock, filter(testing::A<const MessageEvent&>()))
- .With(MessageMatcher(name, from, to))
- .WillOnce(testing::DoAll(FutureArgField<0>(&MessageEvent::message, &future),
- testing::Return(drop)))
- .RetiresOnSaturation(); // Don't impose any subsequent expectations.
- pthread_mutex_unlock(&filter->mutex);
- return future;
-}
-
-
-template <typename PID, typename Method>
-Future<Nothing> FutureDispatch(PID pid, Method method, bool drop = false)
-{
- TestsFilter* filter = FilterTestEventListener::instance()->install();
- pthread_mutex_lock(&filter->mutex);
- Future<Nothing> future;
- EXPECT_CALL(filter->mock, filter(testing::A<const DispatchEvent&>()))
- .With(DispatchMatcher(pid, method))
- .WillOnce(testing::DoAll(FutureSatisfy(&future),
- testing::Return(drop)))
- .RetiresOnSaturation(); // Don't impose any subsequent expectations.
- pthread_mutex_unlock(&filter->mutex);
- return future;
-}
-
-
-template <typename Name, typename From, typename To>
-void DropMessages(Name name, From from, To to)
-{
- TestsFilter* filter = FilterTestEventListener::instance()->install();
- pthread_mutex_lock(&filter->mutex);
- EXPECT_CALL(filter->mock, filter(testing::A<const MessageEvent&>()))
- .With(MessageMatcher(name, from, to))
- .WillRepeatedly(testing::Return(true));
- pthread_mutex_unlock(&filter->mutex);
-}
-
-
-template <typename PID, typename Method>
-void DropDispatches(PID pid, Method method)
-{
- TestsFilter* filter = FilterTestEventListener::instance()->install();
- pthread_mutex_lock(&filter->mutex);
- EXPECT_CALL(filter->mock, filter(testing::A<const DispatchEvent&>()))
- .With(DispatchMatcher(pid, method))
- .WillRepeatedly(testing::Return(true));
- pthread_mutex_unlock(&filter->mutex);
-}
-
-} // namespace process {
-
-#endif // __PROCESS_GMOCK_HPP__
[04/35] Updated libprocess to use '3rdparty' instead of 'third_party'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/3rdparty/stout/tests/os_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/os_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/os_tests.cpp
new file mode 100644
index 0000000..047778d
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/proc_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/proc_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/proc_tests.cpp
new file mode 100644
index 0000000..2305ef5
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/strings_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/strings_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/strings_tests.cpp
new file mode 100644
index 0000000..7ec9446
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/stout/tests/uuid_tests.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/stout/tests/uuid_tests.cpp b/third_party/libprocess/3rdparty/stout/tests/uuid_tests.cpp
new file mode 100644
index 0000000..ad1d986
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/3rdparty/versions.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/3rdparty/versions.am b/third_party/libprocess/3rdparty/versions.am
new file mode 100644
index 0000000..0d05698
--- /dev/null
+++ b/third_party/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/bc531d3c/third_party/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/Makefile.am b/third_party/libprocess/Makefile.am
index c1db145..b6b8abd 100644
--- a/third_party/libprocess/Makefile.am
+++ b/third_party/libprocess/Makefile.am
@@ -1,22 +1,22 @@
-# Makefile for libprocess. Note that third_party needs to be built
-# first (see third_party/Makefile.am).
+# Makefile for libprocess. Note that 3rdparty needs to be built
+# first (see 3rdparty/Makefile.am).
ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = foreign
-SUBDIRS = third_party .
+SUBDIRS = 3rdparty .
-include third_party/versions.am
+include 3rdparty/versions.am
-STOUT = third_party/stout
-BOOST = third_party/boost-$(BOOST_VERSION)
-GLOG = third_party/glog-$(GLOG_VERSION)
-GMOCK = third_party/gmock-$(GMOCK_VERSION)
-GPERFTOOLS = third_party/gperftools-$(GPERFTOOLS_VERSION)
+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 = third_party/ry-http-parser-$(RY_HTTP_PARSER_VERSION)
-LIBEV = third_party/libev-$(LIBEV_VERSION)
+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
@@ -48,7 +48,7 @@ libprocess_la_CPPFLAGS = \
libprocess_la_LIBADD = \
$(GLOG)/libglog.la \
- third_party/libry_http_parser.la \
+ 3rdparty/libry_http_parser.la \
$(LIBEV)/libev.la
if HAS_GPERFTOOLS
@@ -111,7 +111,7 @@ tests_CPPFLAGS = \
-I$(GMOCK)/include \
$(libprocess_la_CPPFLAGS)
-tests_LDADD = third_party/libgmock.la libprocess.la
+tests_LDADD = 3rdparty/libgmock.la libprocess.la
TESTS = tests
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/configure.ac
----------------------------------------------------------------------
diff --git a/third_party/libprocess/configure.ac b/third_party/libprocess/configure.ac
index efa7783..d3b86a3 100644
--- a/third_party/libprocess/configure.ac
+++ b/third_party/libprocess/configure.ac
@@ -35,18 +35,18 @@ LT_OUTPUT
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
+# Save the configure arguments so we can pass them to any third-party
# libraries that we might run configure on (see
-# third_party/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.
+# 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([third_party/stout])
+AC_CONFIG_SUBDIRS([3rdparty/stout])
AC_CONFIG_FILES([Makefile])
-AC_CONFIG_FILES([third_party/Makefile])
+AC_CONFIG_FILES([3rdparty/Makefile])
AC_ARG_ENABLE([install],
AS_HELP_STRING([--enable-install],
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/Makefile.am b/third_party/libprocess/third_party/Makefile.am
deleted file mode 100644
index 2f0567b..0000000
--- a/third_party/libprocess/third_party/Makefile.am
+++ /dev/null
@@ -1,170 +0,0 @@
-# This Makefile is for building third_party packages from
-# tarballs. For autotools-based packages, we configure each of the
-# packages to build static PIC binaries which we can safely link into
-# a shared libmesos, and build it in-place without installing it (even
-# if one runs 'make install' in this directory). Non-autotools based
-# packages may be special cases; this Makefile is responsible for
-# passing any special make or configure flags that might be required.
-
-SUBDIRS = stout
-
-BUILT_SOURCES = # Initialized to enable using +=.
-
-# We need to add '--srcdir=.' needed because 'make distcheck' adds
-# '--srcdir=...' when configuring.
-CONFIGURE_ARGS = @CONFIGURE_ARGS@ --enable-shared=no --with-pic --srcdir=.
-
-include versions.am
-
-STOUT = stout
-BOOST = boost-$(BOOST_VERSION)
-GLOG = glog-$(GLOG_VERSION)
-GMOCK = gmock-$(GMOCK_VERSION)
-GPERFTOOLS = gperftools-$(GPERFTOOLS_VERSION)
-GTEST = $(GMOCK)/gtest
-RY_HTTP_PARSER = ry-http-parser-$(RY_HTTP_PARSER_VERSION)
-LIBEV = libev-$(LIBEV_VERSION)
-PROTOBUF = protobuf-$(PROTOBUF_VERSION)
-
-
-EXTRA_DIST = \
- $(BOOST).tar.gz \
- $(GLOG).tar.gz \
- $(GMOCK).tar.gz \
- $(GPERFTOOLS).tar.gz \
- $(LIBEV).tar.gz \
- $(LIBEV).patch \
- $(PROTOBUF).tar.gz \
- $(RY_HTTP_PARSER).tar.gz
-
-CLEAN_EXTRACTED = \
- $(BOOST) \
- $(GLOG) \
- $(GMOCK) \
- $(GPERFTOOLS) \
- $(LIBEV) \
- $(PROTOBUF) \
- $(RY_HTTP_PARSER)
-
-
-# This is where the magic happens: we use stamp files as dependencies
-# which cause the packages to get extracted as necessary. We also
-# apply any patches as appropriate.
-%-stamp: %.tar.gz
- gzip -d -c $^ | tar xf -
- test ! -e $(srcdir)/$*.patch || patch -d $* -p1 <$(srcdir)/$*.patch
- touch $@
-
-
-# Convenience library for Ryan Dahl's HTTP parser.
-noinst_LTLIBRARIES = libry_http_parser.la
-nodist_libry_http_parser_la_SOURCES = $(RY_HTTP_PARSER)/http_parser.c
-libry_http_parser_la_CPPFLAGS = -I$(RY_HTTP_PARSER)
-
-# We list the sources in BUILT_SOURCES to make sure that the package
-# gets unarchived first.
-BUILT_SOURCES += $(nodist_libry_http_parser_la_SOURCES)
-
-
-# Convenience library for gmock/gtest.
-check_LTLIBRARIES = libgmock.la
-nodist_libgmock_la_SOURCES = \
- $(GTEST)/src/gtest-all.cc \
- $(GMOCK)/src/gmock-all.cc
-libgmock_la_CPPFLAGS = \
- -I$(GTEST)/include -I$(GTEST) \
- -I$(GMOCK)/include -I$(GMOCK)
-
-# We list the sources in BUILT_SOURCES to make sure that the package
-# gets unarchived first.
-BUILT_SOURCES += $(nodist_libgmock_la_SOURCES)
-
-$(GMOCK)/src/gmock-all.cc: $(GMOCK)-stamp
-$(GTEST)/src/gtest-all.cc: $(GMOCK)-stamp
-
-
-$(BOOST)/boost: $(BOOST)-stamp
-
-$(GLOG)/libglog.la: $(GLOG)-stamp
- cd $(GLOG) && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
-
-if HAS_GPERFTOOLS
-$(GPERFTOOLS)/libprofiler.la: $(GPERFTOOLS)-build-stamp
-
-$(GPERFTOOLS)-build-stamp: $(GPERFTOOLS)-stamp
- cd $(GPERFTOOLS) && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
- touch $@
-endif
-
-$(LIBEV)/libev.la: $(LIBEV)-stamp
- cd $(LIBEV) && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
-
-$(PROTOBUF)/src/protoc $(PROTOBUF)/src/libprotobuf.la: $(PROTOBUF)-build-stamp
-
-$(PROTOBUF)-build-stamp: $(PROTOBUF)-stamp
- cd $(PROTOBUF) && ./configure $(CONFIGURE_ARGS) && \
- $(MAKE) $(AM_MAKEFLAGS)
- touch $@
-
-$(RY_HTTP_PARSER)/http_parser.c: $(RY_HTTP_PARSER)-stamp
-
-
-# Tests for stout.
-check_PROGRAMS = stout-tests
-
-stout_tests_SOURCES = \
- $(STOUT)/tests/bytes_tests.cpp \
- $(STOUT)/tests/duration_tests.cpp \
- $(STOUT)/tests/error_tests.cpp \
- $(STOUT)/tests/flags_tests.cpp \
- $(STOUT)/tests/gzip_tests.cpp \
- $(STOUT)/tests/hashset_tests.cpp \
- $(STOUT)/tests/json_tests.cpp \
- $(STOUT)/tests/main.cpp \
- $(STOUT)/tests/multimap_tests.cpp \
- $(STOUT)/tests/none_tests.cpp \
- $(STOUT)/tests/os_tests.cpp \
- $(STOUT)/tests/strings_tests.cpp \
- $(STOUT)/tests/uuid_tests.cpp
-
-if OS_LINUX
- stout_tests_SOURCES += $(STOUT)/tests/proc_tests.cpp
-endif
-
-stout_tests_CPPFLAGS = \
- -I$(srcdir)/$(STOUT)/include \
- -I$(BOOST) \
- -I$(GLOG)/src \
- -I$(GTEST)/include \
- -I$(GMOCK)/include \
- -I$(PROTOBUF)/src \
- $(AM_CPPFLAGS)
-
-stout_tests_LDADD = \
- libgmock.la \
- $(GLOG)/libglog.la \
- $(PROTOBUF)/src/libprotobuf.la
-
-TESTS = stout-tests
-
-# Dependencies for all-local.
-ALL_LOCAL = \
- $(STOUT)/Makefile \
- $(BOOST)-stamp \
- $(GLOG)/libglog.la \
- $(LIBEV)/libev.la \
- $(PROTOBUF)/src/libprotobuf.la \
- $(PROTOBUF)/src/protoc
-
-if HAS_GPERFTOOLS
- ALL_LOCAL += $(GPERFTOOLS)/libprofiler.la
-endif
-
-all-local: $(ALL_LOCAL)
-
-clean-local:
- rm -r -f $(CLEAN_EXTRACTED)
- rm -f *-stamp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/boost-1.53.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/boost-1.53.0.tar.gz b/third_party/libprocess/third_party/boost-1.53.0.tar.gz
deleted file mode 100644
index 770d837..0000000
Binary files a/third_party/libprocess/third_party/boost-1.53.0.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/glog-0.3.1.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/glog-0.3.1.tar.gz b/third_party/libprocess/third_party/glog-0.3.1.tar.gz
deleted file mode 100644
index 19b4b94..0000000
Binary files a/third_party/libprocess/third_party/glog-0.3.1.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/gmock-1.6.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/gmock-1.6.0.tar.gz b/third_party/libprocess/third_party/gmock-1.6.0.tar.gz
deleted file mode 100644
index d45d989..0000000
Binary files a/third_party/libprocess/third_party/gmock-1.6.0.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/gperftools-2.0.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/gperftools-2.0.tar.gz b/third_party/libprocess/third_party/gperftools-2.0.tar.gz
deleted file mode 100644
index 13b03ca..0000000
Binary files a/third_party/libprocess/third_party/gperftools-2.0.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/libev-4.15.patch
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/libev-4.15.patch b/third_party/libprocess/third_party/libev-4.15.patch
deleted file mode 100644
index 2b94532..0000000
--- a/third_party/libprocess/third_party/libev-4.15.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -rupN libev-4.15/ev.h libev-4.15-patched/ev.h
---- libev-4.15/ev.h 2013-03-01 03:05:29.000000000 -0800
-+++ libev-4.15-patched/ev.h 2013-05-20 16:01:47.000000000 -0700
-@@ -121,7 +121,7 @@ EV_CPP(extern "C" {)
- # ifdef _WIN32
- # define EV_CHILD_ENABLE 0
- # else
--# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
-+# define EV_CHILD_ENABLE 0
- #endif
- #endif
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/libev-4.15.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/libev-4.15.tar.gz b/third_party/libprocess/third_party/libev-4.15.tar.gz
deleted file mode 100644
index 4c282b5..0000000
Binary files a/third_party/libprocess/third_party/libev-4.15.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/protobuf-2.4.1.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/protobuf-2.4.1.tar.gz b/third_party/libprocess/third_party/protobuf-2.4.1.tar.gz
deleted file mode 100644
index 38ec4de..0000000
Binary files a/third_party/libprocess/third_party/protobuf-2.4.1.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/ry-http-parser-1c3624a.tar.gz
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/ry-http-parser-1c3624a.tar.gz b/third_party/libprocess/third_party/ry-http-parser-1c3624a.tar.gz
deleted file mode 100644
index b811b63..0000000
Binary files a/third_party/libprocess/third_party/ry-http-parser-1c3624a.tar.gz and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/LICENSE
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/LICENSE b/third_party/libprocess/third_party/stout/LICENSE
deleted file mode 100644
index f433b1a..0000000
--- a/third_party/libprocess/third_party/stout/LICENSE
+++ /dev/null
@@ -1,177 +0,0 @@
-
- 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/bc531d3c/third_party/libprocess/third_party/stout/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/Makefile.am b/third_party/libprocess/third_party/stout/Makefile.am
deleted file mode 100644
index fdd3482..0000000
--- a/third_party/libprocess/third_party/stout/Makefile.am
+++ /dev/null
@@ -1,61 +0,0 @@
-# Makefile for stout.
-
-ACLOCAL_AMFLAGS = -I m4
-
-AUTOMAKE_OPTIONS = foreign
-
-EXTRA_DIST = \
- include/stout/bytes.hpp \
- include/stout/cache.hpp \
- include/stout/duration.hpp \
- include/stout/error.hpp \
- include/stout/exit.hpp \
- include/stout/fatal.hpp \
- include/stout/flags.hpp \
- include/stout/flags/flag.hpp \
- include/stout/flags/flags.hpp \
- include/stout/flags/loader.hpp \
- include/stout/flags/parse.hpp \
- include/stout/foreach.hpp \
- include/stout/format.hpp \
- include/stout/fs.hpp \
- include/stout/gtest.hpp \
- include/stout/gzip.hpp \
- include/stout/hashmap.hpp \
- include/stout/hashset.hpp \
- include/stout/json.hpp \
- include/stout/lambda.hpp \
- include/stout/multihashmap.hpp \
- include/stout/multimap.hpp \
- include/stout/net.hpp \
- include/stout/none.hpp \
- include/stout/nothing.hpp \
- include/stout/numify.hpp \
- include/stout/option.hpp \
- include/stout/os.hpp \
- include/stout/owned.hpp \
- include/stout/path.hpp \
- include/stout/preprocessor.hpp \
- include/stout/proc.hpp \
- include/stout/protobuf.hpp \
- include/stout/result.hpp \
- include/stout/stopwatch.hpp \
- include/stout/stringify.hpp \
- include/stout/strings.hpp \
- include/stout/try.hpp \
- include/stout/utils.hpp \
- include/stout/uuid.hpp \
- tests/bytes_tests.cpp \
- tests/duration_tests.cpp \
- tests/error_tests.cpp \
- tests/flags_tests.cpp \
- tests/gzip_tests.cpp \
- tests/hashset_tests.cpp \
- tests/json_tests.cpp \
- tests/main.cpp \
- tests/multimap_tests.cpp \
- tests/none_tests.cpp \
- tests/os_tests.cpp \
- tests/proc_tests.cpp \
- tests/strings_tests.cpp \
- tests/uuid_tests.cpp
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/README
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/README b/third_party/libprocess/third_party/stout/README
deleted file mode 100644
index 685a4ae..0000000
--- a/third_party/libprocess/third_party/stout/README
+++ /dev/null
@@ -1,32 +0,0 @@
-Stout is a header-only C++ library.
-
-No action is needed if you would like to use this library in your
-project. Simply add the include folder to your include path during
-compilation.
-
-Depending on which headers you'd like to use, you may require the
-following third party libraries:
-
- - Boost
- - Google's glog (this dependency will be removed in the future).
- - Google's protobuf.
- - Google's gmock/gtest.
-
-
-Building Tests
-==============
-
-We'll assume you've got a distribution of gmock and have already built
-a static archive called libgmock.a (see gmock's README to learn
-how). We'll also assume the Boost and glog headers can be found via
-the include paths and libglog.* can be found via the library search
-paths. You can then build the tests via:
-
-$ g++ -I${STOUT}/include -I$(GMOCK)/gtest/include -I$(GMOCK)/include \
- ${STOUT}/tests/tests.cpp libgmock.a -lglog -o tests
-
-Note that if you want to test the gzip headers you'll need to define
-HAVE_LIBZ and link against libz:
-
-$ g++ -I${STOUT}/include -I$(GMOCK)/gtest/include -I$(GMOCK)/include \
- -DHAVE_LIBZ ${STOUT}/tests/tests.cpp libgmock.a -lglog -lz -o tests
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/bootstrap
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/bootstrap b/third_party/libprocess/third_party/stout/bootstrap
deleted file mode 100755
index 89b9bc8..0000000
--- a/third_party/libprocess/third_party/stout/bootstrap
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/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 "${@}"
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/configure.ac
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/configure.ac b/third_party/libprocess/third_party/stout/configure.ac
deleted file mode 100644
index 86e1ff3..0000000
--- a/third_party/libprocess/third_party/stout/configure.ac
+++ /dev/null
@@ -1,14 +0,0 @@
-# Generated with autoscan, then modified appropriately.
-# Process this file with autoconf to produce a configure script.
-
-AC_PREREQ([2.61])
-AC_INIT([stout], [0.1.0])
-
-AC_LANG([C++])
-
-# Initialize automake.
-AM_INIT_AUTOMAKE([1.10])
-
-AC_CONFIG_FILES([Makefile])
-
-AC_OUTPUT
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/bytes.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/bytes.hpp b/third_party/libprocess/third_party/stout/include/stout/bytes.hpp
deleted file mode 100644
index 754fbb2..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/bytes.hpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#ifndef __STOUT_BYTES_HPP__
-#define __STOUT_BYTES_HPP__
-
-#include <ctype.h> // For 'isdigit'.
-#include <stdint.h>
-
-#include <iomanip>
-#include <iostream>
-#include <string>
-
-#include "numify.hpp"
-#include "strings.hpp"
-#include "try.hpp"
-
-
-class Bytes
-{
-public:
- static Try<Bytes> parse(const std::string& s)
- {
- size_t index = 0;
-
- while (index < s.size()) {
- if (isdigit(s[index])) {
- index++;
- continue;
- } else if (s[index] == '.') {
- return Error("Fractional bytes '" + s + "'");
- }
-
- Try<uint64_t> value = numify<uint64_t>(s.substr(0, index));
-
- if (value.isError()) {
- return Error(value.error());
- }
-
- const std::string& unit = strings::upper(s.substr(index));
-
- if (unit == "B") {
- return Bytes(value.get(), BYTES);
- } else if (unit == "KB") {
- return Bytes(value.get(), KILOBYTES);
- } else if (unit == "MB") {
- return Bytes(value.get(), MEGABYTES);
- } else if (unit == "GB") {
- return Bytes(value.get(), GIGABYTES);
- } else if (unit == "TB") {
- return Bytes(value.get(), TERABYTES);
- } else {
- return Error("Unknown bytes unit '" + unit + "'");
- }
- }
- return Error("Invalid bytes '" + s + "'");
- }
-
- Bytes(uint64_t bytes = 0) : value(bytes) {}
- Bytes(uint64_t _value, uint64_t _unit) : value(_value * _unit) {}
-
- // TODO(bmahler): Consider killing kilobytes to terabyte helpers, given
- // they implicitly lose precision if not careful.
- uint64_t bytes() const { return value; }
- uint64_t kilobytes() const { return value / KILOBYTES; }
- uint64_t megabytes() const { return value / MEGABYTES; }
- uint64_t gigabytes() const { return value / GIGABYTES; }
- uint64_t terabytes() const { return value / TERABYTES; }
-
- bool operator < (const Bytes& that) const { return value < that.value; }
- bool operator <= (const Bytes& that) const { return value <= that.value; }
- bool operator > (const Bytes& that) const { return value > that.value; }
- bool operator >= (const Bytes& that) const { return value >= that.value; }
- bool operator == (const Bytes& that) const { return value == that.value; }
- bool operator != (const Bytes& that) const { return value != that.value; }
-
- Bytes& operator += (const Bytes& that)
- {
- value += that.value;
- return *this;
- }
-
- Bytes& operator -= (const Bytes& that)
- {
- value -= that.value;
- return *this;
- }
-
-protected:
- static const uint64_t BYTES = 1;
- static const uint64_t KILOBYTES = 1024 * BYTES;
- static const uint64_t MEGABYTES = 1024 * KILOBYTES;
- static const uint64_t GIGABYTES = 1024 * MEGABYTES;
- static const uint64_t TERABYTES = 1024 * GIGABYTES;
-
-private:
- uint64_t value;
-};
-
-
-class Kilobytes : public Bytes
-{
-public:
- explicit Kilobytes(uint64_t value) : Bytes(value, KILOBYTES) {}
-};
-
-
-class Megabytes : public Bytes
-{
-public:
- explicit Megabytes(uint64_t value) : Bytes(value, MEGABYTES) {}
-};
-
-
-class Gigabytes : public Bytes
-{
-public:
- explicit Gigabytes(uint64_t value) : Bytes(value, GIGABYTES) {}
-};
-
-
-class Terabytes : public Bytes
-{
-public:
- explicit Terabytes(uint64_t value) : Bytes(value, TERABYTES) {}
-};
-
-
-inline std::ostream& operator << (std::ostream& stream, const Bytes& bytes)
-{
- // Only raise the unit when there is no loss of information.
- if (bytes.bytes() == 0) {
- return stream << bytes.bytes() << "B";
- } else if (bytes.bytes() % 1024 != 0) {
- return stream << bytes.bytes() << "B";
- } else if (bytes.kilobytes() % 1024 != 0) {
- return stream << bytes.kilobytes() << "KB";
- } else if (bytes.megabytes() % 1024 != 0) {
- return stream << bytes.megabytes() << "MB";
- } else if (bytes.gigabytes() % 1024 != 0) {
- return stream << bytes.gigabytes() << "GB";
- } else {
- return stream << bytes.terabytes() << "TB";
- }
-}
-
-
-inline Bytes operator + (const Bytes& lhs, const Bytes& rhs)
-{
- Bytes sum = lhs;
- sum += rhs;
- return sum;
-}
-
-
-inline Bytes operator - (const Bytes& lhs, const Bytes& rhs)
-{
- Bytes diff = lhs;
- diff -= rhs;
- return diff;
-}
-
-#endif // __STOUT_BYTES_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/cache.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/cache.hpp b/third_party/libprocess/third_party/stout/include/stout/cache.hpp
deleted file mode 100644
index 653507c..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/cache.hpp
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef __STOUT_CACHE_HPP__
-#define __STOUT_CACHE_HPP__
-
-#include <functional>
-#include <iostream>
-#include <list>
-#include <map>
-
-#include <tr1/functional>
-#include <tr1/unordered_map>
-
-#include "none.hpp"
-#include "option.hpp"
-
-// Forward declaration.
-template <typename Key, typename Value>
-class cache;
-
-// Outputs the key/value pairs from least to most-recently used.
-template <typename Key, typename Value>
-std::ostream& operator << (
- std::ostream& stream,
- const cache<Key, Value>& c);
-
-
-// Provides a least-recently used (LRU) cache of some predefined
-// capacity. A "write" and a "read" both count as uses.
-template <typename Key, typename Value>
-class cache
-{
-public:
- typedef std::list<Key> list;
- typedef std::tr1::unordered_map<
- Key, std::pair<Value, typename list::iterator> > map;
-
- explicit cache(int _capacity) : capacity(_capacity) {}
-
- void put(const Key& key, const Value& value)
- {
- typename map::iterator i = values.find(key);
- if (i == values.end()) {
- insert(key, value);
- } else {
- (*i).second.first = value;
- use(i);
- }
- }
-
- Option<Value> get(const Key& key)
- {
- typename map::iterator i = values.find(key);
-
- if (i != values.end()) {
- use(i);
- return (*i).second.first;
- }
-
- return None();
- }
-
-private:
- // Not copyable, not assignable.
- cache(const cache&);
- cache& operator = (const cache&);
-
- // Give the operator access to our internals.
- friend std::ostream& operator << <>(
- std::ostream& stream,
- const cache<Key, Value>& c);
-
- // Insert key/value into the cache.
- void insert(const Key& key, const Value& value)
- {
- if (keys.size() == capacity) {
- evict();
- }
-
- // Get a "pointer" into the lru list for efficient update.
- typename list::iterator i = keys.insert(keys.end(), key);
-
- // Save key/value and "pointer" into lru list.
- values.insert(std::make_pair(key, std::make_pair(value, i)));
- }
-
- // Updates the LRU ordering in the cache for the given iterator.
- void use(const typename map::iterator& i)
- {
- // Move the "pointer" to the end of the lru list.
- keys.splice(keys.end(), keys, (*i).second.second);
-
- // Now update the "pointer" so we can do this again.
- (*i).second.second = --keys.end();
- }
-
- // Evict the least-recently used element from the cache.
- void evict()
- {
- const typename map::iterator& i = values.find(keys.front());
- CHECK(i != values.end());
- values.erase(i);
- keys.pop_front();
- }
-
- // Size of the cache.
- int capacity;
-
- // Cache of values and "pointers" into the least-recently used list.
- map values;
-
- // Keys ordered by least-recently used.
- list keys;
-};
-
-
-template <typename Key, typename Value>
-std::ostream& operator << (
- std::ostream& stream,
- const cache<Key, Value>& c)
-{
- typename cache<Key, Value>::list::const_iterator i1;
- for (i1 = c.keys.begin(); i1 != c.keys.end(); i1++) {
- stream << *i1 << ": ";
- typename cache<Key, Value>::map::const_iterator i2;
- i2 = c.values.find(*i1);
- CHECK(i2 != c.values.end());
- stream << *i2 << std::endl;
- }
- return stream;
-}
-
-#endif // __STOUT_CACHE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/duration.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/duration.hpp b/third_party/libprocess/third_party/stout/include/stout/duration.hpp
deleted file mode 100644
index 47e85ff..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/duration.hpp
+++ /dev/null
@@ -1,297 +0,0 @@
-#ifndef __STOUT_DURATION_HPP__
-#define __STOUT_DURATION_HPP__
-
-#include <ctype.h> // For 'isdigit'.
-#include <limits.h> // For 'LLONG_(MAX|MIN)'
-
-#include <iomanip>
-#include <iostream>
-#include <string>
-
-#include "error.hpp"
-#include "numify.hpp"
-#include "try.hpp"
-
-class Duration
-{
-public:
- static Try<Duration> parse(const std::string& s)
- {
- // TODO(benh): Support negative durations (i.e., starts with '-').
- size_t index = 0;
- while (index < s.size()) {
- if (isdigit(s[index]) || s[index] == '.') {
- index++;
- continue;
- }
-
- Try<double> value = numify<double>(s.substr(0, index));
-
- if (value.isError()) {
- return Error(value.error());
- }
-
- const std::string& unit = s.substr(index);
-
- if (unit == "ns") {
- return Duration(value.get(), NANOSECONDS);
- } else if (unit == "us") {
- return Duration(value.get(), MICROSECONDS);
- } else if (unit == "ms") {
- return Duration(value.get(), MILLISECONDS);
- } else if (unit == "secs") {
- return Duration(value.get(), SECONDS);
- } else if (unit == "mins") {
- return Duration(value.get(), MINUTES);
- } else if (unit == "hrs") {
- return Duration(value.get(), HOURS);
- } else if (unit == "days") {
- return Duration(value.get(), DAYS);
- } else if (unit == "weeks") {
- return Duration(value.get(), WEEKS);
- } else {
- return Error("Unknown duration unit '" + unit + "'");
- }
- }
- return Error("Invalid duration '" + s + "'");
- }
-
- static Try<Duration> create(double seconds);
-
- Duration() : nanos(0) {}
-
- int64_t ns() const { return nanos; }
- double us() const { return static_cast<double>(nanos) / MICROSECONDS; }
- double ms() const { return static_cast<double>(nanos) / MILLISECONDS; }
- double secs() const { return static_cast<double>(nanos) / SECONDS; }
- double mins() const { return static_cast<double>(nanos) / MINUTES; }
- double hrs() const { return static_cast<double>(nanos) / HOURS; }
- double days() const { return static_cast<double>(nanos) / DAYS; }
- double weeks() const { return static_cast<double>(nanos) / WEEKS; }
-
- bool operator < (const Duration& d) const { return nanos < d.nanos; }
- bool operator <= (const Duration& d) const { return nanos <= d.nanos; }
- bool operator > (const Duration& d) const { return nanos > d.nanos; }
- bool operator >= (const Duration& d) const { return nanos >= d.nanos; }
- bool operator == (const Duration& d) const { return nanos == d.nanos; }
- bool operator != (const Duration& d) const { return nanos != d.nanos; }
-
- Duration& operator += (const Duration& that)
- {
- nanos += that.nanos;
- return *this;
- }
-
- Duration& operator -= (const Duration& that)
- {
- nanos -= that.nanos;
- return *this;
- }
-
- Duration& operator *= (double multiplier)
- {
- nanos = static_cast<int64_t>(nanos * multiplier);
- return *this;
- }
-
- Duration& operator /= (double divisor)
- {
- nanos = static_cast<int64_t>(nanos / divisor);
- return *this;
- }
-
- Duration operator + (const Duration& that) const
- {
- Duration sum = *this;
- sum += that;
- return sum;
- }
-
- Duration operator - (const Duration& that) const
- {
- Duration diff = *this;
- diff -= that;
- return diff;
- }
-
- Duration operator * (double multiplier) const
- {
- Duration product = *this;
- product *= multiplier;
- return product;
- }
-
- Duration operator / (double divisor) const
- {
- Duration quotient = *this;
- quotient /= divisor;
- return quotient;
- }
-
- // TODO(xujyan): Use constexpr for the following variables after
- // switching to C++11.
- // A constant holding the maximum value a Duration can have.
- static Duration max();
- // A constant holding the minimum (negative) value a Duration can
- // have.
- static Duration min();
- // A constant holding a Duration of a "zero" value.
- static Duration zero() { return Duration(); }
-
-protected:
- static const int64_t NANOSECONDS = 1;
- static const int64_t MICROSECONDS = 1000 * NANOSECONDS;
- static const int64_t MILLISECONDS = 1000 * MICROSECONDS;
- static const int64_t SECONDS = 1000 * MILLISECONDS;
- static const int64_t MINUTES = 60 * SECONDS;
- static const int64_t HOURS = 60 * MINUTES;
- static const int64_t DAYS = 24 * HOURS;
- static const int64_t WEEKS = 7 * DAYS;
-
- // For the Seconds, Minutes, Hours, Days & Weeks constructor.
- Duration(int32_t value, int64_t unit)
- : nanos(value * unit) {}
-
- // For the Nanoseconds, Microseconds, Milliseconds constructor.
- Duration(int64_t value, int64_t unit)
- : nanos(value * unit) {}
-
-private:
- // Used only by "parse".
- Duration(double value, int64_t unit)
- : nanos(static_cast<int64_t>(value * unit)) {}
-
- int64_t nanos;
-};
-
-
-class Nanoseconds : public Duration
-{
-public:
- explicit Nanoseconds(int64_t nanoseconds)
- : Duration(nanoseconds, NANOSECONDS) {}
-
- Nanoseconds(const Duration& d) : Duration(d) {}
-};
-
-
-class Microseconds : public Duration
-{
-public:
- explicit Microseconds(int64_t microseconds)
- : Duration(microseconds, MICROSECONDS) {}
-
- Microseconds(const Duration& d) : Duration(d) {}
-};
-
-
-class Milliseconds : public Duration
-{
-public:
- explicit Milliseconds(int64_t milliseconds)
- : Duration(milliseconds, MILLISECONDS) {}
-
- Milliseconds(const Duration& d) : Duration(d) {}
-};
-
-
-class Seconds : public Duration
-{
-public:
- explicit Seconds(int64_t seconds)
- : Duration(seconds, SECONDS) {}
-
- Seconds(const Duration& d) : Duration(d) {}
-};
-
-
-class Minutes : public Duration
-{
-public:
- explicit Minutes(int32_t minutes)
- : Duration(minutes, MINUTES) {}
-
- Minutes(const Duration& d) : Duration(d) {}
-};
-
-
-class Hours : public Duration
-{
-public:
- explicit Hours(int32_t hours)
- : Duration(hours, HOURS) {}
-
- Hours(const Duration& d) : Duration(d) {}
-};
-
-
-class Days : public Duration
-{
-public:
- explicit Days(int32_t days)
- : Duration(days, DAYS) {}
-
- Days(const Duration& d) : Duration(d) {}
-};
-
-
-class Weeks : public Duration
-{
-public:
- explicit Weeks(int32_t value) : Duration(value, WEEKS) {}
-
- Weeks(const Duration& d) : Duration(d) {}
-};
-
-
-inline std::ostream& operator << (
- std::ostream& stream,
- const Duration& duration)
-{
- long precision = stream.precision();
-
- // Output the duration in full double precision.
- stream.precision(std::numeric_limits<double>::digits10);
-
- if (duration < Microseconds(1)) {
- stream << duration.ns() << "ns";
- } else if (duration < Milliseconds(1)) {
- stream << duration.us() << "us";
- } else if (duration < Seconds(1)) {
- stream << duration.ms() << "ms";
- } else if (duration < Minutes(1)) {
- stream << duration.secs() << "secs";
- } else if (duration < Hours(1)) {
- stream << duration.mins() << "mins";
- } else if (duration < Days(1)) {
- stream << duration.hrs() << "hrs";
- } else if (duration < Weeks(1)) {
- stream << duration.days() << "days";
- } else {
- stream << duration.weeks() << "weeks";
- }
-
- // Return the stream to original formatting state.
- stream.precision(precision);
-
- return stream;
-}
-
-
-inline Try<Duration> Duration::create(double seconds)
-{
- if (seconds * SECONDS > LLONG_MAX) {
- return Error("Argument larger than the maximum number of seconds that "
- "a Duration can represent due to int64_t's size limit.");
- }
-
- return Nanoseconds(static_cast<int64_t>(seconds * SECONDS));
-}
-
-
-inline Duration Duration::max() { return Nanoseconds(LLONG_MAX); }
-
-
-inline Duration Duration::min() { return Nanoseconds(LLONG_MIN); }
-
-#endif // __STOUT_DURATION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/error.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/error.hpp b/third_party/libprocess/third_party/stout/include/stout/error.hpp
deleted file mode 100644
index 97a5cec..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/error.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef __STOUT_ERROR_HPP__
-#define __STOUT_ERROR_HPP__
-
-#include <errno.h>
-#include <string.h> // For strerror.
-
-#include <string>
-
-#include "result.hpp"
-#include "try.hpp"
-
-// An "error" type that is implicitly convertible to a Try<T> or
-// Result<T> for any T (effectively "syntactic sugar" to make code
-// more readable). The implementation uses cast operators to perform
-// the conversions instead of adding constructors to Try/Result
-// directly. One could imagine revisiting that decision for C++11
-// because the use of rvalue reference could eliminate some
-// unnecessary copies. However, performance is not critical since
-// Error should not get called very often in practice (if so, it's
-// probably being used for things that aren't really errors or there
-// is a more serious problem during execution).
-
-class Error
-{
-public:
- explicit Error(const std::string& _message) : message(_message) {}
-
- template <typename T>
- operator Try<T> () const
- {
- return Try<T>::error(message);
- }
-
- // Give the compiler some help for nested Try<T>. For example,
- // enable converting Error to an Option<Try<T>>. Note that this will
- // bind to the innermost Try<T>.
- template <template <typename> class S, typename T>
- operator S<Try<T> > () const
- {
- return S<Try<T> >(Try<T>::error(message));
- }
-
- template <typename T>
- operator Result<T> () const
- {
- return Result<T>::error(message);
- }
-
- // Give the compiler some help for nested Result<T>. For example,
- // enable converting Error to an Option<Result<T>>. Note that this
- // will bind to the innermost Result<T>.
- template <template <typename> class S, typename T>
- operator S<Result<T> > () const
- {
- return S<Result<T> >(Result<T>::error(message));
- }
-
- const std::string message;
-};
-
-
-class ErrnoError : public Error
-{
-public:
- ErrnoError()
- : Error(std::string(strerror(errno))) {}
-
- ErrnoError(const std::string& message)
- : Error(message + ": " + std::string(strerror(errno))) {}
-};
-
-#endif // __STOUT_ERROR_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/exit.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/exit.hpp b/third_party/libprocess/third_party/stout/include/stout/exit.hpp
deleted file mode 100644
index e8da726..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/exit.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __STOUT_EXIT_HPP__
-#define __STOUT_EXIT_HPP__
-
-#include <stdlib.h>
-
-#include <iostream> // For std::cerr.
-#include <ostream>
-#include <sstream>
-#include <string>
-
-// Exit takes an exit status and provides a stream for output prior to
-// exiting. This is like glog's LOG(FATAL) or CHECK, except that it
-// does _not_ print a stack trace.
-//
-// Ex: EXIT(1) << "Cgroups are not present in this system.";
-#define EXIT(status) __Exit(status).stream()
-
-struct __Exit
-{
- __Exit(int _status) : status(_status) {}
-
- ~__Exit()
- {
- std::cerr << out.str() << std::endl;
- exit(status);
- }
-
- std::ostream& stream()
- {
- return out;
- }
-
- std::ostringstream out;
- const int status;
-};
-
-#endif // __STOUT_EXIT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/fatal.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/fatal.hpp b/third_party/libprocess/third_party/stout/include/stout/fatal.hpp
deleted file mode 100644
index eabee3e..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/fatal.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef __STOUT_FATAL_HPP__
-#define __STOUT_FATAL_HPP__
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-
-/*
- * Like the non-debug version except includes the file name and line
- * number in the output.
- */
-#define fatal(fmt...) __fatal(__FILE__, __LINE__, fmt)
-inline void __fatal(const char *file, int line, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, " (%s:%u)\n", file, line);
- fflush(stderr);
- va_end(args);
- exit(1);
-}
-
-
-/*
- * Like the non-debug version except includes the file name and line
- * number in the output.
- */
-#define fatalerror(fmt...) __fatalerror(__FILE__, __LINE__, fmt)
-inline void __fatalerror(const char *file, int line, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- fprintf(stderr, " (%s:%u): ", file, line);
- perror(NULL);
- fflush(stderr);
- va_end(args);
- exit(1);
-}
-
-#endif // __STOUT_FATAL_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/flags.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags.hpp b/third_party/libprocess/third_party/stout/include/stout/flags.hpp
deleted file mode 100644
index 0efd079..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/flags.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef __STOUT_FLAGS_HPP__
-#define __STOUT_FLAGS_HPP__
-
-#include <stout/flags/flags.hpp>
-
-// An abstraction for application/library "flags". An example is
-// probably best:
-// -------------------------------------------------------------
-// class MyFlags : public virtual FlagsBase // Use 'virtual' for composition!
-// {
-// public:
-// Flags()
-// {
-// add(&debug,
-// "debug",
-// "Help string for debug",
-// false);
-//
-// add(&name,
-// "name",
-// "Help string for name");
-// }
-
-// bool debug;
-// Option<string> name;
-// };
-//
-// ...
-//
-// map<string, Option<string> > values;
-// values["no-debug"] = None(); // --no-debug
-// values["debug"] = None(); // --debug
-// values["debug"] = Option<string>::some("true"); // --debug=true
-// values["debug"] = Option<string>::some("false"); // --debug=false
-// values["name"] = Option<string>::some("frank"); // --name=frank
-//
-// MyFlags flags;
-// flags.load(values);
-// flags.name.isSome() ...
-// flags.debug ...
-// -------------------------------------------------------------
-//
-// You can also compose flags provided that each has used "virtual
-// inheritance":
-// -------------------------------------------------------------
-// Flags<MyFlags1, MyFlags2> flags;
-// flags.add(...); // Any other flags you want to throw in there.
-// flags.load(values);
-// flags.flag_from_myflags1 ...
-// flags.flag_from_myflags2 ...
-// -------------------------------------------------------------
-//
-// "Fail early, fail often":
-//
-// You can not add duplicate flags, this is checked for you at compile
-// time for composite flags (e.g., Flag<MyFlags1, MyFlags2>) and also
-// checked at runtime for any other flags added via inheritance or
-// Flags::add(...).
-//
-// Flags that can not be loaded (e.g., attempting to use the 'no-'
-// prefix for a flag that is not boolean) will print a message to
-// standard error and abort the process.
-
-// TODO(benh): Provide a boolean which specifies whether or not to
-// abort on duplicates or load errors.
-
-// TODO(benh): Make prefix for environment variables configurable
-// (e.g., "MESOS_").
-
-#endif // __STOUT_FLAGS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/flags/flag.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags/flag.hpp b/third_party/libprocess/third_party/stout/include/stout/flags/flag.hpp
deleted file mode 100644
index d31c984..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/flags/flag.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __STOUT_FLAGS_FLAG_HPP__
-#define __STOUT_FLAGS_FLAG_HPP__
-
-#include <string>
-
-#include <tr1/functional>
-
-#include <stout/nothing.hpp>
-#include <stout/try.hpp>
-
-namespace flags {
-
-// Forward declaration.
-class FlagsBase;
-
-struct Flag
-{
- std::string name;
- std::string help;
- bool boolean;
- std::tr1::function<Try<Nothing>(FlagsBase*, const std::string&)> loader;
-};
-
-} // namespace flags {
-
-#endif // __STOUT_FLAGS_FLAG_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags/flags.hpp b/third_party/libprocess/third_party/stout/include/stout/flags/flags.hpp
deleted file mode 100644
index 77d36e6..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/flags/flags.hpp
+++ /dev/null
@@ -1,481 +0,0 @@
-#ifndef __STOUT_FLAGS_FLAGS_HPP__
-#define __STOUT_FLAGS_FLAGS_HPP__
-
-#include <stdlib.h> // For abort.
-
-#include <map>
-#include <string>
-#include <typeinfo> // For typeid.
-
-#include <tr1/functional>
-
-#include <stout/error.hpp>
-#include <stout/exit.hpp>
-#include <stout/foreach.hpp>
-#include <stout/none.hpp>
-#include <stout/nothing.hpp>
-#include <stout/option.hpp>
-#include <stout/os.hpp>
-#include <stout/stringify.hpp>
-#include <stout/strings.hpp>
-#include <stout/try.hpp>
-
-#include <stout/flags/flag.hpp>
-#include <stout/flags/loader.hpp>
-#include <stout/flags/parse.hpp>
-
-namespace flags {
-
-class FlagsBase
-{
-public:
- virtual ~FlagsBase() {}
-
- // Load any flags from the environment given the variable prefix,
- // i.e., given prefix 'STOUT_' will load a flag named 'foo' via
- // environment variables 'STOUT_foo' or 'STOUT_FOO'.
- virtual Try<Nothing> load(
- const std::string& prefix,
- bool unknowns = false);
-
- // Load any flags from the environment given the variable prefix
- // (see above) followed by loading from the command line (via 'argc'
- // and 'argv'). If 'unknowns' is true then we'll ignore unknown
- // flags we see while loading. If 'duplicates' is true then we'll
- // ignore any duplicates we see while loading.
- virtual Try<Nothing> load(
- const Option<std::string>& prefix,
- int argc,
- char** argv,
- bool unknowns = false,
- bool duplicates = false);
-
- Try<Nothing> load(
- const std::string& prefix,
- int argc,
- char** argv,
- bool unknowns = false,
- bool duplicates = false);
-
- virtual Try<Nothing> load(
- const std::map<std::string, Option<std::string> >& values,
- bool unknowns = false);
-
- virtual Try<Nothing> load(
- const std::map<std::string, std::string>& values,
- bool unknowns = false);
-
- // Returns a string describing the flags.
- std::string usage() const;
-
- typedef std::map<std::string, Flag>::const_iterator const_iterator;
-
- const_iterator begin() const { return flags.begin(); }
- const_iterator end() const { return flags.end(); }
-
- template <typename T1, typename T2>
- void add(T1* t1,
- const std::string& name,
- const std::string& help,
- const T2& t2);
-
- template <typename T>
- void add(Option<T>* option,
- const std::string& name,
- const std::string& help);
-
-protected:
- template <typename Flags, typename T1, typename T2>
- void add(T1 Flags::*t1,
- const std::string& name,
- const std::string& help,
- const T2& t2);
-
- template <typename Flags, typename T>
- void add(Option<T> Flags::*option,
- const std::string& name,
- const std::string& help);
-
- void add(const Flag& flag);
-
-private:
- std::map<std::string, Flag> flags;
-};
-
-
-// Need to declare/define some explicit subclasses of FlagsBase so
-// that we can overload the 'Flags::operator FlagsN () const'
-// functions for each possible type.
-class _Flags1 : public virtual FlagsBase {};
-class _Flags2 : public virtual FlagsBase {};
-class _Flags3 : public virtual FlagsBase {};
-class _Flags4 : public virtual FlagsBase {};
-class _Flags5 : public virtual FlagsBase {};
-
-
-// TODO(benh): Add some "type constraints" for template paramters to
-// make sure they are all of type FlagsBase.
-template <typename Flags1 = _Flags1,
- typename Flags2 = _Flags2,
- typename Flags3 = _Flags3,
- typename Flags4 = _Flags4,
- typename Flags5 = _Flags5>
-class Flags : public virtual Flags1,
- public virtual Flags2,
- public virtual Flags3,
- public virtual Flags4,
- public virtual Flags5 {};
-
-
-template <typename T1, typename T2>
-void FlagsBase::add(
- T1* t1,
- const std::string& name,
- const std::string& help,
- const T2& t2)
-{
- *t1 = t2; // Set the default.
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T1) == typeid(bool);
- flag.loader = std::tr1::bind(
- &Loader<T1>::load,
- t1,
- std::tr1::function<Try<T1>(const std::string&)>(
- std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
-
- // Update the help string to include the default value.
- flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
- ? " (default: " // On same line, add space.
- : "(default: "; // On newline.
- flag.help += stringify(t2);
- flag.help += ")";
-
- FlagsBase::add(flag);
-}
-
-
-template <typename T>
-void FlagsBase::add(
- Option<T>* option,
- const std::string& name,
- const std::string& help)
-{
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T) == typeid(bool);
- flag.loader = std::tr1::bind(
- &OptionLoader<T>::load,
- option,
- std::tr1::function<Try<T>(const std::string&)>(
- std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2); // Use _2 because ignore FlagsBase*.
-
- FlagsBase::add(flag);
-}
-
-
-template <typename Flags, typename T1, typename T2>
-void FlagsBase::add(
- T1 Flags::*t1,
- const std::string& name,
- const std::string& help,
- const T2& t2)
-{
- Flags* flags = dynamic_cast<Flags*>(this);
- if (flags == NULL) {
- std::cerr << "Attempted to add flag '" << name
- << "' with incompatible type" << std::endl;
- abort();
- } else {
- flags->*t1 = t2; // Set the default.
- }
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T1) == typeid(bool);
- flag.loader = std::tr1::bind(
- &MemberLoader<Flags, T1>::load,
- std::tr1::placeholders::_1,
- t1,
- std::tr1::function<Try<T1>(const std::string&)>(
- std::tr1::bind(&parse<T1>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2);
-
- // Update the help string to include the default value.
- flag.help += help.size() > 0 && help.find_last_of("\n\r") != help.size() - 1
- ? " (default: " // On same line, add space.
- : "(default: "; // On newline.
- flag.help += stringify(t2);
- flag.help += ")";
-
- add(flag);
-}
-
-
-template <typename Flags, typename T>
-void FlagsBase::add(
- Option<T> Flags::*option,
- const std::string& name,
- const std::string& help)
-{
- Flags* flags = dynamic_cast<Flags*>(this);
- if (flags == NULL) {
- std::cerr << "Attempted to add flag '" << name
- << "' with incompatible type" << std::endl;
- abort();
- }
-
- Flag flag;
- flag.name = name;
- flag.help = help;
- flag.boolean = typeid(T) == typeid(bool);
- flag.loader = std::tr1::bind(
- &OptionMemberLoader<Flags, T>::load,
- std::tr1::placeholders::_1,
- option,
- std::tr1::function<Try<T>(const std::string&)>(
- std::tr1::bind(&parse<T>, std::tr1::placeholders::_1)),
- name,
- std::tr1::placeholders::_2);
-
- add(flag);
-}
-
-
-inline void FlagsBase::add(const Flag& flag)
-{
- if (flags.count(flag.name) > 0) {
- EXIT(1) << "Attempted to add duplicate flag '" << flag.name << "'";
- } else if (flag.name.find("no-") == 0) {
- EXIT(1) << "Attempted to add flag '" << flag.name
- << "' that starts with the reserved 'no-' prefix";
- }
-
- flags[flag.name] = flag;
-}
-
-
-// Extract environment variable "flags" with the specified prefix.
-inline std::map<std::string, Option<std::string> > extract(
- const std::string& prefix)
-{
- char** environ = os::environ();
-
- std::map<std::string, Option<std::string> > values;
-
- for (int i = 0; environ[i] != NULL; i++) {
- std::string variable = environ[i];
- if (variable.find(prefix) == 0) {
- size_t eq = variable.find_first_of("=");
- if (eq == std::string::npos) {
- continue; // Not expecting a missing '=', but ignore anyway.
- }
- std::string name = variable.substr(prefix.size(), eq - prefix.size());
- name = strings::lower(name); // Allow PREFIX_NAME or PREFIX_name.
- std::string value = variable.substr(eq + 1);
- values[name] = Option<std::string>::some(value);
- }
- }
-
- return values;
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const std::string& prefix,
- bool unknowns)
-{
- return load(extract(prefix), unknowns);
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const Option<std::string>& prefix,
- int argc,
- char** argv,
- bool unknowns,
- bool duplicates)
-{
- std::map<std::string, Option<std::string> > values;
-
- if (prefix.isSome()) {
- values = extract(prefix.get());
- }
-
- // Read flags from the command line.
- for (int i = 1; i < argc; i++) {
- const std::string arg(argv[i]);
-
- std::string name;
- Option<std::string> value = None();
- if (arg.find("--") == 0) {
- size_t eq = arg.find_first_of("=");
- if (eq == std::string::npos && arg.find("--no-") == 0) { // --no-name
- name = arg.substr(2);
- } else if (eq == std::string::npos) { // --name
- name = arg.substr(2);
- } else { // --name=value
- name = arg.substr(2, eq - 2);
- value = arg.substr(eq + 1);
- }
- }
- name = strings::lower(name);
-
- if (!duplicates) {
- if (values.count(name) > 0 ||
- (name.find("no-") == 0 && values.count(name.substr(3)) > 0)) {
- return Error("Duplicate flag '" + name + "' on command line");
- }
- }
-
- values[name] = value;
- }
-
- return load(values, unknowns);
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const std::string& prefix,
- int argc,
- char** argv,
- bool unknowns,
- bool duplicates)
-{
- return load(Option<std::string>::some(prefix),
- argc,
- argv,
- unknowns,
- duplicates);
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const std::map<std::string, Option<std::string> >& values,
- bool unknowns)
-{
- std::map<std::string, Option<std::string> >::const_iterator iterator;
-
- for (iterator = values.begin(); iterator != values.end(); ++iterator) {
- const std::string& name = iterator->first;
- const Option<std::string>& value = iterator->second;
-
- if (flags.count(name) > 0) {
- if (value.isSome()) { // --name=value
- if (flags[name].boolean && value.get() == "") {
- flags[name].loader(this, "true"); // Should never fail.
- } else {
- Try<Nothing> loader = flags[name].loader(this, value.get());
- if (loader.isError()) {
- return Error(
- "Failed to load flag '" + name + "': " + loader.error());
- }
- }
- } else { // --name
- if (flags[name].boolean) {
- flags[name].loader(this, "true"); // Should never fail.
- } else {
- return Error(
- "Failed to load non-boolean flag '" + name + "': Missing value");
- }
- }
- } else if (name.find("no-") == 0) {
- if (flags.count(name.substr(3)) > 0) { // --no-name
- if (flags[name.substr(3)].boolean) {
- if (value.isNone() || value.get() == "") {
- flags[name.substr(3)].loader(this, "false"); // Should never fail.
- } else {
- return Error(
- "Failed to load boolean flag '" + name.substr(3) +
- "' via '" + name + "' with value '" + value.get() + "'");
- }
- } else {
- return Error(
- "Failed to load non-boolean flag '" + name.substr(3) +
- "' via '" + name + "'");
- }
- } else {
- return Error(
- "Failed to load unknown flag '" + name.substr(3) +
- "' via '" + name + "'");
- }
- } else if (!unknowns) {
- return Error("Failed to load unknown flag '" + name + "'");
- }
- }
-
- return Nothing();
-}
-
-
-inline Try<Nothing> FlagsBase::load(
- const std::map<std::string, std::string>& _values,
- bool unknowns)
-{
- std::map<std::string, Option<std::string> > values;
- std::map<std::string, std::string>::const_iterator iterator;
- for (iterator = _values.begin(); iterator != _values.end(); ++iterator) {
- const std::string& name = iterator->first;
- const std::string& value = iterator->second;
- values[name] = Option<std::string>::some(value);
- }
- return load(values, unknowns);
-}
-
-
-inline std::string FlagsBase::usage() const
-{
- const int PAD = 5;
-
- std::string usage;
-
- std::map<std::string, std::string> col1; // key -> col 1 string
-
- // Construct string for the first column and store width of column.
- size_t width = 0;
-
- foreachvalue (const flags::Flag& flag, *this) {
- if (flag.boolean) {
- col1[flag.name] = " --[no-]" + flag.name;
- } else {
- col1[flag.name] = " --" + flag.name + "=VALUE";
- }
- width = std::max(width, col1[flag.name].size());
- }
-
- foreachvalue (const flags::Flag& flag, *this) {
- std::string line = col1[flag.name];
-
- std::string pad(PAD + width - line.size(), ' ');
- line += pad;
-
- size_t pos1 = 0, pos2 = 0;
- pos2 = flag.help.find_first_of("\n\r", pos1);
- line += flag.help.substr(pos1, pos2 - pos1) + "\n";
- usage += line;
-
- while (pos2 != std::string::npos) { // Handle multi-line help strings.
- line = "";
- pos1 = pos2 + 1;
- std::string pad2(PAD + width, ' ');
- line += pad2;
- pos2 = flag.help.find_first_of("\n\r", pos1);
- line += flag.help.substr(pos1, pos2 - pos1) + "\n";
- usage += line;
- }
- }
- return usage;
-}
-
-} // namespace flags {
-
-#endif // __STOUT_FLAGS_FLAGS_HPP__
[03/35] Updated libprocess to use '3rdparty' instead of 'third_party'.
Posted by be...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/flags/loader.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags/loader.hpp b/third_party/libprocess/third_party/stout/include/stout/flags/loader.hpp
deleted file mode 100644
index e5eaf24..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/flags/loader.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef __STOUT_FLAGS_LOADER_HPP__
-#define __STOUT_FLAGS_LOADER_HPP__
-
-#include <string>
-
-#include <tr1/functional>
-
-#include <stout/error.hpp>
-#include <stout/nothing.hpp>
-#include <stout/option.hpp>
-#include <stout/try.hpp>
-
-#include <stout/flags/parse.hpp>
-
-namespace flags {
-
-// Forward declaration.
-class FlagsBase;
-
-template <typename T>
-struct Loader
-{
- static Try<Nothing> load(
- T* flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- Try<T> t = parse(value);
- if (t.isSome()) {
- *flag = t.get();
- } else {
- return Error("Failed to load value '" + value + "': " + t.error());
- }
- return Nothing();
- }
-};
-
-
-template <typename T>
-struct OptionLoader
-{
- static Try<Nothing> load(
- Option<T>* flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- Try<T> t = parse(value);
- if (t.isSome()) {
- *flag = Option<T>::some(t.get());
- } else {
- return Error("Failed to load value '" + value + "': " + t.error());
- }
- return Nothing();
- }
-};
-
-
-template <typename F, typename T>
-struct MemberLoader
-{
- static Try<Nothing> load(
- FlagsBase* base,
- T F::*flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- F* f = dynamic_cast<F*>(base);
- if (f != NULL) {
- Try<T> t = parse(value);
- if (t.isSome()) {
- f->*flag = t.get();
- } else {
- return Error("Failed to load value '" + value + "': " + t.error());
- }
- }
- return Nothing();
- }
-};
-
-
-template <typename F, typename T>
-struct OptionMemberLoader
-{
- static Try<Nothing> load(
- FlagsBase* base,
- Option<T> F::*flag,
- const std::tr1::function<Try<T>(const std::string&)>& parse,
- const std::string& name,
- const std::string& value)
- {
- F* f = dynamic_cast<F*>(base);
- if (f != NULL) {
- Try<T> t = parse(value);
- if (t.isSome()) {
- f->*flag = Option<T>::some(t.get());
- } else {
- return Error("Failed to load value '" + value + "': " + t.error());
- }
- }
- return Nothing();
- }
-};
-
-} // namespace flags {
-
-#endif // __STOUT_FLAGS_LOADER_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/flags/parse.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/flags/parse.hpp b/third_party/libprocess/third_party/stout/include/stout/flags/parse.hpp
deleted file mode 100644
index 54eb35c..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/flags/parse.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __STOUT_FLAGS_PARSE_HPP__
-#define __STOUT_FLAGS_PARSE_HPP__
-
-#include <sstream> // For istringstream.
-#include <string>
-
-#include <tr1/functional>
-
-#include <stout/duration.hpp>
-#include <stout/error.hpp>
-#include <stout/try.hpp>
-
-namespace flags {
-
-template <typename T>
-Try<T> parse(const std::string& value)
-{
- T t;
- std::istringstream in(value);
- in >> t;
- if (!in.good() && !in.eof()) {
- return Error("Failed to convert into required type");
- }
- return t;
-}
-
-
-template <>
-inline Try<std::string> parse(const std::string& value)
-{
- return value;
-}
-
-
-template <>
-inline Try<bool> parse(const std::string& value)
-{
- if (value == "true" || value == "1") {
- return true;
- } else if (value == "false" || value == "0") {
- return false;
- }
- return Error("Expecting a boolean (e.g., true or false)");
-}
-
-
-template <>
-inline Try<Duration> parse(const std::string& value)
-{
- return Duration::parse(value);
-}
-
-} // namespace flags {
-
-#endif // __STOUT_FLAGS_PARSE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/foreach.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/foreach.hpp b/third_party/libprocess/third_party/stout/include/stout/foreach.hpp
deleted file mode 100644
index 0afe285..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/foreach.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef __STOUT_FOREACH_HPP__
-#define __STOUT_FOREACH_HPP__
-
-#include <boost/foreach.hpp>
-
-#include <boost/tuple/tuple.hpp>
-
-namespace __foreach__ {
-
-// NOTE: This is a copied from Boost
-// (boost/tuple/detail/tuple_basic_no_partial_spec.hpp) because the
-// new 'boost::tuples::ignore' does not work in our 'foreachkey' and
-// 'foreachvalue'.
-struct swallow_assign {
- template<typename T>
- swallow_assign const& operator=(const T&) const {
- return *this;
- }
-};
-
-swallow_assign const ignore = swallow_assign();
-
-} // namespace __foreach__ {
-
-#define BOOST_FOREACH_PAIR(VARFIRST, VARSECOND, COL) \
- BOOST_FOREACH_PREAMBLE() \
- if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \
- if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else \
- if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_end) = BOOST_FOREACH_END(COL)) {} else \
- for (bool BOOST_FOREACH_ID(_foreach_continue) = true, BOOST_FOREACH_ID(_foreach_onetime) = true; \
- BOOST_FOREACH_ID(_foreach_continue) && !BOOST_FOREACH_DONE(COL); \
- BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0) \
- if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_onetime))) {} else \
- for (VARFIRST = BOOST_FOREACH_DEREF(COL).first; \
- !BOOST_FOREACH_ID(_foreach_onetime); \
- BOOST_FOREACH_ID(_foreach_onetime) = true) \
- if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \
- for (VARSECOND = BOOST_FOREACH_DEREF(COL).second; \
- !BOOST_FOREACH_ID(_foreach_continue); \
- BOOST_FOREACH_ID(_foreach_continue) = true)
-
-#define foreach BOOST_FOREACH
-#define foreachpair BOOST_FOREACH_PAIR
-
-#define foreachkey(VAR, COL) \
- foreachpair (VAR, __foreach__::ignore, COL)
-
-#define foreachvalue(VAR, COL) \
- foreachpair (__foreach__::ignore, VAR, COL)
-
-#endif // __STOUT_FOREACH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/format.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/format.hpp b/third_party/libprocess/third_party/stout/include/stout/format.hpp
deleted file mode 100644
index 71b5986..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/format.hpp
+++ /dev/null
@@ -1,343 +0,0 @@
-#ifndef __STOUT_FORMAT_HPP__
-#define __STOUT_FORMAT_HPP__
-
-#include <stdarg.h> // For 'va_list', 'va_start', 'va_end'.
-#include <stdio.h> // For 'vasprintf'.
-
-#include <string>
-
-#include <tr1/type_traits> // For 'is_pod'.
-
-#include "error.hpp"
-#include "try.hpp"
-#include "stringify.hpp"
-
-
-// The 'strings::format' functions produces strings based on the
-// printf family of functions. Except, unlike the printf family of
-// functions, the 'strings::format' routines attempt to "stringify"
-// any arguments that are not POD types (i.e., "plain old data":
-// primitives, pointers, certain structs/classes and unions,
-// etc). This enables passing structs/classes to 'strings::format'
-// provided there is a definition/specialization of 'ostream::operator
-// <<' available for that type. Note that the '%s' format specifier is
-// expected for each argument that gets stringified. A specialization
-// for std::string is also provided so that std::string::c_str is not
-// necessary (but again, '%s' is expected as the format specifier).
-
-namespace strings {
-namespace internal {
-
-Try<std::string> format(const std::string& fmt, va_list args);
-Try<std::string> format(const std::string& fmt, ...);
-
-template <typename T, bool b>
-struct stringify;
-
-} // namespace internal {
-
-
-#if __cplusplus >= 201103L
-template <typename ...T>
-Try<std::string> format(const std::string& s, const T& ...t)
-{
- return internal::format(
- s,
- internal::stringify<T, !std::is_pod<T>::value>(t).get()...);
-}
-#else
-template <typename T1>
-Try<std::string> format(const std::string& s,
- const T1& t1)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get());
-}
-
-
-template <typename T1,
- typename T2>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T1>::value>(t2).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6,
- typename T7>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6,
- const T7& t7)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
- internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6,
- typename T7,
- typename T8>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6,
- const T7& t7,
- const T8& t8)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
- internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
- internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6,
- typename T7,
- typename T8,
- typename T9>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6,
- const T7& t7,
- const T8& t8,
- const T9& t9)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
- internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
- internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get(),
- internal::stringify<T9, !std::tr1::is_pod<T9>::value>(t9).get());
-}
-
-
-template <typename T1,
- typename T2,
- typename T3,
- typename T4,
- typename T5,
- typename T6,
- typename T7,
- typename T8,
- typename T9,
- typename T10>
-Try<std::string> format(const std::string& s,
- const T1& t1,
- const T2& t2,
- const T3& t3,
- const T4& t4,
- const T5& t5,
- const T6& t6,
- const T7& t7,
- const T8& t8,
- const T9& t9,
- const T10& t10)
-{
- return internal::format(
- s,
- internal::stringify<T1, !std::tr1::is_pod<T1>::value>(t1).get(),
- internal::stringify<T2, !std::tr1::is_pod<T2>::value>(t2).get(),
- internal::stringify<T3, !std::tr1::is_pod<T3>::value>(t3).get(),
- internal::stringify<T4, !std::tr1::is_pod<T4>::value>(t4).get(),
- internal::stringify<T5, !std::tr1::is_pod<T5>::value>(t5).get(),
- internal::stringify<T6, !std::tr1::is_pod<T6>::value>(t6).get(),
- internal::stringify<T7, !std::tr1::is_pod<T7>::value>(t7).get(),
- internal::stringify<T8, !std::tr1::is_pod<T8>::value>(t8).get(),
- internal::stringify<T9, !std::tr1::is_pod<T9>::value>(t9).get(),
- internal::stringify<T10, !std::tr1::is_pod<T10>::value>(t10).get());
-}
-#endif // __cplusplus >= 201103L
-
-
-namespace internal {
-
-inline Try<std::string> format(const std::string& fmt, va_list args)
-{
- char* temp;
- if (vasprintf(&temp, fmt.c_str(), args) == -1) {
- // Note that temp is undefined, so we do not need to call free.
- return Error("Failed to format '" + fmt + "' (possibly out of memory)");
- }
- std::string result(temp);
- free(temp);
- return result;
-}
-
-
-inline Try<std::string> format(const std::string& fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- const Try<std::string>& result = format(fmt, args);
- va_end(args);
- return result;
-}
-
-
-template <typename T>
-struct stringify<T, false>
-{
- stringify(const T& _t) : t(_t) {}
- const T& get() { return t; }
- const T& t;
-};
-
-
-template <typename T>
-struct stringify<T, true>
-{
- stringify(const T& _t) : s(::stringify(_t)) {}
- const char* get() { return s.c_str(); }
-
- // NOTE: We need to do the copy here, because the temporary returned by
- // ::stringify() doesn't outlive the get() call inside strings::format().
- // TODO(vinod): Figure out a fix for using const ref here.
- const std::string s;
-};
-
-
-template <>
-struct stringify<std::string, true>
-{
- stringify(const std::string& _s) : s(_s) {}
- const char* get() { return s.c_str(); }
- const std::string& s;
-};
-
-} // namespace internal {
-} // namespace strings {
-
-#endif // __STOUT_FORMAT_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/fs.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/fs.hpp b/third_party/libprocess/third_party/stout/include/stout/fs.hpp
deleted file mode 100644
index c1a05b5..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/fs.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef __STOUT_FS_HPP__
-#define __STOUT_FS_HPP__
-
-#include <unistd.h> // For symlink.
-
-#include <sys/statvfs.h>
-
-#include <string>
-
-#include "bytes.hpp"
-#include "error.hpp"
-#include "nothing.hpp"
-#include "try.hpp"
-
-// TODO(bmahler): Migrate the appropriate 'os' namespace funtions here.
-namespace fs {
-
-// Returns the total available disk size in bytes.
-inline Try<Bytes> available(const std::string& path = "/")
-{
- struct statvfs buf;
- if (::statvfs(path.c_str(), &buf) < 0) {
- return ErrnoError();
- }
- return Bytes(buf.f_bavail * buf.f_frsize);
-}
-
-
-// Returns relative disk usage of the file system that the given path
-// is mounted at.
-inline Try<double> usage(const std::string& path = "/")
-{
- struct statvfs buf;
- if (statvfs(path.c_str(), &buf) < 0) {
- return ErrnoError("Error invoking statvfs on '" + path + "'");
- }
- return (double) (buf.f_blocks - buf.f_bfree) / buf.f_blocks;
-}
-
-
-inline Try<Nothing> symlink(
- const std::string& original,
- const std::string& link)
-{
- if (::symlink(original.c_str(), link.c_str()) < 0) {
- return ErrnoError();
- }
- return Nothing();
-}
-
-} // namespace fs {
-
-#endif // __STOUT_FS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/gtest.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/gtest.hpp b/third_party/libprocess/third_party/stout/include/stout/gtest.hpp
deleted file mode 100644
index 3c34124..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/gtest.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef __STOUT_GTEST_HPP__
-#define __STOUT_GTEST_HPP__
-
-#include <gtest/gtest.h>
-
-#include <string>
-
-#include <stout/option.hpp>
-#include <stout/result.hpp>
-#include <stout/try.hpp>
-
-
-template <typename T>
-::testing::AssertionResult AssertSome(
- const char* expr,
- const Option<T>& actual)
-{
- if (actual.isNone()) {
- return ::testing::AssertionFailure()
- << expr << " is NONE";
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T>
-::testing::AssertionResult AssertSome(
- const char* expr,
- const Try<T>& actual)
-{
- if (actual.isError()) {
- return ::testing::AssertionFailure()
- << expr << ": " << actual.error();
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T>
-::testing::AssertionResult AssertSome(
- const char* expr,
- const Result<T>& actual)
-{
- if (actual.isNone()) {
- return ::testing::AssertionFailure()
- << expr << " is NONE";
- } else if (actual.isError()) {
- return ::testing::AssertionFailure()
- << expr << ": " << actual.error();
- }
-
- return ::testing::AssertionSuccess();
-}
-
-
-template <typename T1, typename T2>
-::testing::AssertionResult AssertSomeEq(
- const char* expectedExpr,
- const char* actualExpr,
- const T1& expected,
- const T2& actual) // Duck typing!
-{
- const ::testing::AssertionResult result = AssertSome(actualExpr, actual);
-
- if (result) {
- if (expected == actual.get()) {
- return ::testing::AssertionSuccess();
- } else {
- return ::testing::AssertionFailure()
- << "Value of: (" << actualExpr << ").get()\n"
- << " Actual: " << ::testing::PrintToString(actual.get()) << "\n"
- << "Expected: " << expectedExpr << "\n"
- << "Which is: " << ::testing::PrintToString(expected);
- }
- }
-
- return result;
-}
-
-
-#define ASSERT_SOME(actual) \
- ASSERT_PRED_FORMAT1(AssertSome, actual)
-
-
-#define EXPECT_SOME(actual) \
- EXPECT_PRED_FORMAT1(AssertSome, actual)
-
-
-#define ASSERT_SOME_EQ(expected, actual) \
- ASSERT_PRED_FORMAT2(AssertSomeEq, expected, actual)
-
-
-#define EXPECT_SOME_EQ(expected, actual) \
- EXPECT_PRED_FORMAT2(AssertSomeEq, expected, actual)
-
-
-#define ASSERT_SOME_TRUE(actual) \
- ASSERT_PRED_FORMAT2(AssertSomeEq, true, actual)
-
-
-#define EXPECT_SOME_TRUE(actual) \
- EXPECT_PRED_FORMAT2(AssertSomeEq, true, actual)
-
-
-#define ASSERT_SOME_FALSE(actual) \
- ASSERT_PRED_FORMAT2(AssertSomeEq, false, actual)
-
-
-#define EXPECT_SOME_FALSE(actual) \
- EXPECT_PRED_FORMAT2(AssertSomeEq, false, actual)
-
-
-#define ASSERT_ERROR(actual) \
- ASSERT_TRUE(actual.isError())
-
-
-#define EXPECT_ERROR(actual) \
- EXPECT_TRUE(actual.isError())
-
-#endif // __STOUT_GTEST_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/gzip.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/gzip.hpp b/third_party/libprocess/third_party/stout/include/stout/gzip.hpp
deleted file mode 100644
index ef36f1b..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/gzip.hpp
+++ /dev/null
@@ -1,149 +0,0 @@
-#ifndef __STOUT_GZIP_HPP__
-#define __STOUT_GZIP_HPP__
-
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-#include <string>
-
-#include "error.hpp"
-#include "try.hpp"
-
-// Compression utilities.
-// TODO(bmahler): Provide streaming compression / decompression as well.
-namespace gzip {
-
-// We use a 16KB buffer with zlib compression / decompression.
-#define GZIP_BUFFER_SIZE 16384
-
-// Returns a gzip compressed version of the provided string.
-// The compression level should be within the range [-1, 9].
-// See zlib.h:
-// #define Z_NO_COMPRESSION 0
-// #define Z_BEST_SPEED 1
-// #define Z_BEST_COMPRESSION 9
-// #define Z_DEFAULT_COMPRESSION (-1)
-inline Try<std::string> compress(
- const std::string& decompressed,
-#ifdef HAVE_LIBZ
- int level = Z_DEFAULT_COMPRESSION)
-#else
- int level = -1)
-#endif
-{
-#ifndef HAVE_LIBZ
- return Error("libz is not available");
-#else
- // Verify the level is within range.
- if (!(level == Z_DEFAULT_COMPRESSION ||
- (level >= Z_NO_COMPRESSION && level <= Z_BEST_COMPRESSION))) {
- return Error("Invalid compression level: " + level);
- }
-
- z_stream_s stream;
- stream.next_in =
- const_cast<Bytef*>(reinterpret_cast<const Bytef*>(decompressed.data()));
- stream.avail_in = decompressed.length();
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = Z_NULL;
-
- int code = deflateInit2(
- &stream,
- level, // Compression level.
- Z_DEFLATED, // Compression method.
- MAX_WBITS + 16, // Zlib magic for gzip compression / decompression.
- 8, // Default memLevel value.
- Z_DEFAULT_STRATEGY);
-
- if (code != Z_OK) {
- return Error("Failed to initialize zlib: " + std::string(stream.msg));
- }
-
- // Build up the compressed result.
- Bytef buffer[GZIP_BUFFER_SIZE];
- std::string result = "";
- do {
- stream.next_out = buffer;
- stream.avail_out = GZIP_BUFFER_SIZE;
- code = deflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
-
- if (code != Z_OK && code != Z_STREAM_END) {
- Error error(std::string(stream.msg));
- deflateEnd(&stream);
- return error;
- }
-
- // Consume output and reset the buffer.
- result.append(
- reinterpret_cast<char*>(buffer),
- GZIP_BUFFER_SIZE - stream.avail_out);
- stream.next_out = buffer;
- stream.avail_out = GZIP_BUFFER_SIZE;
- } while (code != Z_STREAM_END);
-
- code = deflateEnd(&stream);
- if (code != Z_OK) {
- return Error("Failed to clean up zlib: " + std::string(stream.msg));
- }
- return result;
-#endif // HAVE_LIBZ
-}
-
-
-// Returns a gzip decompressed version of the provided string.
-inline Try<std::string> decompress(const std::string& compressed)
-{
-#ifndef HAVE_LIBZ
- return Error("libz is not available");
-#else
- z_stream_s stream;
- stream.next_in =
- const_cast<Bytef*>(reinterpret_cast<const Bytef*>(compressed.data()));
- stream.avail_in = compressed.length();
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = Z_NULL;
-
- int code = inflateInit2(
- &stream,
- MAX_WBITS + 16); // Zlib magic for gzip compression / decompression.
-
- if (code != Z_OK) {
- return Error("Failed to initialize zlib: " + std::string(stream.msg));
- }
-
- // Build up the decompressed result.
- Bytef buffer[GZIP_BUFFER_SIZE];
- std::string result = "";
- do {
- stream.next_out = buffer;
- stream.avail_out = GZIP_BUFFER_SIZE;
- code = inflate(&stream, stream.avail_in > 0 ? Z_NO_FLUSH : Z_FINISH);
-
- if (code != Z_OK && code != Z_STREAM_END) {
- Error error(std::string(stream.msg));
- inflateEnd(&stream);
- return error;
- }
-
- // Consume output and reset the buffer.
- result.append(
- reinterpret_cast<char*>(buffer),
- GZIP_BUFFER_SIZE - stream.avail_out);
- stream.next_out = buffer;
- stream.avail_out = GZIP_BUFFER_SIZE;
- } while (code != Z_STREAM_END);
-
- code = inflateEnd(&stream);
- if (code != Z_OK) {
- return Error("Failed to clean up zlib: " + std::string(stream.msg));
- }
- return result;
-#endif // HAVE_LIBZ
-}
-
-} // namespace gzip {
-
-#endif // __STOUT_GZIP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/hashmap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/hashmap.hpp b/third_party/libprocess/third_party/stout/include/stout/hashmap.hpp
deleted file mode 100644
index 796cb50..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/hashmap.hpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef __STOUT_HASHMAP_HPP__
-#define __STOUT_HASHMAP_HPP__
-
-#include <boost/get_pointer.hpp>
-#include <boost/unordered_map.hpp>
-
-#include "hashset.hpp"
-#include "foreach.hpp"
-#include "none.hpp"
-#include "option.hpp"
-
-
-// Provides a hash map via Boost's 'unordered_map'. For most intensive
-// purposes this could be accomplished with a templated typedef, but
-// those don't exist (until C++-11). Also, doing it this way allows us
-// to add functionality, or better naming of existing functionality,
-// etc.
-
-template <typename Key, typename Value>
-class hashmap : public boost::unordered_map<Key, Value>
-{
-public:
- // An explicit default constructor is needed so
- // 'const hashmap<T> map;' is not an error.
- hashmap() {}
-
- // Checks whether this map contains a binding for a key.
- bool contains(const Key& key) const
- {
- return boost::unordered_map<Key, Value>::count(key) > 0;
- }
-
- // Checks whether there exists a bound value in this map.
- bool containsValue(const Value& v) const
- {
- foreachvalue (const Value& value, *this) {
- if (value == v) {
- return true;
- }
- }
- }
-
- // Returns an Option for the binding to the key.
- Option<Value> get(const Key& key) const
- {
- typedef typename boost::unordered_map<Key, Value>::const_iterator
- const_iterator;
- const_iterator it = boost::unordered_map<Key, Value>::find(key);
- if (it == boost::unordered_map<Key, Value>::end()) {
- return None();
- }
- return it->second;
- }
-
- // Returns the set of keys in this map.
- hashset<Key> keys() const
- {
- hashset<Key> result;
- foreachkey (const Key& key, *this) {
- result.insert(key);
- }
- return result;
- }
-
- // Returns the set of values in this map.
- hashset<Value> values() const
- {
- hashset<Value> result;
- foreachvalue (const Value& value, *this) {
- result.insert(value);
- }
- return result;
- }
-
- // Checks whether there exists a value in this map that returns the
- // a result equal to 'r' when the specified method is invoked.
- template <typename R, typename T>
- bool existsValue(R (T::*method)(), R r) const
- {
- foreachvalue (const Value& value, *this) {
- const T* t = boost::get_pointer(value);
- if (t->*method() == r) {
- return true;
- }
- }
- }
-
- // Checks whether there exists a value in this map whose specified
- // member is equal to 'r'.
- template <typename R, typename T>
- bool existsValue(R (T::*member), R r) const
- {
- foreachvalue (const Value& value, *this) {
- const T* t = boost::get_pointer(value);
- if (t->*member == r) {
- return true;
- }
- }
- }
-};
-
-#endif // __STOUT_HASHMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/hashset.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/hashset.hpp b/third_party/libprocess/third_party/stout/include/stout/hashset.hpp
deleted file mode 100644
index f584545..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/hashset.hpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef __STOUT_HASHSET_HPP__
-#define __STOUT_HASHSET_HPP__
-
-#include <boost/get_pointer.hpp>
-#include <boost/unordered_set.hpp>
-
-#include "foreach.hpp"
-
-
-// Provides a hash set via Boost's 'unordered_set'. For most intensive
-// purposes this could be accomplished with a templated typedef, but
-// those don't exist (until C++-11). Also, doing it this way allows us
-// to add functionality, or better naming of existing functionality,
-// etc.
-
-template <typename Elem>
-class hashset : public boost::unordered_set<Elem>
-{
-public:
- // An explicit default constructor is needed so
- // 'const hashset<T> map;' is not an error.
- hashset() {}
-
- // Checks whether this map contains a binding for a key.
- bool contains(const Elem& elem) const
- {
- return boost::unordered_set<Elem>::count(elem) > 0;
- }
-
- // Checks whether there exists a value in this set that returns the
- // a result equal to 'r' when the specified method is invoked.
- template <typename R, typename T>
- bool exists(R (T::*method)(), R r) const
- {
- foreach (const Elem& elem, *this) {
- const T* t = boost::get_pointer(elem);
- if (t->*method() == r) {
- return true;
- }
- }
- }
-
- // Checks whether there exists an element in this set whose
- // specified member is equal to 'r'.
- template <typename R, typename T>
- bool exists(R (T::*member), R r) const
- {
- foreach (const Elem& elem, *this) {
- const T* t = boost::get_pointer(elem);
- if (t->*member == r) {
- return true;
- }
- }
- }
-};
-
-#endif // __STOUT_HASHSET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/json.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/json.hpp b/third_party/libprocess/third_party/stout/include/stout/json.hpp
deleted file mode 100644
index e2cd4f2..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/json.hpp
+++ /dev/null
@@ -1,202 +0,0 @@
-#ifndef __STOUT_JSON__
-#define __STOUT_JSON__
-
-#include <iomanip>
-#include <iostream>
-#include <list>
-#include <map>
-#include <string>
-
-#include <boost/variant.hpp>
-
-#include <stout/foreach.hpp>
-
-// TODO(jsirois): Implement parsing that constructs JSON objects.
-
-
-namespace JSON {
-
-// Implementation of the JavaScript Object Notation (JSON) grammar
-// using boost::variant. We explicitly define each "type" of the
-// grammar, including 'true' (json::True), 'false' (json::False), and
-// 'null' (json::Null), for clarity and also because boost::variant
-// "picks" the wrong type when we try and use std::string, long (or
-// int), double (or float), and bool all in the same variant (while it
-// does work with explicit casts, it seemed bad style to force people
-// to put those casts in place). We could have avoided using
-// json::String or json::Number and just used std::string and double
-// respectively, but we choose to include them for completeness
-// (although, this does pay a 2x cost when compiling thanks to all the
-// extra template instantiations).
-
-struct String;
-struct Number;
-struct Object;
-struct Array;
-struct True;
-struct False;
-struct Null;
-
-
-typedef boost::variant<boost::recursive_wrapper<String>,
- boost::recursive_wrapper<Number>,
- boost::recursive_wrapper<Object>,
- boost::recursive_wrapper<Array>,
- boost::recursive_wrapper<True>,
- boost::recursive_wrapper<False>,
- boost::recursive_wrapper<Null> > Value;
-
-
-struct String
-{
- String() {}
- String(const char* _value) : value(_value) {}
- String(const std::string& _value) : value(_value) {}
- std::string value;
-};
-
-
-struct Number
-{
- Number() {}
- Number(double _value) : value(_value) {}
- double value;
-};
-
-
-struct Object
-{
- std::map<std::string, Value> values;
-};
-
-
-struct Array
-{
- std::list<Value> values;
-};
-
-
-struct True {};
-
-
-struct False {};
-
-
-struct Null {};
-
-
-// Implementation of rendering JSON objects built above using standard
-// C++ output streams. The visitor pattern is used thanks to to build
-// a "renderer" with boost::static_visitor and two top-level render
-// routines are provided for rendering JSON objects and arrays.
-
-struct Renderer : boost::static_visitor<>
-{
- Renderer(std::ostream& _out) : out(_out) {}
-
- void operator () (const String& string) const
- {
- // TODO(benh): This escaping DOES NOT handle unicode, it encodes as ASCII.
- // See RFC4627 for the JSON string specificiation.
- out << "\"";
- foreach (unsigned char c, string.value) {
- switch (c) {
- case '"': out << "\\\""; break;
- case '\\': out << "\\\\"; break;
- case '/': out << "\\/"; break;
- case '\b': out << "\\b"; break;
- case '\f': out << "\\f"; break;
- case '\n': out << "\\n"; break;
- case '\r': out << "\\r"; break;
- case '\t': out << "\\t"; break;
- default:
- // See RFC4627 for these ranges.
- if ((c >= 0x20 && c <= 0x21) ||
- (c >= 0x23 && c <= 0x5B) ||
- (c >= 0x5D && c < 0x7F)) {
- out << c;
- } else {
- // NOTE: We also escape all bytes > 0x7F since they imply more than
- // 1 byte in UTF-8. This is why we don't escape UTF-8 properly.
- // See RFC4627 for the escaping format: \uXXXX (X is a hex digit).
- // Each byte here will be of the form: \u00XX (this is why we need
- // setw and the cast to unsigned int).
- out << "\\u" << std::setfill('0') << std::setw(4)
- << std::hex << std::uppercase << (unsigned int) c;
- }
- break;
- }
- }
- out << "\"";
- }
-
- void operator () (const Number& number) const
- {
- out.precision(10);
- out << number.value;
- }
-
- void operator () (const Object& object) const
- {
- out << "{";
- std::map<std::string, Value>::const_iterator iterator;
- iterator = object.values.begin();
- while (iterator != object.values.end()) {
- out << "\"" << (*iterator).first << "\":";
- boost::apply_visitor(Renderer(out), (*iterator).second);
- if (++iterator != object.values.end()) {
- out << ",";
- }
- }
- out << "}";
- }
-
- void operator () (const Array& array) const
- {
- out << "[";
- std::list<Value>::const_iterator iterator;
- iterator = array.values.begin();
- while (iterator != array.values.end()) {
- boost::apply_visitor(Renderer(out), *iterator);
- if (++iterator != array.values.end()) {
- out << ",";
- }
- }
- out << "]";
- }
-
- void operator () (const True&) const
- {
- out << "true";
- }
-
- void operator () (const False&) const
- {
- out << "false";
- }
-
- void operator () (const Null&) const
- {
- out << "null";
- }
-
-private:
- std::ostream& out;
-};
-
-
-inline void render(std::ostream& out, const Value& value)
-{
- boost::apply_visitor(Renderer(out), value);
-}
-
-
-inline std::ostream& operator<<(std::ostream& out, const JSON::Value& value)
-{
- JSON::render(out, value);
- return out;
-}
-
-} // namespace JSON {
-
-#endif // __STOUT_JSON__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/lambda.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/lambda.hpp b/third_party/libprocess/third_party/stout/include/stout/lambda.hpp
deleted file mode 100644
index d493353..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/lambda.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __STOUT_LAMBDA_HPP__
-#define __STOUT_LAMBDA_HPP__
-
-#include <tr1/functional>
-
-namespace lambda {
-
-using std::tr1::bind;
-using std::tr1::function;
-using namespace std::tr1::placeholders;
-
-} // namespace lambda {
-
-#endif // __STOUT_LAMBDA_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/multihashmap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/multihashmap.hpp b/third_party/libprocess/third_party/stout/include/stout/multihashmap.hpp
deleted file mode 100644
index 10e49dc..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/multihashmap.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef __STOUT_MULTIHASHMAP_HPP__
-#define __STOUT_MULTIHASHMAP_HPP__
-
-#include <algorithm> // For find.
-#include <list>
-#include <set>
-#include <utility>
-
-#include <boost/unordered_map.hpp>
-
-
-// Implementation of a hash multimap via Boost's 'unordered_multimap'
-// but with a better interface. The rationale for creating this is
-// that the std::multimap interface is painful to use (requires lots
-// of iterator garbage, as well as the use of 'equal_range' which
-// makes for cluttered code).
-template <typename K, typename V>
-class multihashmap : public boost::unordered_multimap<K, V>
-{
-public:
- void put(const K& key, const V& value);
- std::list<V> get(const K& key) const;
- std::set<K> keys() const;
- bool remove(const K& key);
- bool remove(const K& key, const V& value);
- bool contains(const K& key) const;
- bool contains(const K& key, const V& value) const;
-};
-
-
-template <typename K, typename V>
-void multihashmap<K, V>::put(const K& key, const V& value)
-{
- boost::unordered_multimap<K, V>::insert(std::pair<K, V>(key, value));
-}
-
-
-template <typename K, typename V>
-std::list<V> multihashmap<K, V>::get(const K& key) const
-{
- std::list<V> values; // Values to return.
-
- std::pair<typename boost::unordered_multimap<K, V>::const_iterator,
- typename boost::unordered_multimap<K, V>::const_iterator> range;
-
- range = boost::unordered_multimap<K, V>::equal_range(key);
-
- typename boost::unordered_multimap<K, V>::const_iterator i;
- for (i = range.first; i != range.second; ++i) {
- values.push_back(i->second);
- }
-
- return values;
-}
-
-
-template <typename K, typename V>
-std::set<K> multihashmap<K, V>::keys() const
-{
- std::set<K> keys;
- foreachkey (const K& key, *this) {
- keys.insert(key);
- }
- return keys;
-}
-
-
-template <typename K, typename V>
-bool multihashmap<K, V>::remove(const K& key)
-{
- return boost::unordered_multimap<K, V>::erase(key) > 0;
-}
-
-
-template <typename K, typename V>
-bool multihashmap<K, V>::remove(const K& key, const V& value)
-{
- std::pair<typename boost::unordered_multimap<K, V>::iterator,
- typename boost::unordered_multimap<K, V>::iterator> range;
-
- range = boost::unordered_multimap<K, V>::equal_range(key);
-
- typename boost::unordered_multimap<K, V>::iterator i;
- for (i = range.first; i != range.second; ++i) {
- if (i->second == value) {
- boost::unordered_multimap<K, V>::erase(i);
- return true;
- }
- }
-
- return false;
-}
-
-
-template <typename K, typename V>
-bool multihashmap<K, V>::contains(const K& key) const
-{
- return multihashmap<K, V>::count(key) > 0;
-}
-
-
-template <typename K, typename V>
-bool multihashmap<K, V>::contains(const K& key, const V& value) const
-{
- const std::list<V>& values = get(key);
- return std::find(values.begin(), values.end(), value) != values.end();
-}
-
-#endif // __STOUT_MULTIHASHMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/multimap.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/multimap.hpp b/third_party/libprocess/third_party/stout/include/stout/multimap.hpp
deleted file mode 100644
index 187ad79..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/multimap.hpp
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef __STOUT_MULTIMAP_HPP__
-#define __STOUT_MULTIMAP_HPP__
-
-#include <algorithm>
-#include <list>
-#include <map>
-#include <set>
-#include <utility>
-
-// Implementation of a multimap via std::multimap but with a better
-// interface. The rationale for creating this is that the
-// std::multimap interface is painful to use (requires lots of
-// iterator garbage, as well as the use of 'equal_range' which makes
-// for cluttered code).
-template <typename K, typename V>
-class Multimap : public std::multimap<K, V>
-{
-public:
- void put(const K& key, const V& value);
- std::list<V> get(const K& key) const;
- std::set<K> keys() const;
- bool remove(const K& key);
- bool remove(const K& key, const V& value);
- bool contains(const K& key) const;
- bool contains(const K& key, const V& value) const;
-};
-
-
-template <typename K, typename V>
-void Multimap<K, V>::put(const K& key, const V& value)
-{
- std::multimap<K, V>::insert(std::pair<K, V>(key, value));
-}
-
-
-template <typename K, typename V>
-std::list<V> Multimap<K, V>::get(const K& key) const
-{
- std::list<V> values; // Values to return.
-
- std::pair<typename std::multimap<K, V>::const_iterator,
- typename std::multimap<K, V>::const_iterator> range;
-
- range = std::multimap<K, V>::equal_range(key);
-
- typename std::multimap<K, V>::const_iterator i;
- for (i = range.first; i != range.second; ++i) {
- values.push_back(i->second);
- }
-
- return values;
-}
-
-
-template <typename K, typename V>
-std::set<K> Multimap<K, V>::keys() const
-{
- std::set<K> keys;
- foreachkey (const K& key, *this) {
- keys.insert(key);
- }
- return keys;
-}
-
-
-template <typename K, typename V>
-bool Multimap<K, V>::remove(const K& key)
-{
- return std::multimap<K, V>::erase(key) > 0;
-}
-
-
-template <typename K, typename V>
-bool Multimap<K, V>::remove(const K& key, const V& value)
-{
- std::pair<typename std::multimap<K, V>::iterator,
- typename std::multimap<K, V>::iterator> range;
-
- range = std::multimap<K, V>::equal_range(key);
-
- typename std::multimap<K, V>::iterator i;
- for (i = range.first; i != range.second; ++i) {
- if (i->second == value) {
- std::multimap<K, V>::erase(i);
- return true;
- }
- }
-
- return false;
-}
-
-
-template <typename K, typename V>
-bool Multimap<K, V>::contains(const K& key) const
-{
- return std::multimap<K, V>::count(key) > 0;
-}
-
-
-template <typename K, typename V>
-bool Multimap<K, V>::contains(const K& key, const V& value) const
-{
- const std::list<V>& values = get(key);
- return std::find(values.begin(), values.end(), value) != values.end();
-}
-
-#endif // __STOUT_MULTIMAP_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/net.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/net.hpp b/third_party/libprocess/third_party/stout/include/stout/net.hpp
deleted file mode 100644
index 1c5f88a..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/net.hpp
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef __STOUT_NET_HPP__
-#define __STOUT_NET_HPP__
-
-#include <netdb.h>
-#include <stdio.h>
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#ifdef HAVE_LIBCURL
-#include <curl/curl.h>
-#endif
-
-#include <string>
-
-#include "error.hpp"
-#include "os.hpp"
-#include "try.hpp"
-
-
-// Network utilities.
-namespace net {
-
-// Returns the HTTP response code resulting from attempting to download the
-// specified HTTP or FTP URL into a file at the specified path.
-inline Try<int> download(const std::string& url, const std::string& path)
-{
-#ifndef HAVE_LIBCURL
- return Error("libcurl is not available");
-#else
- Try<int> fd = os::open(
- path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
-
- if (fd.isError()) {
- return Error(fd.error());
- }
-
- curl_global_init(CURL_GLOBAL_ALL);
- CURL* curl = curl_easy_init();
-
- if (curl == NULL) {
- curl_easy_cleanup(curl);
- os::close(fd.get());
- return Error("Failed to initialize libcurl");
- }
-
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
-
- FILE* file = fdopen(fd.get(), "w");
- if (file == NULL) {
- return ErrnoError("Failed to open file handle of '" + path + "'");
- }
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
-
- CURLcode curlErrorCode = curl_easy_perform(curl);
- if (curlErrorCode != 0) {
- curl_easy_cleanup(curl);
- fclose(file);
- return Error(curl_easy_strerror(curlErrorCode));
- }
-
- long code;
- curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
- curl_easy_cleanup(curl);
-
- if (fclose(file) != 0) {
- return ErrnoError("Failed to close file handle of '" + path + "'");
- }
-
- return Try<int>::some(code);
-#endif // HAVE_LIBCURL
-}
-
-// Returns a Try of the hostname for the provided IP. If the hostname cannot
-// be resolved, then a string version of the IP address is returned.
-inline Try<std::string> getHostname(uint32_t ip)
-{
- sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = ip;
-
- char hostname[MAXHOSTNAMELEN];
- if (getnameinfo(
- (sockaddr*)&addr,
- sizeof(addr),
- hostname,
- MAXHOSTNAMELEN,
- NULL,
- 0,
- 0) != 0) {
- return ErrnoError();
- }
-
- return std::string(hostname);
-}
-
-} // namespace net {
-
-#endif // __STOUT_NET_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/none.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/none.hpp b/third_party/libprocess/third_party/stout/include/stout/none.hpp
deleted file mode 100644
index ea8e0f5..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/none.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef __STOUT_NONE_HPP__
-#define __STOUT_NONE_HPP__
-
-#include "option.hpp"
-#include "result.hpp"
-
-// A "none" type that is implicitly convertible to an Option<T> and
-// Result<T> for any T (effectively "syntactic sugar" to make code
-// more readable). The implementation uses cast operators to perform
-// the conversions instead of adding constructors to Option/Result
-// directly. Performance shouldn't be an issue given that an instance
-// of None has no virtual functions and no fields.
-
-class None
-{
-public:
- template <typename T>
- operator Option<T> () const
- {
- return Option<T>::none();
- }
-
- // Give the compiler some help for nested Option<T>. For example,
- // enable converting None to a Try<Option<T>>. Note that this will
- // bind to the innermost Option<T>.
- template <template <typename> class S, typename T>
- operator S<Option<T> > () const
- {
- return S<Option<T> >(Option<T>::none());
- }
-
- template <typename T>
- operator Result<T> () const
- {
- return Result<T>::none();
- }
-
- // Give the compiler some help for nested Result<T>. For example,
- // enable converting None to a Try<Result<T>>. Note that this will
- // bind to the innermost Result<T>.
- template <template <typename> class S, typename T>
- operator S<Result<T> > () const
- {
- return S<Result<T> >(Result<T>::none());
- }
-
- // Give the compiler some more help to disambiguate the above cast
- // operators from Result<Option<T>>.
- template <typename T>
- operator Result<Option<T> > () const
- {
- return Result<Option<T> >::none();
- }
-};
-
-#endif // __STOUT_NONE_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/nothing.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/nothing.hpp b/third_party/libprocess/third_party/stout/include/stout/nothing.hpp
deleted file mode 100644
index c11a010..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/nothing.hpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __NOTHING_HPP__
-#define __NOTHING_HPP__
-
-struct Nothing {};
-
-#endif // __NOTHING_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/numify.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/numify.hpp b/third_party/libprocess/third_party/stout/include/stout/numify.hpp
deleted file mode 100644
index d23e238..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/numify.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef __STOUT_NUMIFY_HPP__
-#define __STOUT_NUMIFY_HPP__
-
-#include <string>
-
-#include <boost/lexical_cast.hpp>
-
-#include "error.hpp"
-#include "none.hpp"
-#include "option.hpp"
-#include "result.hpp"
-#include "try.hpp"
-
-template <typename T>
-Try<T> numify(const std::string& s)
-{
- try {
- return boost::lexical_cast<T>(s);
- } catch (const boost::bad_lexical_cast&) {
- return Error("Failed to convert '" + s + "' to number");
- }
-}
-
-
-template <typename T>
-Result<T> numify(const Option<std::string>& s)
-{
- if (s.isSome()) {
- Try<T> t = numify<T>(s.get());
- if (t.isSome()) {
- return t.get();
- } else if (t.isError()) {
- return Error(t.error());
- }
- }
-
- return None();
-}
-
-#endif // __STOUT_NUMIFY_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/option.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/option.hpp b/third_party/libprocess/third_party/stout/include/stout/option.hpp
deleted file mode 100644
index f991ae8..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/option.hpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __STOUT_OPTION_HPP__
-#define __STOUT_OPTION_HPP__
-
-#include <assert.h>
-
-template <typename T>
-class Option
-{
-public:
- static Option<T> none()
- {
- return Option<T>(NONE);
- }
-
- static Option<T> some(const T& t)
- {
- return Option<T>(SOME, new T(t));
- }
-
- Option() : state(NONE), t(NULL) {}
-
- Option(const T& _t) : state(SOME), t(new T(_t)) {}
-
- Option(const Option<T>& that)
- {
- state = that.state;
- if (that.t != NULL) {
- t = new T(*that.t);
- } else {
- t = NULL;
- }
- }
-
- ~Option()
- {
- delete t;
- }
-
- Option<T>& operator = (const Option<T>& that)
- {
- if (this != &that) {
- delete t;
- state = that.state;
- if (that.t != NULL) {
- t = new T(*that.t);
- } else {
- t = NULL;
- }
- }
-
- return *this;
- }
-
- bool operator == (const Option<T>& that) const
- {
- return (state == NONE && that.state == NONE) ||
- (state == SOME && that.state == SOME && *t == *that.t);
- }
-
- bool operator != (const Option<T>& that) const
- {
- return !operator == (that);
- }
-
- bool isSome() const { return state == SOME; }
- bool isNone() const { return state == NONE; }
-
- T get() const { assert(state == SOME); return *t; }
-
- T get(const T& _t) const { return state == NONE ? _t : *t; }
-
-private:
- enum State {
- SOME,
- NONE,
- };
-
- Option(State _state, T* _t = NULL)
- : state(_state), t(_t) {}
-
- State state;
- T* t;
-};
-
-#endif // __STOUT_OPTION_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/os.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/os.hpp b/third_party/libprocess/third_party/stout/include/stout/os.hpp
deleted file mode 100644
index 28a08cc..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/os.hpp
+++ /dev/null
@@ -1,1081 +0,0 @@
-#ifndef __STOUT_OS_HPP__
-#define __STOUT_OS_HPP__
-
-#ifdef __APPLE__
-#include <crt_externs.h> // For _NSGetEnviron().
-#endif
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fts.h>
-#include <glob.h>
-#include <libgen.h>
-#include <limits.h>
-#include <netdb.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <glog/logging.h>
-
-#ifdef __linux__
-#include <linux/version.h>
-#endif
-
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#ifdef __APPLE__
-#include <sys/sysctl.h>
-#endif
-#ifdef __linux__
-#include <sys/sysinfo.h>
-#endif
-#include <sys/types.h>
-#include <sys/utsname.h>
-
-#include <list>
-#include <set>
-#include <sstream>
-#include <string>
-
-#include "bytes.hpp"
-#include "duration.hpp"
-#include "error.hpp"
-#include "foreach.hpp"
-#include "none.hpp"
-#include "nothing.hpp"
-#include "path.hpp"
-#include "result.hpp"
-#include "strings.hpp"
-#include "try.hpp"
-
-#ifdef __APPLE__
-// Assigning the result pointer to ret silences an unused var warning.
-#define gethostbyname2_r(name, af, ret, buf, buflen, result, h_errnop) \
- ({ (void)ret; *(result) = gethostbyname2(name, af); 0; })
-#endif // __APPLE__
-
-// Need to declare 'environ' pointer for non OS X platforms.
-#ifndef __APPLE__
-extern char** environ;
-#endif
-
-namespace os {
-
-inline char** environ()
-{
- // Accessing the list of environment variables is platform-specific.
- // On OS X, the 'environ' symbol isn't visible to shared libraries,
- // so we must use the _NSGetEnviron() function (see 'man environ' on
- // OS X). On other platforms, it's fine to access 'environ' from
- // shared libraries.
-#ifdef __APPLE__
- return *_NSGetEnviron();
-#endif
- return ::environ;
-}
-
-
-// Checks if the specified key is in the environment variables.
-inline bool hasenv(const std::string& key)
-{
- char* value = ::getenv(key.c_str());
-
- return value != NULL;
-}
-
-// Looks in the environment variables for the specified key and
-// returns a string representation of it's value. If 'expected' is
-// true (default) and no environment variable matching key is found,
-// this function will exit the process.
-inline std::string getenv(const std::string& key, bool expected = true)
-{
- char* value = ::getenv(key.c_str());
-
- if (expected && value == NULL) {
- LOG(FATAL) << "Expecting '" << key << "' in environment variables";
- }
-
- if (value != NULL) {
- return std::string(value);
- }
-
- return std::string();
-}
-
-
-// Sets the value associated with the specified key in the set of
-// environment variables.
-inline void setenv(const std::string& key,
- const std::string& value,
- bool overwrite = true)
-{
- ::setenv(key.c_str(), value.c_str(), overwrite ? 1 : 0);
-}
-
-
-// Unsets the value associated with the specified key in the set of
-// environment variables.
-inline void unsetenv(const std::string& key)
-{
- ::unsetenv(key.c_str());
-}
-
-
-inline Try<bool> access(const std::string& path, int how)
-{
- if (::access(path.c_str(), how) < 0) {
- if (errno == EACCES) {
- return false;
- } else {
- return ErrnoError();
- }
- }
- return true;
-}
-
-
-inline Try<int> open(const std::string& path, int oflag, mode_t mode = 0)
-{
- int fd = ::open(path.c_str(), oflag, mode);
-
- if (fd < 0) {
- return ErrnoError();
- }
-
- return fd;
-}
-
-
-inline Try<Nothing> close(int fd)
-{
- if (::close(fd) != 0) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-
-inline Try<Nothing> cloexec(int fd)
-{
- int flags = ::fcntl(fd, F_GETFD);
-
- if (flags == -1) {
- return ErrnoError();
- }
-
- if (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-
-inline Try<Nothing> nonblock(int fd)
-{
- int flags = ::fcntl(fd, F_GETFL);
-
- if (flags == -1) {
- return ErrnoError();
- }
-
- if (::fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-
-inline Try<bool> isNonblock(int fd)
-{
- int flags = ::fcntl(fd, F_GETFL);
-
- if (flags == -1) {
- return ErrnoError();
- }
-
- return (flags & O_NONBLOCK) != 0;
-}
-
-
-inline Try<Nothing> touch(const std::string& path)
-{
- Try<int> fd =
- open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IRWXO);
-
- if (fd.isError()) {
- return Error("Failed to open file '" + path + "'");
- }
-
- // TODO(benh): Is opening/closing sufficient to have the same
- // semantics as the touch utility (i.e., doesn't the utility change
- // the modified date)?
- return close(fd.get());
-}
-
-
-// Creates a temporary file using the specified path template. The
-// template may be any path with _6_ `Xs' appended to it, for example
-// /tmp/temp.XXXXXX. The trailing `Xs' are replaced with a unique
-// alphanumeric combination.
-inline Try<std::string> mktemp(const std::string& path = "/tmp/XXXXXX")
-{
- char* temp = new char[path.size() + 1];
- int fd = ::mkstemp(::strcpy(temp, path.c_str()));
-
- if (fd < 0) {
- delete temp;
- return ErrnoError();
- }
-
- // We ignore the return value of close(). This is because users
- // calling this function are interested in the return value of
- // mkstemp(). Also an unsuccessful close() doesn't affect the file.
- os::close(fd);
-
- std::string result(temp);
- delete temp;
- return result;
-}
-
-
-// Write out the string to the file at the current fd position.
-inline Try<Nothing> write(int fd, const std::string& message)
-{
- size_t offset = 0;
-
- while (offset < message.length()) {
- ssize_t length =
- ::write(fd, message.data() + offset, message.length() - offset);
-
- if (length < 0) {
- // TODO(benh): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
- if (errno == EINTR) {
- continue;
- }
- return ErrnoError();
- }
-
- offset += length;
- }
-
- 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 std::string& 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 ErrnoError("Failed to open file '" + path + "'");
- }
-
- Try<Nothing> result = write(fd.get(), message);
-
- // 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;
-}
-
-
-// Reads 'size' bytes from a file from its current offset.
-// If EOF is encountered before reading size bytes, then the offset
-// is restored and none is returned.
-inline Result<std::string> read(int fd, size_t size)
-{
- // Save the current offset.
- off_t current = lseek(fd, 0, SEEK_CUR);
- if (current == -1) {
- return ErrnoError("Failed to lseek to SEEK_CUR");
- }
-
- char* buffer = new char[size];
- size_t offset = 0;
-
- while (offset < size) {
- ssize_t length = ::read(fd, buffer + offset, size - offset);
-
- if (length < 0) {
- // TODO(bmahler): Handle a non-blocking fd? (EAGAIN, EWOULDBLOCK)
- if (errno == EINTR) {
- continue;
- }
- // Attempt to restore the original offset.
- lseek(fd, current, SEEK_SET);
- return ErrnoError();
- } else if (length == 0) {
- // Reached EOF before expected! Restore the offset.
- lseek(fd, current, SEEK_SET);
- return None();
- }
-
- offset += length;
- }
-
- return std::string(buffer, size);
-}
-
-
-// Returns the contents of the file starting from its current offset.
-// If an error occurs, this will attempt to recover the file offset.
-inline Try<std::string> read(int fd)
-{
- // Save the current offset.
- off_t current = lseek(fd, 0, SEEK_CUR);
- if (current == -1) {
- return ErrnoError("Failed to lseek to SEEK_CUR");
- }
-
- // Get the size of the file from the offset.
- off_t size = lseek(fd, current, SEEK_END);
- if (size == -1) {
- return ErrnoError("Failed to lseek to SEEK_END");
- }
-
- // Restore the offset.
- if (lseek(fd, current, SEEK_SET) == -1) {
- return ErrnoError("Failed to lseek with SEEK_SET");
- }
-
- Result<std::string> result = read(fd, size);
- if (result.isNone()) {
- // Hit EOF before reading size bytes.
- return Error("The file size was modified while reading");
- } else if (result.isError()) {
- return Error(result.error());
- }
-
- return result.get();
-}
-
-
-// A wrapper function that wraps the above read() with
-// open and closing the file.
-inline Try<std::string> 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 + "'");
- }
-
- Try<std::string> result = read(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;
-}
-
-
-inline Try<Nothing> rm(const std::string& path)
-{
- if (::remove(path.c_str()) != 0) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-
-inline Try<std::string> basename(const std::string& path)
-{
- char* temp = new char[path.size() + 1];
- char* result = ::basename(::strcpy(temp, path.c_str()));
- if (result == NULL) {
- delete temp;
- return ErrnoError();
- }
-
- std::string s(result);
- delete temp;
- return s;
-}
-
-
-inline Try<std::string> dirname(const std::string& path)
-{
- char* temp = new char[path.size() + 1];
- char* result = ::dirname(::strcpy(temp, path.c_str()));
- if (result == NULL) {
- delete temp;
- return ErrnoError();
- }
-
- std::string s(result);
- delete temp;
- return s;
-}
-
-
-inline Try<std::string> realpath(const std::string& path)
-{
- char temp[PATH_MAX];
- if (::realpath(path.c_str(), temp) == NULL) {
- return ErrnoError();
- }
- return std::string(temp);
-}
-
-
-inline bool isdir(const std::string& path)
-{
- struct stat s;
-
- if (::stat(path.c_str(), &s) < 0) {
- return false;
- }
- return S_ISDIR(s.st_mode);
-}
-
-
-inline bool isfile(const std::string& path)
-{
- struct stat s;
-
- if (::stat(path.c_str(), &s) < 0) {
- return false;
- }
- return S_ISREG(s.st_mode);
-}
-
-
-inline bool islink(const std::string& path)
-{
- struct stat s;
-
- if (::lstat(path.c_str(), &s) < 0) {
- return false;
- }
- return S_ISLNK(s.st_mode);
-}
-
-
-inline bool exists(const std::string& path)
-{
- struct stat s;
-
- if (::lstat(path.c_str(), &s) < 0) {
- return false;
- }
- return true;
-}
-
-
-// TODO(benh): Put this in the 'paths' or 'files' or 'fs' namespace.
-inline Try<long> mtime(const std::string& path)
-{
- struct stat s;
-
- if (::lstat(path.c_str(), &s) < 0) {
- return ErrnoError("Error invoking stat for '" + path + "'");
- }
-
- return s.st_mtime;
-}
-
-
-inline Try<Nothing> mkdir(const std::string& directory, bool recursive = true)
-{
- if (!recursive) {
- if (::mkdir(directory.c_str(), 0755) < 0) {
- return ErrnoError();
- }
- } else {
- std::vector<std::string> tokens = strings::tokenize(directory, "/");
- std::string path = "";
-
- // We got an absolute path, so keep the leading slash.
- if (directory.find_first_of("/") == 0) {
- path = "/";
- }
-
- foreach (const std::string& token, tokens) {
- path += token;
- if (::mkdir(path.c_str(), 0755) < 0 && errno != EEXIST) {
- return ErrnoError();
- }
- path += "/";
- }
- }
-
- return Nothing();
-}
-
-// Creates a temporary directory using the specified path
-// template. The template may be any path with _6_ `Xs' appended to
-// it, for example /tmp/temp.XXXXXX. The trailing `Xs' are replaced
-// with a unique alphanumeric combination.
-inline Try<std::string> mkdtemp(const std::string& path = "/tmp/XXXXXX")
-{
- char* temp = new char[path.size() + 1];
- if (::mkdtemp(::strcpy(temp, path.c_str())) != NULL) {
- std::string result(temp);
- delete temp;
- return result;
- } else {
- delete temp;
- return ErrnoError();
- }
-}
-
-// By default, recursively deletes a directory akin to: 'rm -r'. If the
-// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
-// Note that this function expects an absolute path.
-inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
-{
- if (!recursive) {
- if (::rmdir(directory.c_str()) < 0) {
- return ErrnoError();
- }
- } else {
- char* paths[] = {const_cast<char*>(directory.c_str()), NULL};
-
- FTS* tree = fts_open(paths, FTS_NOCHDIR, NULL);
- if (tree == NULL) {
- return ErrnoError();
- }
-
- FTSENT* node;
- while ((node = fts_read(tree)) != NULL) {
- switch (node->fts_info) {
- case FTS_DP:
- if (::rmdir(node->fts_path) < 0 && errno != ENOENT) {
- return ErrnoError();
- }
- break;
- case FTS_F:
- case FTS_SL:
- if (::unlink(node->fts_path) < 0 && errno != ENOENT) {
- return ErrnoError();
- }
- break;
- default:
- break;
- }
- }
-
- if (errno != 0) {
- return ErrnoError();
- }
-
- if (fts_close(tree) < 0) {
- return ErrnoError();
- }
- }
-
- return Nothing();
-}
-
-
-inline int system(const std::string& command)
-{
- return ::system(command.c_str());
-}
-
-
-// TODO(bmahler): Clean these bool functions to return Try<Nothing>.
-// Changes the specified path's user and group ownership to that of
-// the specified user..
-inline Try<Nothing> chown(
- const std::string& user,
- const std::string& path,
- bool recursive = true)
-{
- passwd* passwd;
- if ((passwd = ::getpwnam(user.c_str())) == NULL) {
- return ErrnoError("Failed to get user information for '" + user + "'");
- }
-
- if (recursive) {
- // TODO(bmahler): Consider walking the file tree instead. We would need
- // to be careful to not miss dotfiles.
- std::string command = "chown -R " + stringify(passwd->pw_uid) + ':' +
- stringify(passwd->pw_gid) + " '" + path + "'";
-
- int status = os::system(command);
- if (status != 0) {
- return ErrnoError(
- "Failed to execute '" + command +
- "' (exit status: " + stringify(status) + ")");
- }
- } else {
- if (::chown(path.c_str(), passwd->pw_uid, passwd->pw_gid) < 0) {
- return ErrnoError();
- }
- }
-
- return Nothing();
-}
-
-
-inline bool chmod(const std::string& path, int mode)
-{
- if (::chmod(path.c_str(), mode) < 0) {
- PLOG(ERROR) << "Failed to changed the mode of the path '" << path << "'";
- return false;
- }
-
- return true;
-}
-
-
-inline bool chdir(const std::string& directory)
-{
- if (::chdir(directory.c_str()) < 0) {
- PLOG(ERROR) << "Failed to change directory";
- return false;
- }
-
- return true;
-}
-
-
-inline bool su(const std::string& user)
-{
- passwd* passwd;
- if ((passwd = ::getpwnam(user.c_str())) == NULL) {
- PLOG(ERROR) << "Failed to get user information for '"
- << user << "', getpwnam";
- return false;
- }
-
- if (::setgid(passwd->pw_gid) < 0) {
- PLOG(ERROR) << "Failed to set group id, setgid";
- return false;
- }
-
- if (::setuid(passwd->pw_uid) < 0) {
- PLOG(ERROR) << "Failed to set user id, setuid";
- return false;
- }
-
- return true;
-}
-
-
-inline std::string getcwd()
-{
- size_t size = 100;
-
- while (true) {
- char* temp = new char[size];
- if (::getcwd(temp, size) == temp) {
- std::string result(temp);
- delete[] temp;
- return result;
- } else {
- if (errno != ERANGE) {
- delete[] temp;
- return std::string();
- }
- size *= 2;
- delete[] temp;
- }
- }
-
- return std::string();
-}
-
-
-// TODO(bmahler): Wrap with a Try.
-inline std::list<std::string> ls(const std::string& directory)
-{
- std::list<std::string> result;
-
- DIR* dir = opendir(directory.c_str());
-
- if (dir == NULL) {
- return std::list<std::string>();
- }
-
- // Calculate the size for a "directory entry".
- long name_max = fpathconf(dirfd(dir), _PC_NAME_MAX);
-
- // If we don't get a valid size, check NAME_MAX, but fall back on
- // 255 in the worst case ... Danger, Will Robinson!
- if (name_max == -1) {
- name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
- }
-
- size_t name_end =
- (size_t) offsetof(dirent, d_name) + name_max + 1;
-
- size_t size = (name_end > sizeof(dirent)
- ? name_end
- : sizeof(dirent));
-
- dirent* temp = (dirent*) malloc(size);
-
- if (temp == NULL) {
- free(temp);
- closedir(dir);
- return std::list<std::string>();
- }
-
- struct dirent* entry;
-
- int error;
-
- while ((error = readdir_r(dir, temp, &entry)) == 0 && entry != NULL) {
- if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
- continue;
- }
- result.push_back(entry->d_name);
- }
-
- free(temp);
- closedir(dir);
-
- if (error != 0) {
- return std::list<std::string>();
- }
-
- return result;
-}
-
-
-// Return the list of file paths that match the given pattern by recursively
-// searching the given directory. A match is successful if the pattern is a
-// substring of the file name.
-// NOTE: Directory path should not end with '/'.
-// NOTE: Symbolic links are not followed.
-// TODO(vinod): Support regular expressions for pattern.
-// TODO(vinod): Consider using ftw or a non-recursive approach.
-inline Try<std::list<std::string> > find(
- const std::string& directory,
- const std::string& pattern)
-{
- std::list<std::string> results;
-
- if (!isdir(directory)) {
- return Error("'" + directory + "' is not a directory");
- }
-
- foreach (const std::string& entry, ls(directory)) {
- std::string path = path::join(directory, entry);
- // If it's a directory, recurse.
- if (isdir(path) && !islink(path)) {
- Try<std::list<std::string> > matches = find(path, pattern);
- if (matches.isError()) {
- return matches;
- }
- foreach (const std::string& match, matches.get()) {
- results.push_back(match);
- }
- } else {
- if (entry.find(pattern) != std::string::npos) {
- results.push_back(path); // Matched the file pattern!
- }
- }
- }
-
- return results;
-}
-
-
-inline std::string user()
-{
- passwd* passwd;
- if ((passwd = getpwuid(getuid())) == NULL) {
- LOG(FATAL) << "Failed to get username information";
- }
-
- return passwd->pw_name;
-}
-
-
-inline Try<std::string> hostname()
-{
- char host[512];
-
- if (gethostname(host, sizeof(host)) < 0) {
- return ErrnoError();
- }
-
- // Allocate temporary buffer for gethostbyname2_r.
- size_t length = 1024;
- char* temp = new char[length];
-
- struct hostent he, *hep = NULL;
- int result = 0;
- int herrno = 0;
-
- while ((result = gethostbyname2_r(host, AF_INET, &he, temp,
- length, &hep, &herrno)) == ERANGE) {
- // Enlarge the buffer.
- delete[] temp;
- length *= 2;
- temp = new char[length];
- }
-
- if (result != 0 || hep == NULL) {
- delete[] temp;
- return Error(hstrerror(herrno));
- }
-
- std::string hostname = hep->h_name;
- delete[] temp;
- return Try<std::string>::some(hostname);
-}
-
-
-// Runs a shell command formatted with varargs and return the return value
-// of the command. Optionally, the output is returned via an argument.
-// TODO(vinod): Pass an istream object that can provide input to the command.
-inline Try<int> shell(std::ostream* os, const std::string& fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
-
- const Try<std::string>& cmdline = strings::internal::format(fmt, args);
-
- va_end(args);
-
- if (cmdline.isError()) {
- return Error(cmdline.error());
- }
-
- FILE* file;
-
- if ((file = popen(cmdline.get().c_str(), "r")) == NULL) {
- return Error("Failed to run '" + cmdline.get() + "'");
- }
-
- char line[1024];
- // NOTE(vinod): Ideally the if and while loops should be interchanged. But
- // we get a broken pipe error if we don't read the output and simply close.
- while (fgets(line, sizeof(line), file) != NULL) {
- if (os != NULL) {
- *os << line ;
- }
- }
-
- if (ferror(file) != 0) {
- ErrnoError error("Error reading output of '" + cmdline.get() + "'");
- pclose(file); // Ignoring result since we already have an error.
- return error;
- }
-
- int status;
- if ((status = pclose(file)) == -1) {
- return Error("Failed to get status of '" + cmdline.get() + "'");
- }
-
- return status;
-}
-
-
-// Suspends execution for the given duration.
-inline Try<Nothing> sleep(const Duration& duration)
-{
- timespec remaining;
- remaining.tv_sec = static_cast<long>(duration.secs());
- remaining.tv_nsec =
- static_cast<long>((duration - Seconds(remaining.tv_sec)).ns());
-
- while (nanosleep(&remaining, &remaining) == -1) {
- if (errno == EINTR) {
- continue;
- } else {
- return ErrnoError();
- }
- }
-
- return Nothing();
-}
-
-
-// Creates a tar 'archive' with gzip compression, of the given 'path'.
-inline Try<Nothing> tar(const std::string& path, const std::string& archive)
-{
- Try<int> status =
- shell(NULL, "tar -czf %s %s", archive.c_str(), path.c_str());
-
- if (status.isError()) {
- return Error("Failed to archive " + path + ": " + status.error());
- } else if (status.get() != 0) {
- return Error("Non-zero exit status when archiving " + path +
- ": " + stringify(status.get()));
- }
-
- return Nothing();
-}
-
-
-// Returns the list of files that match the given (shell) pattern.
-inline Try<std::list<std::string> > glob(const std::string& pattern)
-{
- glob_t g;
- int status = ::glob(pattern.c_str(), GLOB_NOSORT, NULL, &g);
-
- std::list<std::string> result;
-
- if (status != 0) {
- if (status == GLOB_NOMATCH) {
- return result; // Empty list.
- } else {
- return ErrnoError();
- }
- }
-
- for (size_t i = 0; i < g.gl_pathc; ++i) {
- result.push_back(g.gl_pathv[i]);
- }
-
- globfree(&g); // Best-effort free of dynamically allocated memory.
-
- return result;
-}
-
-
-// Returns the total number of cpus (cores).
-inline Try<long> cpus()
-{
- long cpus = sysconf(_SC_NPROCESSORS_ONLN);
-
- if (cpus < 0) {
- return ErrnoError();
- }
- return cpus;
-}
-
-
-// Returns the total size of main memory.
-inline Try<Bytes> memory()
-{
-#ifdef __linux__
- struct sysinfo info;
- if (sysinfo(&info) != 0) {
- return ErrnoError();
- }
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 23)
- return Bytes(info.totalram * info.mem_unit);
-# else
- return Bytes(info.totalram);
-# endif
-#elif defined __APPLE__
- const size_t NAME_SIZE = 2;
- int name[NAME_SIZE];
- name[0] = CTL_HW;
- name[1] = HW_MEMSIZE;
-
- int64_t memory;
- size_t length = sizeof(memory);
-
- if (sysctl(name, NAME_SIZE, &memory, &length, NULL, 0) < 0) {
- return ErrnoError("Failed to get sysctl of HW_MEMSIZE");
- }
- return Bytes(memory);
-#else
- return Error("Cannot determine the size of main memory");
-#endif
-}
-
-
-// The structure returned by uname describing the currently running system.
-struct UTSInfo
-{
- std::string sysname; // Operating system name (e.g. Linux).
- std::string nodename; // Network name of this machine.
- std::string release; // Release level of the operating system.
- std::string version; // Version level of the operating system.
- std::string machine; // Machine hardware platform.
-};
-
-
-// Return the system information.
-inline Try<UTSInfo> uname()
-{
- struct utsname name;
-
- if (::uname(&name) < 0) {
- return ErrnoError();
- }
-
- UTSInfo info;
- info.sysname = name.sysname;
- info.nodename = name.nodename;
- info.release = name.release;
- info.version = name.version;
- info.machine = name.machine;
- return info;
-}
-
-
-// Return the operating system name (e.g. Linux).
-inline Try<std::string> sysname()
-{
- Try<UTSInfo> info = uname();
- if (info.isError()) {
- return Error(info.error());
- }
-
- return info.get().sysname;
-}
-
-
-// The OS release level.
-struct Release
-{
- int version;
- int major;
- int minor;
-};
-
-
-// Return the OS release numbers.
-inline Try<Release> release()
-{
- Try<UTSInfo> info = uname();
- if (info.isError()) {
- return Error(info.error());
- }
-
- Release r;
- if (::sscanf(
- info.get().release.c_str(),
- "%d.%d.%d",
- &r.version,
- &r.major,
- &r.minor) != 3) {
- return Error("Failed to parse: " + info.get().release);
- }
-
- return r;
-}
-
-
-inline Try<bool> alive(pid_t pid)
-{
- CHECK(pid > 0);
-
- if (::kill(pid, 0) == 0) {
- return true;
- }
-
- if (errno == ESRCH) {
- return false;
- }
-
- return Try<bool>::error(strerror(errno));
-}
-
-} // namespace os {
-
-#endif // __STOUT_OS_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/owned.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/owned.hpp b/third_party/libprocess/third_party/stout/include/stout/owned.hpp
deleted file mode 100644
index 3433f50..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/owned.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __STOUT_OWNED_HPP__
-#define __STOUT_OWNED_HPP__
-
-#include <boost/shared_ptr.hpp>
-
-// Represents a uniquely owned pointer.
-//
-// TODO(bmahler): For now, Owned only provides shared_ptr semantics.
-// When we make the switch to C++11, we will change to provide
-// unique_ptr semantics. Consequently, each usage of Owned that
-// invoked a copy will have to be adjusted to use move semantics.
-template <typename T>
-class Owned : public boost::shared_ptr<T>
-{
-public:
- Owned(T* t) : boost::shared_ptr<T>(t) {}
-};
-
-
-#endif // __STOUT_OWNED_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/path.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/path.hpp b/third_party/libprocess/third_party/stout/include/stout/path.hpp
deleted file mode 100644
index fda4e04..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/path.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef __STOUT_PATH_HPP__
-#define __STOUT_PATH_HPP__
-
-#include <string>
-#include <vector>
-
-#include "strings.hpp"
-
-namespace path {
-
-inline std::string join(const std::string& path1, const std::string& path2)
-{
- return
- strings::remove(path1, "/", strings::SUFFIX) + "/" +
- strings::remove(path2, "/", strings::PREFIX);
-}
-
-
-inline std::string join(
- const std::string& path1,
- const std::string& path2,
- const std::string& path3)
-{
- return join(path1, join(path2, path3));
-}
-
-
-inline std::string join(
- const std::string& path1,
- const std::string& path2,
- const std::string& path3,
- const std::string& path4)
-{
- return join(path1, join(path2, path3, path4));
-}
-
-
-inline std::string join(
- const std::string& path1,
- const std::string& path2,
- const std::string& path3,
- const std::string& path4,
- const std::string& path5)
-{
- return join(path1, join(path2, join(path3, join(path4, path5))));
-}
-
-
-inline std::string join(
- const std::string& path1,
- const std::string& path2,
- const std::string& path3,
- const std::string& path4,
- const std::string& path5,
- const std::string& path6)
-{
- return join(path1, join(path2, path3, path4, path5, path6));
-}
-
-
-inline std::string join(const std::vector<std::string>& paths)
-{
- if (paths.empty()) {
- return "";
- }
-
- std::string result = paths[0];
- for (size_t i = 1; i < paths.size(); ++i) {
- result = join(result, paths[i]);
- }
- return result;
-}
-
-} // namespace path {
-
-#endif // __STOUT_PATH_HPP__
http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/bc531d3c/third_party/libprocess/third_party/stout/include/stout/preprocessor.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/third_party/stout/include/stout/preprocessor.hpp b/third_party/libprocess/third_party/stout/include/stout/preprocessor.hpp
deleted file mode 100644
index 466e16f..0000000
--- a/third_party/libprocess/third_party/stout/include/stout/preprocessor.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __PROCESS_PREPROCESSOR_HPP__
-#define __PROCESS_PREPROCESSOR_HPP__
-
-#include <boost/preprocessor/cat.hpp>
-
-#include <boost/preprocessor/arithmetic/inc.hpp>
-
-#include <boost/preprocessor/facilities/intercept.hpp>
-
-#include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
-#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
-#include <boost/preprocessor/repetition/repeat.hpp>
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>
-
-// Provides aliases to a bunch of preprocessor macros useful for
-// creating template definitions that have varying number of
-// parameters (should be removable with C++-11 variadic templates).
-
-#define CAT BOOST_PP_CAT
-#define INC BOOST_PP_INC
-#define INTERCEPT BOOST_PP_INTERCEPT
-#define ENUM_PARAMS BOOST_PP_ENUM_PARAMS
-#define ENUM_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS
-#define ENUM_TRAILING_PARAMS BOOST_PP_ENUM_TRAILING_PARAMS
-#define REPEAT BOOST_PP_REPEAT
-#define REPEAT_FROM_TO BOOST_PP_REPEAT_FROM_TO
-
-#endif // __PROCESS_PREPROCESSOR_HPP__