This is an automated email from the ASF dual-hosted git repository. bbannier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mesos.git
commit f1789b0fe5cad221b79a0bc2adfe2036cce6f33d Author: Benjamin Bannier <bbann...@apache.org> AuthorDate: Wed Sep 25 23:01:24 2019 +0200 Introduced automatic lifecycle management in `DynamicLibrary`. This not only simplifies our implementation of `DynamicLibrary`, but also removes the potential for accidental file descriptor leaks. Review: https://reviews.apache.org/r/71388/ --- .../stout/include/stout/posix/dynamiclibrary.hpp | 35 ++++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/3rdparty/stout/include/stout/posix/dynamiclibrary.hpp b/3rdparty/stout/include/stout/posix/dynamiclibrary.hpp index 6a50592..2e2726e 100644 --- a/3rdparty/stout/include/stout/posix/dynamiclibrary.hpp +++ b/3rdparty/stout/include/stout/posix/dynamiclibrary.hpp @@ -15,6 +15,7 @@ #include <dlfcn.h> +#include <memory> #include <string> #include <stout/nothing.hpp> @@ -28,20 +29,17 @@ class DynamicLibrary { public: - DynamicLibrary() : handle_(nullptr) { } + DynamicLibrary() + : handle_(nullptr, [](void* handle) { + if (handle == nullptr) { + return 0; + } - // Since this class manages a naked handle it cannot be copy- or - // move-constructed. - // TODO(bbannier): Allow for move-construction. - DynamicLibrary(const DynamicLibrary&) = delete; - DynamicLibrary(DynamicLibrary&&) = delete; + return dlclose(handle); + }) + {} - virtual ~DynamicLibrary() - { - if (handle_ != nullptr) { - close(); - } - } + virtual ~DynamicLibrary() = default; Try<Nothing> open(const std::string& path) { @@ -50,7 +48,7 @@ public: return Error("Library already opened"); } - handle_ = dlopen(path.c_str(), RTLD_NOW); + handle_.reset(dlopen(path.c_str(), RTLD_NOW)); if (handle_ == nullptr) { return Error("Could not load library '" + path + "': " + dlerror()); @@ -67,12 +65,17 @@ public: return Error("Could not close library; handle was already `nullptr`"); } - if (dlclose(handle_) != 0) { + if (dlclose(handle_.get()) != 0) { return Error( "Could not close library '" + (path_.isSome() ? path_.get() : "") + "': " + dlerror()); } + // Release the handle so the default `dlclose` operation is not + // invoked anymore as after successful explicit `dlclose` it does + // not point to an open shared object anymore. + handle_.release(); + handle_ = nullptr; path_ = None(); @@ -86,7 +89,7 @@ public: "Could not get symbol '" + name + "'; library handle was `nullptr`"); } - void* symbol = dlsym(handle_, name.c_str()); + void* symbol = dlsym(handle_.get(), name.c_str()); if (symbol == nullptr) { return Error( @@ -98,7 +101,7 @@ public: } private: - void* handle_; + std::unique_ptr<void, int (*)(void*)> handle_; Option<std::string> path_; };