You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mp...@apache.org on 2016/02/26 01:39:22 UTC

[1/2] mesos git commit: Windows: Added support for dynamic library loading.

Repository: mesos
Updated Branches:
  refs/heads/master 61ff6848a -> 61b17a90d


Windows: Added support for dynamic library loading.

Originally r40583. Only minor changes were made.

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


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

Branch: refs/heads/master
Commit: 93cef0d0f855b06d7398a8c7fe579d2eb56e3ce6
Parents: 61ff684
Author: Alex Clemmer <cl...@gmail.com>
Authored: Thu Feb 25 16:23:58 2016 -0800
Committer: Michael Park <mp...@apache.org>
Committed: Thu Feb 25 16:25:17 2016 -0800

----------------------------------------------------------------------
 .../stout/include/stout/dynamiclibrary.hpp      | 82 ++--------------
 .../include/stout/posix/dynamiclibrary.hpp      | 99 ++++++++++++++++++++
 .../include/stout/windows/dynamiclibrary.hpp    | 98 +++++++++++++++++++
 3 files changed, 204 insertions(+), 75 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/93cef0d0/3rdparty/libprocess/3rdparty/stout/include/stout/dynamiclibrary.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/dynamiclibrary.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/dynamiclibrary.hpp
index 166c97d..e5b2d00 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/dynamiclibrary.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/dynamiclibrary.hpp
@@ -13,80 +13,12 @@
 #ifndef __STOUT_DYNAMICLIBRARY_HPP__
 #define __STOUT_DYNAMICLIBRARY_HPP__
 
-#include <dlfcn.h>
-
-#include <string>
-
-#include <stout/nothing.hpp>
-#include <stout/option.hpp>
-#include <stout/try.hpp>
-
-/**
- * DynamicLibrary is a very simple wrapper around the programming interface
- * to the dynamic linking loader.
- */
-class DynamicLibrary
-{
-public:
-  DynamicLibrary() : handle_(NULL) { }
-
-  virtual ~DynamicLibrary()
-  {
-    if (handle_ != NULL) {
-      close();
-    }
-  }
-
-  Try<Nothing> open(const std::string& path)
-  {
-    // Check if we've already opened a library.
-    if (handle_ != NULL) {
-      return Error("Library already opened");
-    }
-
-    handle_ = dlopen(path.c_str(), RTLD_NOW);
-
-    if (handle_ == NULL) {
-      return Error(
-          "Could not load library '" + path +
-          "': " + dlerror());
-    }
-
-    path_ = path;
-
-    return Nothing();
-  }
-
-  Try<Nothing> close()
-  {
-    if (dlclose(handle_) != 0) {
-      return Error(
-          "Could not close library '" +
-          (path_.isSome() ? path_.get() : "") + "': " + dlerror());
-    }
-
-    handle_ = NULL;
-    path_ = None();
-
-    return Nothing();
-  }
-
-  Try<void*> loadSymbol(const std::string& name)
-  {
-    void* symbol = dlsym(handle_, name.c_str());
-
-    if (symbol == NULL) {
-      return Error(
-          "Error looking up symbol '" + name + "' in '" +
-          (path_.isSome() ? path_.get() : "") + "' : " + dlerror());
-    }
-
-    return symbol;
-  }
-
-private:
-  void* handle_;
-  Option<std::string> path_;
-};
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/windows/dynamiclibrary.hpp>
+#else
+#include <stout/posix/dynamiclibrary.hpp>
+#endif // __WINDOWS__
 
 #endif // __STOUT_DYNAMICLIBRARY_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/93cef0d0/3rdparty/libprocess/3rdparty/stout/include/stout/posix/dynamiclibrary.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/posix/dynamiclibrary.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/dynamiclibrary.hpp
new file mode 100644
index 0000000..427ff8a
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/posix/dynamiclibrary.hpp
@@ -0,0 +1,99 @@
+// Licensed 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 __STOUT_POSIX_DYNAMICLIBRARY_HPP__
+#define __STOUT_POSIX_DYNAMICLIBRARY_HPP__
+
+#include <dlfcn.h>
+
+#include <string>
+
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+/**
+ * DynamicLibrary is a very simple wrapper around the programming interface
+ * to the dynamic linking loader.
+ */
+class DynamicLibrary
+{
+public:
+  DynamicLibrary() : handle_(NULL) { }
+
+  virtual ~DynamicLibrary()
+  {
+    if (handle_ != NULL) {
+      close();
+    }
+  }
+
+  Try<Nothing> open(const std::string& path)
+  {
+    // Check if we've already opened a library.
+    if (handle_ != NULL) {
+      return Error("Library already opened");
+    }
+
+    handle_ = dlopen(path.c_str(), RTLD_NOW);
+
+    if (handle_ == NULL) {
+      return Error("Could not load library '" + path + "': " + dlerror());
+    }
+
+    path_ = path;
+
+    return Nothing();
+  }
+
+  Try<Nothing> close()
+  {
+    if (handle_ == NULL) {
+      return Error("Could not close library; handle was already `NULL`");
+    }
+
+    if (dlclose(handle_) != 0) {
+      return Error(
+          "Could not close library '" +
+          (path_.isSome() ? path_.get() : "") + "': " + dlerror());
+    }
+
+    handle_ = NULL;
+    path_ = None();
+
+    return Nothing();
+  }
+
+  Try<void*> loadSymbol(const std::string& name)
+  {
+    if (handle_ == NULL) {
+      return Error(
+          "Could not get symbol '" + name + "'; library handle was `NULL`");
+    }
+
+    void* symbol = dlsym(handle_, name.c_str());
+
+    if (symbol == NULL) {
+      return Error(
+          "Error looking up symbol '" + name + "' in '" +
+          (path_.isSome() ? path_.get() : "") + "' : " + dlerror());
+    }
+
+    return symbol;
+  }
+
+private:
+  void* handle_;
+  Option<std::string> path_;
+};
+
+#endif // __STOUT_POSIX_DYNAMICLIBRARY_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/93cef0d0/3rdparty/libprocess/3rdparty/stout/include/stout/windows/dynamiclibrary.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/windows/dynamiclibrary.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/dynamiclibrary.hpp
new file mode 100644
index 0000000..4235cb1
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/windows/dynamiclibrary.hpp
@@ -0,0 +1,98 @@
+// Licensed 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 __STOUT_WINDOWS_DYNAMICLIBRARY_HPP__
+#define __STOUT_WINDOWS_DYNAMICLIBRARY_HPP__
+
+#include <string>
+
+#include <stout/nothing.hpp>
+#include <stout/option.hpp>
+#include <stout/try.hpp>
+
+#include <stout/windows/error.hpp>
+
+/**
+ * DynamicLibrary is a very simple wrapper around the programming interface
+ * to the dynamic linking loader.
+ */
+class DynamicLibrary
+{
+public:
+  DynamicLibrary() : handle_(NULL) { }
+
+  virtual ~DynamicLibrary()
+  {
+    if (handle_ != NULL) {
+      close();
+    }
+  }
+
+  Try<Nothing> open(const std::string& path)
+  {
+    // Check if we've already opened a library.
+    if (handle_ != NULL) {
+      return Error("Library already opened");
+    }
+
+    handle_ = LoadLibrary(path.c_str());
+
+    if (handle_ == NULL) {
+      return WindowsError("Could not load library '" + path + "'");
+    }
+
+    path_ = path;
+
+    return Nothing();
+  }
+
+  Try<Nothing> close()
+  {
+    if (handle_ == NULL) {
+      return Error("Could not close library; handle was already `NULL`");
+    }
+
+    if (!FreeLibrary(handle_)) {
+      return WindowsError(
+          "Could not close library '" + (path_.isSome() ? path_.get() : ""));
+    }
+
+    handle_ = NULL;
+    path_ = None();
+
+    return Nothing();
+  }
+
+  Try<void*> loadSymbol(const std::string& name)
+  {
+    if (handle_ == NULL) {
+      return Error(
+          "Could not get symbol '" + name + "'; library handle was `NULL`");
+    }
+
+    void* symbol = GetProcAddress(handle_, name.c_str());
+
+    if (symbol == NULL) {
+      return WindowsError(
+          "Error looking up symbol '" + name + "' in '" +
+          (path_.isSome() ? path_.get() : ""));
+    }
+
+    return symbol;
+  }
+
+private:
+  HMODULE handle_;
+  Option<std::string> path_;
+};
+
+#endif // __STOUT_WINDOWS_DYNAMICLIBRARY_HPP__


[2/2] mesos git commit: Windows: Added dynamic library loading tests to build.

Posted by mp...@apache.org.
Windows: Added dynamic library loading tests to build.

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


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

Branch: refs/heads/master
Commit: 61b17a90d3cbd8deda943d7de4b2ae3b83f6d353
Parents: 93cef0d
Author: Alex Clemmer <cl...@gmail.com>
Authored: Thu Feb 25 16:25:40 2016 -0800
Committer: Michael Park <mp...@apache.org>
Committed: Thu Feb 25 16:29:40 2016 -0800

----------------------------------------------------------------------
 .../3rdparty/stout/tests/CMakeLists.txt         |   2 +-
 .../stout/tests/dynamiclibrary_tests.cpp        | 153 +++++++++++++++++--
 2 files changed, 142 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/61b17a90/3rdparty/libprocess/3rdparty/stout/tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/CMakeLists.txt b/3rdparty/libprocess/3rdparty/stout/tests/CMakeLists.txt
index 3c65d04..6f9d46c 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/CMakeLists.txt
+++ b/3rdparty/libprocess/3rdparty/stout/tests/CMakeLists.txt
@@ -23,6 +23,7 @@ set(STOUT_TESTS_SRC
   bytes_tests.cpp
   cache_tests.cpp
   duration_tests.cpp
+  dynamiclibrary_tests.cpp
   error_tests.cpp
   hashmap_tests.cpp
   hashset_tests.cpp
@@ -50,7 +51,6 @@ set(STOUT_TESTS_SRC
 if (NOT WIN32)
   set(STOUT_TESTS_SRC
     ${STOUT_TESTS_SRC}
-    dynamiclibrary_tests.cpp
     flags_tests.cpp
     gzip_tests.cpp
     mac_tests.cpp

http://git-wip-us.apache.org/repos/asf/mesos/blob/61b17a90/3rdparty/libprocess/3rdparty/stout/tests/dynamiclibrary_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/dynamiclibrary_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/dynamiclibrary_tests.cpp
index 27626ae..ac7352c 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/dynamiclibrary_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/dynamiclibrary_tests.cpp
@@ -16,25 +16,154 @@
 #include <stout/gtest.hpp>
 #include <stout/some.hpp>
 
-// Test that we can dynamically load the library, that loads libraries.
-TEST(DynamicLibraryTest, LoadKnownSymbol)
-{
-  DynamicLibrary dltest;
+using std::string;
 
 #ifdef __linux__
-  Try<Nothing> result = dltest.open("libdl.so");
+static const string valid_library_path = "libdl.so";
 #elif defined(__FreeBSD__)
-  Try<Nothing> result = dltest.open("libc.so.7");
+static const string valid_library_path = "libc.so.7";
+#elif defined(__WINDOWS__)
+static const string valid_library_path = "ntdll.dll";
+#else
+static const string valid_library_path = "libdl.dylib";
+#endif
+
+#ifdef __WINDOWS__
+static const string valid_symbol = "NtOpenProcess";
 #else
-  Try<Nothing> result = dltest.open("libdl.dylib");
+static const string valid_symbol = "dlopen";
 #endif
 
-  EXPECT_SOME(result);
+static const string invalid_symbol = "InvalidSymbol";
+static const string invalid_library_path = "InvalidLibraryPath";
+
+
+// Successful `open`, load symbol, `close`.
+TEST(DynamicLibraryTest, LoadKnownSymbol)
+{
+  DynamicLibrary dltest;
+
+  EXPECT_SOME(dltest.open(valid_library_path));
+  EXPECT_SOME(dltest.loadSymbol(valid_symbol));
+  EXPECT_SOME(dltest.close());
+}
+
+
+// Successful `open`, fail to load nonsense symbol, `close`.
+TEST(DynamicLibraryTest, FailToLoadInvalidSymbol)
+{
+  DynamicLibrary dltest;
+
+  EXPECT_SOME(dltest.open(valid_library_path));
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
+  EXPECT_SOME(dltest.close());
+}
+
+
+// Verify that `loadSymbol` and `close` fail if we don't call `open` first.
+TEST(DynamicLibraryTest, CloseAndLoadSymbolFailWithoutOpeningLib)
+{
+  DynamicLibrary dltest;
+
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
+  EXPECT_ERROR(dltest.close());
+}
+
+
+// Verify we can open a library and load a symbol. Then close, verify that we
+// can't load the symbol. Then open and verify we can load symbol again, just
+// to be safe.
+TEST(DynamicLibraryTest, VerifyClose)
+{
+  DynamicLibrary dltest;
+
+  EXPECT_SOME(dltest.open(valid_library_path));
+  EXPECT_SOME(dltest.loadSymbol(valid_symbol));
+  EXPECT_SOME(dltest.close());
+
+  EXPECT_ERROR(dltest.loadSymbol(valid_symbol));
+
+  EXPECT_SOME(dltest.open(valid_library_path));
+  EXPECT_SOME(dltest.loadSymbol(valid_symbol));
+  EXPECT_SOME(dltest.close());
+}
+
+
+// Attempt to load invalid lib path, verify failure, as well as failures when
+// we try to call `loadSymbol` and `close`.
+TEST(DynamicLibraryTest, FailToLoadInvalidLibPath)
+{
+  DynamicLibrary dltest;
+
+  EXPECT_ERROR(dltest.open(invalid_library_path));
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
+  EXPECT_ERROR(dltest.close());
+}
+
+
+// Attempt to `open` invalid lib path _twice_, verify failure, then verify
+// failure when we call `loadSymbol` and `close`.
+TEST(DynamicLibraryTest, DoubleFailOpen)
+{
+  DynamicLibrary dltest;
+
+  EXPECT_ERROR(dltest.open(invalid_library_path));
+  EXPECT_ERROR(dltest.open(invalid_library_path));
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
+  EXPECT_ERROR(dltest.close());
+}
+
+
+// `open` valid library, load symbol, then verify we fail when we try to open
+// the library again; verify we can still load symbols from, and `close`, the
+// original library.
+TEST(DynamicLibraryTest, OpenSuccessThenOpenFail)
+{
+  DynamicLibrary dltest;
+
+  // `open`, successfully load symbol.
+  EXPECT_SOME(dltest.open(valid_library_path));
+  EXPECT_SOME(dltest.loadSymbol(valid_symbol));
+
+  // `open` same path again, fail, but successfully load known symbol; fail to
+  // load nonsense symbol.
+  EXPECT_ERROR(dltest.open(valid_library_path));
+  EXPECT_SOME(dltest.loadSymbol(valid_symbol));
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
+
+  // `open` different (invalid) path, fail, but successfully load known symbol;
+  // fail to load nonsense symbol.
+  EXPECT_ERROR(dltest.open(invalid_library_path));
+  EXPECT_SOME(dltest.loadSymbol(valid_symbol));
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
+
+  // Finally, successfully `close`.
+  EXPECT_SOME(dltest.close());
+}
+
+
+// Attempt to `open` invalid lib, verify we can't load symbols from it, then
+// open valid lib, and verify we can load symbols from, and `close` it.
+TEST(DynamicLibraryTest, OpenFailThenOpenSuccess)
+{
+  DynamicLibrary dltest;
+
+  // Fail to `open`, then fail load nonsense symbols.
+  EXPECT_ERROR(dltest.open(invalid_library_path));
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
 
-  Try<void*> symbol = dltest.loadSymbol("dlopen");
+  // `open` valid path, succeed, then successfully load known symbol; fail to
+  // load nonsense symbol.
+  EXPECT_SOME(dltest.open(valid_library_path));
+  EXPECT_SOME(dltest.loadSymbol(valid_symbol));
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
 
-  EXPECT_SOME(symbol);
+  // `open` different (invalid) path, fail, but successfully load known symbol;
+  // fail to load nonsense symbol.
+  EXPECT_ERROR(dltest.open(invalid_library_path));
+  EXPECT_SOME(dltest.loadSymbol(valid_symbol));
+  EXPECT_ERROR(dltest.loadSymbol(invalid_symbol));
 
-  result = dltest.close();
-  EXPECT_SOME(result);
+  // Finally, successfully `close`.
+  EXPECT_SOME(dltest.close());
 }