From ffec57ec9313012af2fe10c9ab2356aff7ddfb7b Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 23 Jun 2016 18:53:10 +0200 Subject: [PATCH] WIP: safer callbacks --- src/uvw/check.hpp | 12 ++++++++---- src/uvw/timer.hpp | 21 ++++++++++++--------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/uvw/check.hpp b/src/uvw/check.hpp index da017266..8b66bf31 100644 --- a/src/uvw/check.hpp +++ b/src/uvw/check.hpp @@ -12,8 +12,10 @@ namespace uvw { class Check final: public Resource { - static void startCallback(uv_check_t* h) { - static_cast(h->data)->startCb(UVWError{}); + static Check* startCallback(uv_check_t* h) { + Check *check = static_cast(h->data); + check->startCb(UVWError{}); + return check; } explicit Check(std::shared_ptr ref) @@ -29,12 +31,14 @@ public: } void start(std::function cb) noexcept { + using UVCB = UVCallback; + auto func = UVCB::get(this); startCb = std::move(cb); - get()->data = this; - auto err = uv_check_start(get(), &startCallback); + auto err = uv_check_start(get(), func); if(err) { startCb(UVWError{err}); + reset(); } } diff --git a/src/uvw/timer.hpp b/src/uvw/timer.hpp index 77cac182..353fcf8d 100644 --- a/src/uvw/timer.hpp +++ b/src/uvw/timer.hpp @@ -14,8 +14,10 @@ namespace uvw { class Timer final: public Resource { - static void proto(uv_timer_t* h) { - static_cast(h->data)->callback(UVWError{}); + static Timer* startCallback(uv_timer_t* h) { + Timer *timer = static_cast(h->data); + timer->startCb(UVWError{}); + return timer; } explicit Timer(std::shared_ptr ref) @@ -26,20 +28,21 @@ class Timer final: public Resource { public: using Time = std::chrono::duration; - using Callback = std::function; template static std::shared_ptr create(Args&&... args) { return std::shared_ptr{new Timer{std::forward(args)...}}; } - void start(const Time &timeout, const Time &rep, Callback cb) noexcept { - callback = std::move(cb); - get()->data = this; - auto err = uv_timer_start(get(), &proto, timeout.count(), rep.count()); + void start(const Time &timeout, const Time &rep, std::function cb) noexcept { + using UVCB = UVCallback; + auto func = UVCB::get(this); + startCb = std::move(cb); + auto err = uv_timer_start(get(), func, timeout.count(), rep.count()); if(err) { - callback(UVWError{err}); + startCb(UVWError{err}); + reset(); } } @@ -51,7 +54,7 @@ public: explicit operator bool() { return initialized; } private: - Callback callback; + std::function startCb; bool initialized; };