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());
}