You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bb...@apache.org on 2019/09/30 12:52:34 UTC
[mesos] 03/03: Introduced automatic lifecycle management in
`DynamicLibrary`.
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 <bb...@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_;
};