reference given back to the caller + tcp.connect migrated to the callback model
This commit is contained in:
parent
a411679970
commit
f10bb0503a
@ -12,8 +12,8 @@ namespace uvw {
|
|||||||
|
|
||||||
|
|
||||||
class Check final: public Resource<Check> {
|
class Check final: public Resource<Check> {
|
||||||
static void startCallback(Check &, std::function<void(UVWError)> &cb, uv_check_t*) {
|
static void startCallback(Check &check, std::function<void(UVWError, Check &)> &cb, uv_check_t *) {
|
||||||
cb(UVWError{});
|
cb(UVWError{}, check);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Check(std::shared_ptr<Loop> ref)
|
explicit Check(std::shared_ptr<Loop> ref)
|
||||||
@ -28,11 +28,11 @@ public:
|
|||||||
return std::shared_ptr<Check>{new Check{std::forward<Args>(args)...}};
|
return std::shared_ptr<Check>{new Check{std::forward<Args>(args)...}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(std::function<void(UVWError)> cb) noexcept {
|
void start(std::function<void(UVWError, Check &)> cb) noexcept {
|
||||||
using CB = Callback<void(uv_check_t*)>;
|
using CB = Callback<void(uv_check_t *)>;
|
||||||
auto func = CB::on<&Check::startCallback>(*this, cb);
|
auto func = CB::on<&Check::startCallback>(*this, cb);
|
||||||
auto err = uv_check_start(get<uv_check_t>(), func);
|
auto err = uv_check_start(get<uv_check_t>(), func);
|
||||||
if(err) { cb(UVWError{err}); }
|
if(err) { cb(UVWError{err}, *this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
UVWError stop() noexcept { return UVWError{uv_check_stop(get<uv_check_t>())}; }
|
UVWError stop() noexcept { return UVWError{uv_check_stop(get<uv_check_t>())}; }
|
||||||
|
|||||||
@ -24,8 +24,8 @@ class Resource;
|
|||||||
namespace details {
|
namespace details {
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> void* get(T *handle) { return handle->data; }
|
||||||
void* get(T *handle) { return handle->data; }
|
void* get(uv_connect_t *conn) { return conn->handle->data; }
|
||||||
|
|
||||||
|
|
||||||
template<typename T, typename F>
|
template<typename T, typename F>
|
||||||
@ -34,17 +34,17 @@ struct UVCallback;
|
|||||||
|
|
||||||
template<typename T,typename H, typename... Args>
|
template<typename T,typename H, typename... Args>
|
||||||
struct UVCallback<T, void(H, Args...)> {
|
struct UVCallback<T, void(H, Args...)> {
|
||||||
template<void(*F)(T &, std::function<void(UVWError)> &, H, Args...)>
|
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||||
static auto once(T &, std::function<void(UVWError)>);
|
static auto once(T &, std::function<void(UVWError, T &)>);
|
||||||
|
|
||||||
template<void(*F)(T &, std::function<void(UVWError)> &, H, Args...)>
|
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||||
static auto on(T &, std::function<void(UVWError)>);
|
static auto on(T &, std::function<void(UVWError, T &)>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<void(*F)(T &, std::function<void(UVWError)> &, H, Args...)>
|
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||||
static void protoOnce(H, Args...);
|
static void protoOnce(H, Args...);
|
||||||
|
|
||||||
template<void(*F)(T &, std::function<void(UVWError)> &, H, Args...)>
|
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||||
static void protoOn(H, Args...);
|
static void protoOn(H, Args...);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,8 +57,8 @@ class Resource: public std::enable_shared_from_this<T> {
|
|||||||
template<typename, typename>
|
template<typename, typename>
|
||||||
friend struct details::UVCallback;
|
friend struct details::UVCallback;
|
||||||
|
|
||||||
static void closeCallback(T &, std::function<void(UVWError)> &cb, uv_handle_t*) {
|
static void closeCallback(T &t, std::function<void(UVWError, T &)> &cb, uv_handle_t*) {
|
||||||
cb(UVWError{});
|
cb(UVWError{}, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -93,7 +93,7 @@ public:
|
|||||||
void unreference() noexcept { uv_ref(get<uv_handle_t>()); }
|
void unreference() noexcept { uv_ref(get<uv_handle_t>()); }
|
||||||
bool referenced() const noexcept { return !(uv_has_ref(get<uv_handle_t>()) == 0); }
|
bool referenced() const noexcept { return !(uv_has_ref(get<uv_handle_t>()) == 0); }
|
||||||
|
|
||||||
void close(std::function<void(UVWError)> cb) noexcept {
|
void close(std::function<void(UVWError, T &)> cb) noexcept {
|
||||||
using CB = Callback<void(uv_handle_t*)>;
|
using CB = Callback<void(uv_handle_t*)>;
|
||||||
auto func = CB::template once<&Resource<T>::closeCallback>(*static_cast<T*>(this), std::move(cb));
|
auto func = CB::template once<&Resource<T>::closeCallback>(*static_cast<T*>(this), std::move(cb));
|
||||||
uv_close(get<uv_handle_t>(), func);
|
uv_close(get<uv_handle_t>(), func);
|
||||||
@ -103,7 +103,7 @@ private:
|
|||||||
std::shared_ptr<Loop> pLoop;
|
std::shared_ptr<Loop> pLoop;
|
||||||
std::shared_ptr<void> handle;
|
std::shared_ptr<void> handle;
|
||||||
std::shared_ptr<void> leak;
|
std::shared_ptr<void> leak;
|
||||||
std::function<void(UVWError)> callback;
|
std::function<void(UVWError, T &)> callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -111,8 +111,8 @@ namespace details {
|
|||||||
|
|
||||||
|
|
||||||
template<typename T, typename H, typename... Args>
|
template<typename T, typename H, typename... Args>
|
||||||
template<void(*F)(T &, std::function<void(UVWError)> &, H, Args...)>
|
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||||
auto UVCallback<T, void(H, Args...)>::once(T &ref, std::function<void(UVWError)> cb) {
|
auto UVCallback<T, void(H, Args...)>::once(T &ref, std::function<void(UVWError, T &)> cb) {
|
||||||
Resource<T> &res = ref;
|
Resource<T> &res = ref;
|
||||||
res.callback = std::move(cb);
|
res.callback = std::move(cb);
|
||||||
res.leak = res.shared_from_this();
|
res.leak = res.shared_from_this();
|
||||||
@ -121,8 +121,8 @@ auto UVCallback<T, void(H, Args...)>::once(T &ref, std::function<void(UVWError)>
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename H, typename... Args>
|
template<typename T, typename H, typename... Args>
|
||||||
template<void(*F)(T &, std::function<void(UVWError)> &, H, Args...)>
|
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||||
auto UVCallback<T, void(H, Args...)>::on(T &ref, std::function<void(UVWError)> cb) {
|
auto UVCallback<T, void(H, Args...)>::on(T &ref, std::function<void(UVWError, T &)> cb) {
|
||||||
Resource<T> &res = ref;
|
Resource<T> &res = ref;
|
||||||
res.callback = std::move(cb);
|
res.callback = std::move(cb);
|
||||||
res.leak = res.shared_from_this();
|
res.leak = res.shared_from_this();
|
||||||
@ -131,19 +131,17 @@ auto UVCallback<T, void(H, Args...)>::on(T &ref, std::function<void(UVWError)> c
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename H, typename... Args>
|
template<typename T, typename H, typename... Args>
|
||||||
template<void(*F)(T &, std::function<void(UVWError)> &, H, Args...)>
|
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||||
void UVCallback<T, void(H, Args...)>::protoOnce(H handle, Args... args) {
|
void UVCallback<T, void(H, Args...)>::protoOnce(H handle, Args... args) {
|
||||||
T &ref = *(static_cast<T*>(details::get(handle)));
|
T &ref = *(static_cast<T*>(details::get(handle)));
|
||||||
auto cb = ref.callback;
|
std::shared_ptr<T> ptr = std::static_pointer_cast<T>(ref.leak);
|
||||||
auto ptr = ref.leak;
|
auto cb = std::move(ref.callback);
|
||||||
ref.leak.reset();
|
ref.leak.reset();
|
||||||
F(ref, ref.callback, handle, std::forward<Args>(args)...);
|
F(*ptr, cb, handle, std::forward<Args>(args)...);
|
||||||
ref.callback = nullptr;
|
|
||||||
(void)ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename H, typename... Args>
|
template<typename T, typename H, typename... Args>
|
||||||
template<void(*F)(T &, std::function<void(UVWError)> &, H, Args...)>
|
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||||
void UVCallback<T, void(H, Args...)>::protoOn(H handle, Args... args) {
|
void UVCallback<T, void(H, Args...)>::protoOn(H handle, Args... args) {
|
||||||
T &ref = *(static_cast<T*>(details::get(handle)));
|
T &ref = *(static_cast<T*>(details::get(handle)));
|
||||||
F(ref, ref.callback, handle, std::forward<Args>(args)...);
|
F(ref, ref.callback, handle, std::forward<Args>(args)...);
|
||||||
|
|||||||
@ -11,8 +11,8 @@ namespace uvw {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Stream: public Resource<T> {
|
class Stream: public Resource<T> {
|
||||||
static void listenCallback(T &ref, std::function<void(UVWError)> &cb, uv_stream_t* srv, int status) {
|
static void listenCallback(T &t, std::function<void(UVWError, T &)> &cb, uv_stream_t *, int status) {
|
||||||
cb(UVWError{status});
|
cb(UVWError{status}, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -21,11 +21,11 @@ protected:
|
|||||||
public:
|
public:
|
||||||
// TODO shutdown
|
// TODO shutdown
|
||||||
|
|
||||||
void listen(int backlog, std::function<void(UVWError)> cb) noexcept {
|
void listen(int backlog, std::function<void(UVWError, T &)> cb) noexcept {
|
||||||
using CB = typename Resource<T>::template Callback<void(uv_stream_t*, int)>;
|
using CB = typename Resource<T>::template Callback<void(uv_stream_t *, int)>;
|
||||||
auto func = CB::on<&Stream<T>::listenCallback>(*static_cast<T*>(this), cb);
|
auto func = CB::on<&Stream<T>::listenCallback>(*static_cast<T*>(this), cb);
|
||||||
auto err = uv_listen(this->template get<uv_stream_t>(), backlog, func);
|
auto err = uv_listen(this->template get<uv_stream_t>(), backlog, func);
|
||||||
if(err) { cb(UVWError{err}); }
|
if(err) { cb(UVWError{err}, *static_cast<T*>(this)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO read
|
// TODO read
|
||||||
|
|||||||
@ -16,10 +16,8 @@ namespace uvw {
|
|||||||
|
|
||||||
|
|
||||||
class Tcp final: public Stream<Tcp> {
|
class Tcp final: public Stream<Tcp> {
|
||||||
static void protoConnect(uv_connect_t* req, int status) {
|
static void connectCallback(Tcp &tcp, std::function<void(UVWError, Tcp &)> &cb, uv_connect_t *, int status) {
|
||||||
Tcp *tcp = static_cast<Tcp*>(req->handle->data);
|
cb(UVWError{status}, tcp);
|
||||||
tcp->connCb(UVWError{status});
|
|
||||||
tcp->connCb = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Tcp(std::shared_ptr<Loop> ref)
|
explicit Tcp(std::shared_ptr<Loop> ref)
|
||||||
@ -52,44 +50,35 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<int>
|
template<int>
|
||||||
void connect(std::string, int, std::function<void(UVWError)>) noexcept;
|
void connect(std::string, int, std::function<void(UVWError, Tcp &)>) noexcept;
|
||||||
|
|
||||||
explicit operator bool() { return initialized; }
|
explicit operator bool() { return initialized; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<uv_connect_t> conn;
|
std::unique_ptr<uv_connect_t> conn;
|
||||||
std::function<void(UVWError)> connCb;
|
|
||||||
bool initialized;
|
bool initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Tcp::connect<Tcp::IPv4>(std::string ip, int port, std::function<void(UVWError)> cb) noexcept {
|
void Tcp::connect<Tcp::IPv4>(std::string ip, int port, std::function<void(UVWError, Tcp &)> cb) noexcept {
|
||||||
// TODO switch to the Callback model
|
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
uv_ip4_addr(ip.c_str(), port, &addr);
|
uv_ip4_addr(ip.c_str(), port, &addr);
|
||||||
connCb = std::move(cb);
|
using CB = Callback<void(uv_connect_t *, int)>;
|
||||||
get<uv_tcp_t>()->data = this;
|
auto func = CB::template once<&Tcp::connectCallback>(*this, cb);
|
||||||
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), func);
|
||||||
|
if(err) { cb(UVWError{err}, *this); }
|
||||||
if(err) {
|
|
||||||
connCb(UVWError{err});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Tcp::connect<Tcp::IPv6>(std::string ip, int port, std::function<void(UVWError)> cb) noexcept {
|
void Tcp::connect<Tcp::IPv6>(std::string ip, int port, std::function<void(UVWError, Tcp &)> cb) noexcept {
|
||||||
// TODO switch to the Callback model
|
|
||||||
sockaddr_in6 addr;
|
sockaddr_in6 addr;
|
||||||
uv_ip6_addr(ip.c_str(), port, &addr);
|
uv_ip6_addr(ip.c_str(), port, &addr);
|
||||||
connCb = std::move(cb);
|
using CB = Callback<void(uv_connect_t *, int)>;
|
||||||
get<uv_tcp_t>()->data = this;
|
auto func = CB::template once<&Tcp::connectCallback>(*this, cb);
|
||||||
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), func);
|
||||||
|
if(err) { cb(UVWError{err}, *this); }
|
||||||
if(err) {
|
|
||||||
connCb(UVWError{err});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -14,8 +14,8 @@ namespace uvw {
|
|||||||
|
|
||||||
|
|
||||||
class Timer final: public Resource<Timer> {
|
class Timer final: public Resource<Timer> {
|
||||||
static void startCallback(Timer &, std::function<void(UVWError)> &cb, uv_timer_t*) {
|
static void startCallback(Timer &timer, std::function<void(UVWError, Timer &)> &cb, uv_timer_t *) {
|
||||||
cb(UVWError{});
|
cb(UVWError{}, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit Timer(std::shared_ptr<Loop> ref)
|
explicit Timer(std::shared_ptr<Loop> ref)
|
||||||
@ -32,11 +32,11 @@ public:
|
|||||||
return std::shared_ptr<Timer>{new Timer{std::forward<Args>(args)...}};
|
return std::shared_ptr<Timer>{new Timer{std::forward<Args>(args)...}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(const Time &timeout, const Time &rep, std::function<void(UVWError)> cb) noexcept {
|
void start(const Time &timeout, const Time &rep, std::function<void(UVWError, Timer &)> cb) noexcept {
|
||||||
using CB = Callback<void(uv_timer_t*)>;
|
using CB = Callback<void(uv_timer_t *)>;
|
||||||
auto func = CB::on<&Timer::startCallback>(*this, cb);
|
auto func = CB::on<&Timer::startCallback>(*this, cb);
|
||||||
auto err = uv_timer_start(get<uv_timer_t>(), func, timeout.count(), rep.count());
|
auto err = uv_timer_start(get<uv_timer_t>(), func, timeout.count(), rep.count());
|
||||||
if(err) { cb(UVWError{err}); }
|
if(err) { cb(UVWError{err}, *this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
UVWError stop() noexcept { return UVWError{uv_timer_stop(get<uv_timer_t>())}; }
|
UVWError stop() noexcept { return UVWError{uv_timer_stop(get<uv_timer_t>())}; }
|
||||||
|
|||||||
@ -5,10 +5,9 @@
|
|||||||
void f(uvw::Loop &loop) {
|
void f(uvw::Loop &loop) {
|
||||||
uvw::Handle<uvw::Tcp> handle = loop.handle<uvw::Tcp>();
|
uvw::Handle<uvw::Tcp> handle = loop.handle<uvw::Tcp>();
|
||||||
|
|
||||||
auto cb = [handle](uvw::UVWError err) mutable {
|
auto cb = [](uvw::UVWError err, uvw::Tcp &tcp) mutable {
|
||||||
std::cout << "---" << ((bool)err) << std::endl;
|
std::cout << "---" << ((bool)err) << std::endl;
|
||||||
uvw::Tcp &tcp = handle;
|
tcp.close([](uvw::UVWError err, uvw::Tcp &) mutable {
|
||||||
tcp.close([](uvw::UVWError err) mutable {
|
|
||||||
std::cout << "---" << ((bool)err) << std::endl;
|
std::cout << "---" << ((bool)err) << std::endl;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user