diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 1c2a06bd..baecdbbb 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -22,7 +22,11 @@ template<> struct HandleType { }; template -class Handle: public Emitter, public std::enable_shared_from_this { +class Handle + : public BaseHandle, + public Emitter, + public std::enable_shared_from_this +{ struct BaseWrapper { virtual ~BaseWrapper() = default; virtual void * get() const noexcept = 0; @@ -93,14 +97,14 @@ public: Loop& loop() const noexcept { return *pLoop; } - bool active() const noexcept { return !(uv_is_active(get()) == 0); } - bool closing() const noexcept { return !(uv_is_closing(get()) == 0); } + bool active() const noexcept override { return !(uv_is_active(get()) == 0); } + bool closing() const noexcept override { return !(uv_is_closing(get()) == 0); } - void reference() noexcept { uv_ref(get()); } - void unreference() noexcept { uv_unref(get()); } - bool referenced() const noexcept { return !(uv_has_ref(get()) == 0); } + void reference() noexcept override { uv_ref(get()); } + void unreference() noexcept override { uv_unref(get()); } + bool referenced() const noexcept override { return !(uv_has_ref(get()) == 0); } - void close() noexcept { + void close() noexcept override { if(!closing()) { uv_close(get(), &Handle::closeCallback); } diff --git a/src/uvw/loop.hpp b/src/uvw/loop.hpp index 4b4aa81e..b01095dd 100644 --- a/src/uvw/loop.hpp +++ b/src/uvw/loop.hpp @@ -13,6 +13,17 @@ namespace uvw { +class BaseHandle { +public: + virtual bool active() const noexcept = 0; + virtual bool closing() const noexcept = 0; + virtual void reference() noexcept = 0; + virtual void unreference() noexcept = 0; + virtual bool referenced() const noexcept = 0; + virtual void close() noexcept = 0; +}; + + class Loop final: public Emitter, public std::enable_shared_from_this { template friend class Handle; @@ -96,6 +107,16 @@ public: uv_stop(loop.get()); } + void walk(std::function callback) noexcept { + // remember: non-capturing lambdas decay to pointers to functions + uv_walk(loop.get(), [](uv_handle_t *handle, void *func) { + BaseHandle &ref = *static_cast(handle->data); + std::function &f = + *static_cast*>(func); + f(ref); + }, &callback); + } + private: std::unique_ptr loop; }; diff --git a/test/main.cpp b/test/main.cpp index 8a34e953..2b64e819 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -43,6 +43,9 @@ void listen(uvw::Loop &loop) { client->on([](const uvw::EndEvent &, uvw::Tcp &client) { std::cout << "end" << std::endl; + int count = 0; + client.loop().walk([&count](uvw::BaseHandle &handle) { ++count; }); + std::cout << "still alive: " << count << " handles" << std::endl; client.close(); });