summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2019-04-23 17:37:26 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2019-04-25 16:03:08 (GMT)
commit8cfd25db711c22f9478e565a496145577df24d77 (patch)
tree4903ef06ec74137f44c375bbdd23fbbce9a99676 /Source
parentc0e6b22d0a81c0e0dc1ee87366790882a3d54667 (diff)
downloadCMake-8cfd25db711c22f9478e565a496145577df24d77.zip
CMake-8cfd25db711c22f9478e565a496145577df24d77.tar.gz
CMake-8cfd25db711c22f9478e565a496145577df24d77.tar.bz2
cmUVHandlePtr: Add cm::uv_loop_ptr
Diffstat (limited to 'Source')
-rw-r--r--Source/cmUVHandlePtr.cxx54
-rw-r--r--Source/cmUVHandlePtr.h40
2 files changed, 86 insertions, 8 deletions
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index fd07d2d..27069ee 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -11,19 +11,59 @@
namespace cm {
-static void close_delete(uv_handle_t* h)
+struct uv_loop_deleter
{
- free(h);
+ void operator()(uv_loop_t* loop) const;
+};
+
+void uv_loop_deleter::operator()(uv_loop_t* loop) const
+{
+ uv_run(loop, UV_RUN_DEFAULT);
+ int result = uv_loop_close(loop);
+ (void)result;
+ assert(result >= 0);
+ free(loop);
+}
+
+int uv_loop_ptr::init(void* data)
+{
+ this->reset();
+
+ this->loop.reset(static_cast<uv_loop_t*>(calloc(1, sizeof(uv_loop_t))),
+ uv_loop_deleter());
+ this->loop->data = data;
+
+ return uv_loop_init(this->loop.get());
+}
+
+void uv_loop_ptr::reset()
+{
+ this->loop.reset();
+}
+
+uv_loop_ptr::operator uv_loop_t*()
+{
+ return this->loop.get();
+}
+
+uv_loop_t* uv_loop_ptr::operator->() const noexcept
+{
+ return this->loop.get();
+}
+
+uv_loop_t* uv_loop_ptr::get() const
+{
+ return this->loop.get();
}
template <typename T>
-static void default_delete(T* type_handle)
+static void handle_default_delete(T* type_handle)
{
auto handle = reinterpret_cast<uv_handle_t*>(type_handle);
if (handle) {
assert(!uv_is_closing(handle));
if (!uv_is_closing(handle)) {
- uv_close(handle, &close_delete);
+ uv_close(handle, [](uv_handle_t* h) { free(h); });
}
}
}
@@ -34,7 +74,7 @@ static void default_delete(T* type_handle)
template <typename T>
struct uv_handle_deleter
{
- void operator()(T* type_handle) const { default_delete(type_handle); }
+ void operator()(T* type_handle) const { handle_default_delete(type_handle); }
};
template <typename T>
@@ -107,7 +147,7 @@ struct uv_handle_deleter<uv_async_t>
void operator()(uv_async_t* handle)
{
std::lock_guard<std::mutex> lock(*handleMutex);
- default_delete(handle);
+ handle_default_delete(handle);
}
};
@@ -136,7 +176,7 @@ struct uv_handle_deleter<uv_signal_t>
{
if (handle) {
uv_signal_stop(handle);
- default_delete(handle);
+ handle_default_delete(handle);
}
}
};
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h
index 992c429..c09e4bf 100644
--- a/Source/cmUVHandlePtr.h
+++ b/Source/cmUVHandlePtr.h
@@ -30,7 +30,45 @@
namespace cm {
/***
- * RAII class to simplify and insure the safe usage of uv_*_t types. This
+ * RAII class to simplify and ensure the safe usage of uv_loop_t. This includes
+ * making sure resources are properly freed.
+ */
+class uv_loop_ptr
+{
+protected:
+ std::shared_ptr<uv_loop_t> loop;
+
+public:
+ uv_loop_ptr(uv_loop_ptr const&) = delete;
+ uv_loop_ptr& operator=(uv_loop_ptr const&) = delete;
+ uv_loop_ptr(uv_loop_ptr&&) noexcept;
+ uv_loop_ptr& operator=(uv_loop_ptr&&) noexcept;
+
+ // Dtor and ctor need to be inline defined like this for default ctors and
+ // dtors to work. Some compilers do not like '= default' here.
+ uv_loop_ptr() {} // NOLINT(modernize-use-equals-default)
+ uv_loop_ptr(std::nullptr_t) {}
+ ~uv_loop_ptr() { this->reset(); }
+
+ int init(void* data = nullptr);
+
+ /**
+ * Properly close the handle if needed and sets the inner handle to nullptr
+ */
+ void reset();
+
+ /**
+ * Allow less verbose calling of uv_loop_* functions
+ * @return reinterpreted handle
+ */
+ operator uv_loop_t*();
+
+ uv_loop_t* get() const;
+ uv_loop_t* operator->() const noexcept;
+};
+
+/***
+ * RAII class to simplify and ensure the safe usage of uv_*_t types. This
* includes making sure resources are properly freed and contains casting
* operators which allow for passing into relevant uv_* functions.
*