diff --git a/src/uvw.hpp b/src/uvw.hpp index 8870260f..52900628 100644 --- a/src/uvw.hpp +++ b/src/uvw.hpp @@ -7,6 +7,7 @@ #include "uvw/loop.hpp" #include "uvw/prepare.hpp" #include "uvw/request.hpp" +#include "uvw/self.hpp" #include "uvw/signal.hpp" #include "uvw/stream.hpp" #include "uvw/tcp.hpp" diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 7d5c6925..f3fcb6c7 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -5,6 +5,7 @@ #include #include #include "emitter.hpp" +#include "self.hpp" #include "loop.hpp" @@ -25,11 +26,7 @@ template<> struct HandleType { }; template -class Handle - : public BaseHandle, - public Emitter, - public std::enable_shared_from_this -{ +class Handle: public BaseHandle, public Emitter, public Self { struct BaseWrapper { virtual ~BaseWrapper() = default; virtual void * get() const noexcept = 0; @@ -45,20 +42,18 @@ class Handle static void closeCallback(uv_handle_t *handle) { Handle &ref = *(static_cast(handle->data)); - ref.initialized = false; ref.publish(CloseEvent{}); - ref.leak.reset(); + ref.reset(); } protected: template explicit Handle(HandleType, std::shared_ptr ref) - : Emitter{}, - std::enable_shared_from_this{}, + : BaseHandle{}, + Emitter{}, + Self{}, wrapper{std::make_unique>()}, - pLoop{std::move(ref)}, - leak{nullptr}, - initialized{false} + pLoop{std::move(ref)} { this->template get()->data = static_cast(this); } @@ -70,21 +65,17 @@ protected: template bool initialize(F &&f, Args&&... args) { - bool ret = true; - - if(!initialized) { + if(!this->self()) { auto err = std::forward(f)(parent(), get(), std::forward(args)...); if(err) { this->publish(ErrorEvent{err}); - ret = false; } else { - leak = this->shared_from_this(); - initialized = true; + this->leak(); } } - return ret; + return this->self(); } template @@ -117,8 +108,6 @@ public: private: std::unique_ptr wrapper; std::shared_ptr pLoop; - std::shared_ptr leak; - bool initialized; }; diff --git a/src/uvw/self.hpp b/src/uvw/self.hpp new file mode 100644 index 00000000..aff2e3d1 --- /dev/null +++ b/src/uvw/self.hpp @@ -0,0 +1,21 @@ +#pragma once + + +#include + + +namespace uvw { + + +template +struct Self: std::enable_shared_from_this { + void leak() noexcept { ptr = this->shared_from_this(); } + void reset() noexcept { ptr.reset(); } + bool self() const noexcept { return static_cast(ptr); } + +private: + std::shared_ptr ptr{nullptr}; +}; + + +}