Repository: mesos
Updated Branches:
  refs/heads/master 6987a9e05 -> 4f97402d7


Allowed waiting for a link to be removed.

Review: https://reviews.apache.org/r/21141


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4f97402d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4f97402d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4f97402d

Branch: refs/heads/master
Commit: 4f97402d70f0f0936396cf5443ce545cf8e1c958
Parents: 19f643a
Author: Jie Yu <yujie....@gmail.com>
Authored: Tue May 6 17:14:25 2014 -0700
Committer: Jie Yu <yujie....@gmail.com>
Committed: Wed May 14 17:38:43 2014 -0700

----------------------------------------------------------------------
 src/linux/routing/link/link.cpp | 70 ++++++++++++++++++++++++++++++++++++
 src/linux/routing/link/link.hpp |  9 +++++
 src/tests/routing_tests.cpp     | 22 ++++++++++++
 3 files changed, 101 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/4f97402d/src/linux/routing/link/link.cpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/link/link.cpp b/src/linux/routing/link/link.cpp
index 62996bd..039e308 100644
--- a/src/linux/routing/link/link.cpp
+++ b/src/linux/routing/link/link.cpp
@@ -32,7 +32,13 @@
 
 #include <netlink/route/link/veth.h>
 
+#include <process/delay.hpp>
+#include <process/pid.hpp>
+#include <process/process.hpp>
+
 #include <stout/error.hpp>
+#include <stout/duration.hpp>
+#include <stout/lambda.hpp>
 #include <stout/none.hpp>
 #include <stout/os.hpp>
 
@@ -41,6 +47,8 @@
 #include "linux/routing/link/internal.hpp"
 #include "linux/routing/link/link.hpp"
 
+using namespace process;
+
 using std::string;
 
 namespace routing {
@@ -109,6 +117,68 @@ Try<bool> remove(const string& _link)
 }
 
 
+namespace internal {
+
+// A process that checks if a link has been removed.
+class ExistenceChecker : public Process<ExistenceChecker>
+{
+public:
+  ExistenceChecker(const string& _link) : link(_link) {}
+
+  virtual ~ExistenceChecker() {}
+
+  // Returns a future which gets set when the link has been removed.
+  Future<Nothing> future() { return promise.future(); }
+
+protected:
+  virtual void initialize()
+  {
+    // Stop when no one cares.
+    promise.future().onDiscard(lambda::bind(
+        static_cast<void (*)(const UPID&, bool)>(terminate), self(), true));
+
+    check();
+  }
+
+  virtual void finalize()
+  {
+    promise.discard();
+  }
+
+private:
+  void check()
+  {
+    Try<bool> exists = link::exists(link);
+    if (exists.isError()) {
+      promise.fail(exists.error());
+      terminate(self());
+      return;
+    } else if (!exists.get()) {
+      promise.set(Nothing());
+      terminate(self());
+      return;
+    }
+
+    // Perform the check again.
+    delay(Milliseconds(100), self(), &Self::check);
+  }
+
+  const string link;
+  Promise<Nothing> promise;
+};
+
+} // namespace internal {
+
+
+Future<Nothing> removed(const string& link)
+{
+  internal::ExistenceChecker* checker = new internal::ExistenceChecker(link);
+  Future<Nothing> future = checker->future();
+  spawn(checker, true);
+  return future;
+}
+
+
 Result<int> index(const string& _link)
 {
   Result<Netlink<struct rtnl_link> > link = internal::get(_link);

http://git-wip-us.apache.org/repos/asf/mesos/blob/4f97402d/src/linux/routing/link/link.hpp
----------------------------------------------------------------------
diff --git a/src/linux/routing/link/link.hpp b/src/linux/routing/link/link.hpp
index ef982e3..4264a1e 100644
--- a/src/linux/routing/link/link.hpp
+++ b/src/linux/routing/link/link.hpp
@@ -25,8 +25,11 @@
 
 #include <string>
 
+#include <process/future.hpp>
+
 #include <stout/hashmap.hpp>
 #include <stout/net.hpp>
+#include <stout/nothing.hpp>
 #include <stout/option.hpp>
 #include <stout/result.hpp>
 #include <stout/try.hpp>
@@ -53,6 +56,12 @@ Try<bool> create(
 Try<bool> remove(const std::string& link);
 
 
+// Waits for the link to be removed. The returned future will be set
+// once the link has been removed. The user can discard the returned
+// future to cancel the operation.
+process::Future<Nothing> removed(const std::string& link);
+
+
 // Returns the interface index of the link. Returns None if the link
 // is not found.
 Result<int> index(const std::string& link);

http://git-wip-us.apache.org/repos/asf/mesos/blob/4f97402d/src/tests/routing_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/routing_tests.cpp b/src/tests/routing_tests.cpp
index aca88dc..1658f9a 100644
--- a/src/tests/routing_tests.cpp
+++ b/src/tests/routing_tests.cpp
@@ -26,6 +26,9 @@
 
 #include <gtest/gtest.h>
 
+#include <process/clock.hpp>
+#include <process/gtest.hpp>
+
 #include <stout/foreach.hpp>
 #include <stout/gtest.hpp>
 #include <stout/hashmap.hpp>
@@ -43,6 +46,8 @@
 #include "linux/routing/queueing/handle.hpp"
 #include "linux/routing/queueing/ingress.hpp"
 
+using namespace process;
+
 using namespace routing;
 using namespace routing::filter;
 using namespace routing::queueing;
@@ -270,6 +275,23 @@ TEST_F(RoutingVethTest, ROOT_LinkCreatePid)
 #endif
 
 
+TEST_F(RoutingVethTest, ROOT_LinkWait)
+{
+  AWAIT_READY(link::removed(TEST_VETH_LINK));
+
+  ASSERT_SOME(link::create(TEST_VETH_LINK, TEST_PEER_LINK, None()));
+
+  EXPECT_SOME_TRUE(link::exists(TEST_VETH_LINK));
+  EXPECT_SOME_TRUE(link::exists(TEST_PEER_LINK));
+
+  Future<Nothing> removed = link::removed(TEST_VETH_LINK);
+  EXPECT_TRUE(removed.isPending());
+
+  ASSERT_SOME_TRUE(link::remove(TEST_VETH_LINK));
+  AWAIT_READY(removed);
+}
+
+
 TEST_F(RoutingVethTest, ROOT_LinkSetUp)
 {
   ASSERT_SOME(link::create(TEST_VETH_LINK, TEST_PEER_LINK, None()));

Reply via email to