From 10f0f1336b96767b1e84019d95af736b08b79189 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 09:35:50 +0200 Subject: [PATCH 01/11] refactoring --- README.md | 13 ++++--- src/uvw/stream.hpp | 5 ++- src/uvw/tcp.hpp | 63 ++++++++++--------------------- src/uvw/udp.hpp | 94 ++++++++++++++++------------------------------ src/uvw/util.hpp | 10 ++--- test/main.cpp | 4 +- 6 files changed, 71 insertions(+), 118 deletions(-) diff --git a/README.md b/README.md index a1449ebf..66272a5d 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ void listen(uvw::Loop &loop) { client->read(); }); - tcp->bind("127.0.0.1", 4242); + tcp->bind("127.0.0.1", 4242); tcp->listen(); } @@ -41,7 +41,7 @@ void conn(uvw::Loop &loop) { tcp.close(); }); - tcp->connect(std::string{"127.0.0.1"}, 4242); + tcp->connect(std::string{"127.0.0.1"}, 4242); } int main() { @@ -147,7 +147,7 @@ To know what are the available resources' types, please refer the API reference. ##### The event-based approach For `uvw` offers an event-based approach, resources are small event emitters to which listeners can be attached. -Attaching a listener to a resource is the reccomended way to be notified about changes. +Attaching a listener to a resource is the recommended way to be notified about changes. Listeners must be callable objects of type `void(const EventType &, ResourceType &)`, where: * `EventType` is the type of the event for which they have been designed @@ -180,11 +180,14 @@ tcp->on([](const uvw::ListenEvent &event, uvw::Tcp &srv) mutab client->read(); }); -tcp->bind("127.0.0.1", 4242); +tcp->bind("127.0.0.1", 4242); tcp->listen(); ``` -The API reference is the reccomended documentation for further details about resources and their methods. +Note that `uvw::Tcp` already supports _IPv6_ out-of-the-box. The statement above is equivalent to `tcp->bind("127.0.0.1", 4242)`. +It's suffice to explicitly specify `uvw::Tcp::IPv6` as the underlying protocol to use it. + +The API reference is the recommended documentation for further details about resources and their methods. ## Tests diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 191f7f67..36a8c1b4 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -126,7 +126,10 @@ public: listen(DEFAULT_BACKLOG); } - virtual void accept(T &) = 0; + template + void accept(U &ref) { + this->invoke(&uv_accept, this->template get(), ref.template get()); + } void read() { this->invoke(&uv_read_start, this->template get(), &this->allocCallback, &readCallback); diff --git a/src/uvw/tcp.hpp b/src/uvw/tcp.hpp index 7b3c985e..006f1f73 100644 --- a/src/uvw/tcp.hpp +++ b/src/uvw/tcp.hpp @@ -17,23 +17,8 @@ namespace uvw { class Tcp final: public Stream { - using SockFunctionType = Addr(*)(const Tcp &); - using PeerFunctionType = SockFunctionType; - - template - static Addr tSock(const Tcp &tcp) noexcept { - return details::address(uv_tcp_getsockname, tcp.get()); - } - - template - static Addr tPeer(const Tcp &tcp) noexcept { - return details::address(uv_tcp_getpeername, tcp.get()); - } - explicit Tcp(std::shared_ptr ref) - : Stream{HandleType{}, std::move(ref)}, - sockF{&tSock}, - peerF{&tPeer} + : Stream{HandleType{}, std::move(ref)} { } public: @@ -61,33 +46,34 @@ public: invoke(&uv_tcp_keepalive, get(), enable, time.count()); } - template> + template void bind(std::string ip, unsigned int port, Flags flags = Flags{}) { - typename Traits::Type addr; - Traits::AddrFunc(ip.data(), port, &addr); - - if(0 == invoke(&uv_tcp_bind, get(), reinterpret_cast(&addr), flags)) { - sockF = &tSock; - peerF = &tPeer; - } + typename details::IpTraits::Type addr; + details::IpTraits::AddrFunc(ip.data(), port, &addr); + invoke(&uv_tcp_bind, get(), reinterpret_cast(&addr), flags); } - template> + template void bind(Addr addr, Flags flags = Flags{}) { bind(addr.ip, addr.port, flags); } - Addr sock() const noexcept { return sockF(*this); } - Addr peer() const noexcept { return peerF(*this); } + template + Addr sock() const noexcept { + return details::address(&uv_tcp_getsockname, get()); + } - template> + template + Addr peer() const noexcept { + return details::address(&uv_tcp_getpeername, get()); + } + + template void connect(std::string ip, unsigned int port) { - typename Traits::Type addr; - Traits::AddrFunc(ip.data(), port, &addr); + typename details::IpTraits::Type addr; + details::IpTraits::AddrFunc(ip.data(), port, &addr); auto listener = [ptr = this->shared_from_this()](const auto &event, details::Connect &) { - ptr->sockF = &tSock; - ptr->peerF = &tPeer; ptr->publish(event); }; @@ -97,19 +83,8 @@ public: connect->connect(&uv_tcp_connect, get(), reinterpret_cast(&addr)); } - template> + template void connect(Addr addr) { connect(addr.ip, addr.port); } - - void accept(Tcp &tcp) override { - if(0 == invoke(&uv_accept, get(), tcp.get())) { - tcp.sockF = sockF; - tcp.peerF = peerF; - } - } - -private: - SockFunctionType sockF; - PeerFunctionType peerF; }; diff --git a/src/uvw/udp.hpp b/src/uvw/udp.hpp index b9469c31..3c7d7639 100644 --- a/src/uvw/udp.hpp +++ b/src/uvw/udp.hpp @@ -39,40 +39,27 @@ public: class Udp final: public Handle { - using SockFunctionType = Addr(*)(const Udp &); - using PeerFunctionType = Addr(*)(const sockaddr *); - - template - static Addr tSock(const Udp &udp) noexcept { - return details::address(uv_udp_getsockname, udp.get()); - } - - template> - static Addr tPeer(const sockaddr *addr) noexcept { - const typename Traits::Type *aptr = reinterpret_cast(addr); - int len = sizeof(*addr); - return details::address(aptr, len); - } - explicit Udp(std::shared_ptr ref) - : Handle{HandleType{}, std::move(ref)}, - sockF{&tSock}, - peerF{&tPeer} + : Handle{HandleType{}, std::move(ref)} { } + template static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) { + typename details::IpTraits::Type *aptr = reinterpret_cast::Type *>(addr); + int len = sizeof(*addr); + Udp &udp = *(static_cast(handle->data)); // data will be destroyed no matter of what the value of nread is std::unique_ptr data{buf->base}; if(nread > 0) { // data available (can be truncated) - udp.publish(UDPDataEvent{udp.peerF(addr), std::move(data), nread, flags & UV_UDP_PARTIAL}); + udp.publish(UDPDataEvent{details::address(aptr, len), std::move(data), nread, flags & UV_UDP_PARTIAL}); } else if(nread == 0 && addr == nullptr) { // no more data to be read, doing nothing is fine } else if(nread == 0 && addr != nullptr) { // empty udp packet - udp.publish(UDPDataEvent{udp.peerF(addr), std::move(data), nread, false}); + udp.publish(UDPDataEvent{details::address(aptr, len), std::move(data), nread, false}); } else { // transmission error udp.publish(ErrorEvent(nread)); @@ -100,30 +87,26 @@ public: bool init() { return initialize(&uv_udp_init); } - template> + template void bind(std::string ip, unsigned int port, Flags flags = Flags{}) { - typename Traits::Type addr; - Traits::AddrFunc(ip.data(), port, &addr); - - if(0 == invoke(&uv_udp_bind, get(), reinterpret_cast(&addr), flags)) { - sockF = &tSock; - peerF = &tPeer; - } + typename details::IpTraits::Type addr; + details::IpTraits::AddrFunc(ip.data(), port, &addr); + invoke(&uv_udp_bind, get(), reinterpret_cast(&addr), flags); } - template> + template void bind(Addr addr, Flags flags = Flags{}) { bind(addr.ip, addr.port, flags); } - Addr sock() const noexcept { return sockF(*this); } + template + Addr sock() const noexcept { + return details::address(&uv_udp_getsockname, get()); + } - template + template void multicastMembership(std::string multicast, std::string interface, Membership membership) { - if(0 == invoke(&uv_udp_set_membership, get(), multicast.data(), interface.data(), static_cast(membership))) { - sockF = &tSock; - peerF = &tPeer; - } + invoke(&uv_udp_set_membership, get(), multicast.data(), interface.data(), static_cast(membership)); } void multicastLoop(bool enable = true) { @@ -134,27 +117,22 @@ public: invoke(&uv_udp_set_multicast_ttl, get(), val > 255 ? 255 : val); } - template + template void multicastInterface(std::string interface) { - if(0 == invoke(&uv_udp_set_multicast_interface, get(), interface.data())) { - sockF = &tSock; - peerF = &tPeer; - } + invoke(&uv_udp_set_multicast_interface, get(), interface.data()); } void broadcast(bool enable = false) { invoke(&uv_udp_set_broadcast, get(), enable); } void ttl(int val) { invoke(&uv_udp_set_ttl, get(), val > 255 ? 255 : val); } - template> + template void send(std::string ip, unsigned int port, char *data, ssize_t len) { - typename Traits::Type addr; - Traits::AddrFunc(ip.data(), port, &addr); + typename details::IpTraits::Type addr; + details::IpTraits::AddrFunc(ip.data(), port, &addr); uv_buf_t bufs[] = { uv_buf_init(data, len) }; auto listener = [ptr = this->shared_from_this()](const auto &event, details::Send &) { - ptr->sockF = &tSock; - ptr->peerF = &tPeer; ptr->publish(event); }; @@ -162,20 +140,17 @@ public: send->once(listener); send->once(listener); send->send(get(), bufs, 1, reinterpret_cast(&addr)); - - sockF = &tSock; - peerF = &tPeer; } - template> + template void send(std::string ip, unsigned int port, std::unique_ptr data, ssize_t len) { send(ip, port, data.get(), len); } - template> + template int trySend(std::string ip, unsigned int port, char *data, ssize_t len) { - typename Traits::Type addr; - Traits::AddrFunc(ip.data(), port, &addr); + typename details::IpTraits::Type addr; + details::IpTraits::AddrFunc(ip.data(), port, &addr); uv_buf_t bufs[] = { uv_buf_init(data, len) }; auto bw = uv_udp_try_send(get(), bufs, 1, reinterpret_cast(&addr)); @@ -183,25 +158,22 @@ public: if(bw < 0) { this->publish(ErrorEvent{bw}); bw = 0; - } else { - sockF = &tSock; - peerF = &tPeer; } return bw; } - template> + template int trySend(std::string ip, unsigned int port, std::unique_ptr data, ssize_t len) { return trySend(ip, port, data.get(), len); } - void recv() { invoke(&uv_udp_recv_start, get(), &allocCallback, &recvCallback); } - void stop() { invoke(&uv_udp_recv_stop, get()); } + template + void recv() { + invoke(&uv_udp_recv_start, get(), &allocCallback, &recvCallback); + } -private: - SockFunctionType sockF; - PeerFunctionType peerF; + void stop() { invoke(&uv_udp_recv_stop, get()); } }; diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index 7c41bd95..02fb1481 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -107,12 +107,12 @@ const IpTraits::NameFuncType IpTraits::NameFunc = &uv_ip4_name; const IpTraits::NameFuncType IpTraits::NameFunc = &uv_ip6_name; -template> -Addr address(const typename Traits::Type *aptr, int len) noexcept { +template +Addr address(const typename details::IpTraits::Type *aptr, int len) noexcept { std::pair addr{}; char name[len]; - int err = Traits::NameFunc(aptr, name, len); + int err = details::IpTraits::NameFunc(aptr, name, len); if(0 == err) { addr = { std::string{name}, ntohs(aptr->sin_port) }; @@ -126,7 +126,7 @@ Addr address(const typename Traits::Type *aptr, int len) noexcept { } -template> +template Addr address(F &&f, const H *handle) noexcept { sockaddr_storage ssto; int len = sizeof(ssto); @@ -135,7 +135,7 @@ Addr address(F &&f, const H *handle) noexcept { int err = std::forward(f)(handle, reinterpret_cast(&ssto), &len); if(0 == err) { - typename Traits::Type *aptr = reinterpret_cast(&ssto); + typename details::IpTraits::Type *aptr = reinterpret_cast::Type *>(&ssto); addr = address(aptr, len); } diff --git a/test/main.cpp b/test/main.cpp index d588e38a..8858ff23 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -56,7 +56,7 @@ void listen(uvw::Loop &loop) { std::cout << "close" << std::endl; }); - tcp->bind("127.0.0.1", 4242); + tcp->bind("127.0.0.1", 4242); tcp->listen(); } @@ -88,7 +88,7 @@ void conn(uvw::Loop &loop) { std::cout << "close" << std::endl; }); - tcp->connect(std::string{"127.0.0.1"}, 4242); + tcp->connect(std::string{"127.0.0.1"}, 4242); } void g() { From 8b2a219450b465964ce0ec73c56c56d398a4773d Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 14:50:00 +0200 Subject: [PATCH 02/11] minor changes --- src/uvw/request.hpp | 16 ++++++++-------- src/uvw/stream.hpp | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp index 4686b3e4..0127c38b 100644 --- a/src/uvw/request.hpp +++ b/src/uvw/request.hpp @@ -42,18 +42,18 @@ class Request: public Resource { protected: using Resource::Resource; - template - auto exec(F &&f, A&&... args) - -> std::enable_if_t))>>::value, int> { - auto ret = this->invoke(std::forward(f), std::forward(args)..., &execCallback); + template + auto exec(F &&f, Args&&... args) + -> std::enable_if_t))>>::value, int> { + auto ret = this->invoke(std::forward(f), std::forward(args)..., &execCallback); if(0 == ret) { this->leak(); } return ret; } - template - auto exec(F &&f, A&&... args) - -> std::enable_if_t))>>::value> { - std::forward(f)(std::forward(args)..., &execCallback); + template + auto exec(F &&f, Args&&... args) + -> std::enable_if_t))>>::value> { + std::forward(f)(std::forward(args)..., &execCallback); this->leak(); } diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 36a8c1b4..65fe262e 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -29,9 +29,9 @@ public: return std::shared_ptr{new Connect{std::forward(args)...}}; } - template - void connect(F &&f, A... args) { - exec(std::forward(f), get(), std::forward(args)...); + template + void connect(F &&f, Args... args) { + exec(std::forward(f), get(), std::forward(args)...); } }; From 1b310caabefd83bd65db5a35a1e8e1dd4815e926 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 14:57:46 +0200 Subject: [PATCH 03/11] improved Loop --- src/uvw/loop.hpp | 29 +++++++++++++++++++++++++++++ test/uvw/loop.cpp | 2 ++ 2 files changed, 31 insertions(+) diff --git a/src/uvw/loop.hpp b/src/uvw/loop.hpp index 8e0bad1e..000396e7 100644 --- a/src/uvw/loop.hpp +++ b/src/uvw/loop.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "emitter.hpp" #include "util.hpp" @@ -35,6 +36,12 @@ class Loop final: public Emitter, public std::enable_shared_from_this { + BLOCK_SIGNAL = UV_LOOP_BLOCK_SIGNAL + }; + static std::shared_ptr create() { auto ptr = std::unique_ptr{new uv_loop_t, [](uv_loop_t *l){ delete l; }}; auto loop = std::shared_ptr(new Loop{std::move(ptr)}); @@ -77,6 +84,12 @@ public: } } + template + void configure(Configure flag, Args... args) { + auto err = uv_loop_configure(loop.get(), static_cast>(flag), std::forward(args)...); + if(err) { publish(ErrorEvent{err}); } + } + template std::enable_if_t::value, std::shared_ptr> resource(Args&&... args) { @@ -116,6 +129,22 @@ public: uv_stop(loop.get()); } + FileDescriptor descriptor() const noexcept { + return uv_backend_fd(loop.get()); + } + + Time timeout() const noexcept { + return Time{uv_backend_timeout(loop.get())}; + } + + Time now() const noexcept { + return Time{uv_now(loop.get())}; + } + + void update() const noexcept { + return uv_update_time(loop.get()); + } + void walk(std::function callback) { // remember: non-capturing lambdas decay to pointers to functions uv_walk(loop.get(), [](uv_handle_t *handle, void *func) { diff --git a/test/uvw/loop.cpp b/test/uvw/loop.cpp index e94afc02..1dce00c5 100644 --- a/test/uvw/loop.cpp +++ b/test/uvw/loop.cpp @@ -3,6 +3,8 @@ TEST(Loop, Basics) { + // TODO partially done + auto def = uvw::Loop::getDefault(); ASSERT_TRUE(static_cast(def)); From a9c44dab3e5fff5f27beb62af2e2a86565c80485 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 17:02:09 +0200 Subject: [PATCH 04/11] refinement of Tcp --- src/uvw/tcp.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/uvw/tcp.hpp b/src/uvw/tcp.hpp index 006f1f73..147723fb 100644 --- a/src/uvw/tcp.hpp +++ b/src/uvw/tcp.hpp @@ -38,6 +38,11 @@ public: bool init() { return initialize(&uv_tcp_init); } + template + bool init(T&& t, Args&&... args) { + return initialize(&uv_tcp_init_ex, std::forward(t), std::forward(args)...); + } + void noDelay(bool value = false) { invoke(&uv_tcp_nodelay, get(), value); } @@ -46,6 +51,10 @@ public: invoke(&uv_tcp_keepalive, get(), enable, time.count()); } + void simultaneousAccepts(bool enable = true) { + invoke(&uv_tcp_simultaneous_accepts, get(), enable); + } + template void bind(std::string ip, unsigned int port, Flags flags = Flags{}) { typename details::IpTraits::Type addr; From 8976288b05ea72ee44e6df72b991e1a677a3fdcb Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 17:02:15 +0200 Subject: [PATCH 05/11] minor changes --- src/uvw/loop.hpp | 2 +- src/uvw/poll.hpp | 2 +- src/uvw/tty.hpp | 6 +++--- src/uvw/util.hpp | 25 ++++++++++++++----------- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/uvw/loop.hpp b/src/uvw/loop.hpp index 000396e7..91a3d099 100644 --- a/src/uvw/loop.hpp +++ b/src/uvw/loop.hpp @@ -129,7 +129,7 @@ public: uv_stop(loop.get()); } - FileDescriptor descriptor() const noexcept { + FileHandle descriptor() const noexcept { return uv_backend_fd(loop.get()); } diff --git a/src/uvw/poll.hpp b/src/uvw/poll.hpp index ff6a816e..a2af3c32 100644 --- a/src/uvw/poll.hpp +++ b/src/uvw/poll.hpp @@ -36,7 +36,7 @@ public: return std::shared_ptr{new Poll{std::forward(args)...}}; } - bool init(FileDescriptor fd) { return initialize(&uv_poll_init, static_cast(fd)); } + bool init(FileHandle fd) { return initialize(&uv_poll_init, static_cast(fd)); } void start(Flags flags) { invoke(&uv_poll_start, get(), flags, &startCallback); } void start(Event event) { start(Flags{event}); } diff --git a/src/uvw/tty.hpp b/src/uvw/tty.hpp index a5dda816..fad00ce2 100644 --- a/src/uvw/tty.hpp +++ b/src/uvw/tty.hpp @@ -15,10 +15,10 @@ namespace uvw { class TTY final: public Stream { explicit TTY(std::shared_ptr ref, - FileDescriptor desc, + FileHandle desc, bool readable) : Stream{HandleType{}, std::move(ref)}, - fd{static_cast(desc)}, + fd{static_cast(desc)}, rw{readable} { } @@ -63,7 +63,7 @@ public: } private: - FileDescriptor::Type fd; + FileHandle::Type fd; int rw; }; diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index 02fb1481..82dc9d15 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -44,21 +44,24 @@ private: }; -struct FileDescriptor { - using Type = uv_file; - - constexpr FileDescriptor(Type desc): fd{desc} { } - - constexpr operator Type() const noexcept { return fd; } - +template +struct UVTypeWrapper { + using Type = T; + constexpr UVTypeWrapper(Type val): value{val} { } + constexpr operator Type() const noexcept { return value; } private: - const Type fd; + const Type value; }; -static constexpr auto STDIN = FileDescriptor{0}; -static constexpr auto STDOUT = FileDescriptor{1}; -static constexpr auto STDERR = FileDescriptor{2}; +using FileHandle = UVTypeWrapper; +using OSSocketHandle = UVTypeWrapper; +using OSFileDescriptor = UVTypeWrapper; + + +static constexpr auto STDIN = FileHandle{0}; +static constexpr auto STDOUT = FileHandle{1}; +static constexpr auto STDERR = FileHandle{2}; /** From 9f515b6fb4dbec96ca7b33a5fb0d0f0998dfbbfe Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 17:05:41 +0200 Subject: [PATCH 06/11] refinement of Tcp --- src/uvw/tcp.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/uvw/tcp.hpp b/src/uvw/tcp.hpp index 147723fb..ce49875a 100644 --- a/src/uvw/tcp.hpp +++ b/src/uvw/tcp.hpp @@ -43,6 +43,10 @@ public: return initialize(&uv_tcp_init_ex, std::forward(t), std::forward(args)...); } + void open(OSSocketHandle sock) { + invoke(&uv_tcp_open, get(), sock); + } + void noDelay(bool value = false) { invoke(&uv_tcp_nodelay, get(), value); } From e7b2ac78a774b5556ca675641fb730a9a8e93973 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 17:17:30 +0200 Subject: [PATCH 07/11] refinement of Udp --- src/uvw/udp.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/uvw/udp.hpp b/src/uvw/udp.hpp index 3c7d7639..3a8570c0 100644 --- a/src/uvw/udp.hpp +++ b/src/uvw/udp.hpp @@ -87,6 +87,15 @@ public: bool init() { return initialize(&uv_udp_init); } + template + bool init(T&& t, Args&&... args) { + return initialize(&uv_udp_init_ex, std::forward(t), std::forward(args)...); + } + + void open(OSSocketHandle sock) { + invoke(&uv_udp_open, get(), sock); + } + template void bind(std::string ip, unsigned int port, Flags flags = Flags{}) { typename details::IpTraits::Type addr; From 04ba5d4c86966e68bbcd0ccaaa3305bb20158deb Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 17:17:53 +0200 Subject: [PATCH 08/11] a bunch of TODOs --- src/uvw/handle.hpp | 4 ++++ src/uvw/pipe.hpp | 2 ++ src/uvw/stream.hpp | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index e1574d5c..54b32c62 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -91,6 +91,10 @@ public: std::size_t size() const noexcept { return uv_handle_size(this->template get()->type); } + + // TODO uv_send_buffer_size + // TODO uv_recv_buffer_size + // TODO uv_fileno }; diff --git a/src/uvw/pipe.hpp b/src/uvw/pipe.hpp index 1413ff6e..36827cc9 100644 --- a/src/uvw/pipe.hpp +++ b/src/uvw/pipe.hpp @@ -28,6 +28,8 @@ public: bool init(bool ipc = false) { return initialize(&uv_pipe_init, ipc); } + // TODO uv_pipe_open + void bind(std::string name) { invoke(&uv_pipe_bind, get(), name.data()); } diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 65fe262e..4b480fba 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -156,6 +156,8 @@ public: write(data.get(), len); } + // TODO uv_write2 + int tryWrite(char *data, ssize_t len) { uv_buf_t bufs[] = { uv_buf_init(data, len) }; auto bw = uv_try_write(this->template get(), bufs, 1); @@ -179,6 +181,8 @@ public: bool writable() const noexcept { return (uv_is_writable(this->template get()) == 1); } + + // TODO uv_stream_set_blocking }; From e1f37d9ab3087aba99943a2beab117224a6ae9cf Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 17:32:32 +0200 Subject: [PATCH 09/11] fixed types --- src/uvw/loop.hpp | 2 +- src/uvw/poll.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uvw/loop.hpp b/src/uvw/loop.hpp index 91a3d099..b0b618cc 100644 --- a/src/uvw/loop.hpp +++ b/src/uvw/loop.hpp @@ -129,7 +129,7 @@ public: uv_stop(loop.get()); } - FileHandle descriptor() const noexcept { + int descriptor() const noexcept { return uv_backend_fd(loop.get()); } diff --git a/src/uvw/poll.hpp b/src/uvw/poll.hpp index a2af3c32..760e1d28 100644 --- a/src/uvw/poll.hpp +++ b/src/uvw/poll.hpp @@ -36,7 +36,7 @@ public: return std::shared_ptr{new Poll{std::forward(args)...}}; } - bool init(FileHandle fd) { return initialize(&uv_poll_init, static_cast(fd)); } + bool init(int fd) { return initialize(&uv_poll_init, fd); } void start(Flags flags) { invoke(&uv_poll_start, get(), flags, &startCallback); } void start(Event event) { start(Flags{event}); } From bdc6f19de7562eac08b3a6d99408fa7d24be5ef0 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 17:39:09 +0200 Subject: [PATCH 10/11] refinement of Handle --- src/uvw/handle.hpp | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 54b32c62..b1676ad1 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -39,6 +39,22 @@ class Handle: public BaseHandle, public Resource ref.publish(CloseEvent{}); } + template + int setBufferSize(F &&f) { + int value = 0; + + if(0 != invoke(std::forward(f), this->template get(), &value)) { + value = 0; + } + + return 0; + } + + template + void getBufferSize(F &&f, int value) { + invoke(&std::forward(f), this->template get(), &value); + } + protected: using Resource::Resource; @@ -92,9 +108,27 @@ public: return uv_handle_size(this->template get()->type); } - // TODO uv_send_buffer_size - // TODO uv_recv_buffer_size - // TODO uv_fileno + int sendBufferSize() const { + return setBufferSize(&uv_send_buffer_size); + } + + void sendBufferSize(int value) { + getBufferSize(&uv_send_buffer_size, value); + } + + int recvBufferSize() const { + return setBufferSize(&uv_recv_buffer_size); + } + + void recvBufferSize(int value) { + getBufferSize(&uv_recv_buffer_size, value); + } + + OSFileDescriptor fileno() const { + uv_os_fd_t fd; + invoke(&uv_fileno, this->template get(), &fd); + return fd; + } }; From eed71a5e68fb10f495e612fc53445401d746a653 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Jul 2016 17:57:01 +0200 Subject: [PATCH 11/11] refinement of Stream --- src/uvw/stream.hpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 4b480fba..d80e43cb 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -67,6 +67,10 @@ public: void write(uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs) { exec(&uv_write, get(), handle, bufs, nbufs); } + + void write(uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t *send) { + exec(&uv_write2, get(), handle, bufs, nbufs, send); + } }; @@ -127,7 +131,7 @@ public: } template - void accept(U &ref) { + void accept(Stream &ref) { this->invoke(&uv_accept, this->template get(), ref.template get()); } @@ -156,7 +160,24 @@ public: write(data.get(), len); } - // TODO uv_write2 + template + void write(Stream &send, char *data, ssize_t len) { + uv_buf_t bufs[] = { uv_buf_init(data, len) }; + + auto listener = [ptr = this->shared_from_this()](const auto &event, details::Write &) { + ptr->publish(event); + }; + + auto write = this->loop().template resource(); + write->template once(listener); + write->template once(listener); + write->write(this->template get(), bufs, 1, send.template get()); + } + + template + void write(Stream &send, std::unique_ptr data, ssize_t len) { + write(send, data.get(), len); + } int tryWrite(char *data, ssize_t len) { uv_buf_t bufs[] = { uv_buf_init(data, len) }; @@ -182,7 +203,9 @@ public: return (uv_is_writable(this->template get()) == 1); } - // TODO uv_stream_set_blocking + void blocking(bool enable = false) { + this->invoke(&uv_stream_set_blocking, this->template get(), enable); + } };