diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 9e7996f8..e1574d5c 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -18,6 +18,7 @@ template<> struct HandleType { }; template<> struct HandleType { }; template<> struct HandleType { }; template<> struct HandleType { }; +template<> struct HandleType { }; template<> struct HandleType { }; template<> struct HandleType { }; template<> struct HandleType { }; diff --git a/src/uvw/pipe.hpp b/src/uvw/pipe.hpp new file mode 100644 index 00000000..4422a240 --- /dev/null +++ b/src/uvw/pipe.hpp @@ -0,0 +1,58 @@ +#pragma once + + +#include +#include +#include +#include +#include +#include "event.hpp" +#include "request.hpp" +#include "stream.hpp" +#include "util.hpp" + + +namespace uvw { + + +class Pipe final: public Stream { + explicit Pipe(std::shared_ptr ref) + : Stream{HandleType{}, std::move(ref)} + { } + +public: + template + static std::shared_ptr create(Args&&... args) { + return std::shared_ptr{new Pipe{std::forward(args)...}}; + } + + bool init(bool ipc = false) { return initialize(&uv_ipc_init, ipc); } + + void bind(std::string name) { + invoke(&uv_pipe_bind, get(), name.data()); + } + + void connect(std::string name) { + std::weak_ptr weak = this->shared_from_this(); + + auto listener = [weak](const auto &event, details::Connect &) { + auto ptr = weak.lock(); + if(ptr) { ptr->publish(event); } + }; + + auto connect = loop().resource(); + connect->once(listener); + connect->once(listener); + connect->connect(&uv_pipe_connect, get(), name.data()); + } + + std::string sock() const noexcept { return details::path(&uv_pipe_getsockname, get()); } + std::string peer() const noexcept { return details::path(&uv_pipe_getpeername, get()); } + + // TODO uv_pipe_pending_instances + // TODO uv_pipe_pending_count + // TODO uv_pipe_pending_type +}; + + +} diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index d2704e70..48825fb1 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -18,6 +18,24 @@ namespace uvw { namespace details { +class Connect final: public Request { + explicit Connect(std::shared_ptr ref) + : Request{RequestType{}, std::move(ref)} + { } + +public: + template + static std::shared_ptr create(Args&&... args) { + return std::shared_ptr{new Connect{std::forward(args)...}}; + } + + template + void connect(F &&f, A... args) { + exec(std::forward(f), get(), std::forward(args)...); + } +}; + + class Shutdown final: public Request { explicit Shutdown(std::shared_ptr ref) : Request{RequestType{}, std::move(ref)} @@ -111,6 +129,8 @@ public: listen(DEFAULT_BACKLOG); } + virtual void accept(T &) = 0; + 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 ac706c20..f68d6853 100644 --- a/src/uvw/tcp.hpp +++ b/src/uvw/tcp.hpp @@ -16,47 +16,24 @@ namespace uvw { -namespace details { - - -class Connect final: public Request { - explicit Connect(std::shared_ptr ref) - : Request{RequestType{}, std::move(ref)} - { } - -public: - template - static std::shared_ptr create(Args&&... args) { - return std::shared_ptr{new Connect{std::forward(args)...}}; - } - - void connect(uv_tcp_t *handle, const sockaddr *addr) { - exec(&uv_tcp_connect, get(), handle, addr); - } -}; - - -} - - class Tcp final: public Stream { - using AddressFunctionType = Addr(*)(const Tcp &); - using RemoteFunctionType = AddressFunctionType; + using SockFunctionType = Addr(*)(const Tcp &); + using PeerFunctionType = SockFunctionType; template - static Addr tAddress(const Tcp &tcp) noexcept { + static Addr tSock(const Tcp &tcp) noexcept { return details::address(uv_tcp_getsockname, tcp.get()); } template - static Addr tRemote(const Tcp &tcp) noexcept { + 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)}, - addressF{&tAddress}, - remoteF{&tRemote} + sockF{&tSock}, + peerF{&tPeer} { } public: @@ -90,8 +67,8 @@ public: Traits::AddrFunc(ip.data(), port, &addr); if(0 == invoke(&uv_tcp_bind, get(), reinterpret_cast(&addr), flags)) { - addressF = &tAddress; - remoteF = &tRemote; + sockF = &tSock; + peerF = &tPeer; } } @@ -100,8 +77,8 @@ public: bind(addr.ip, addr.port, flags); } - Addr address() const noexcept { return addressF(*this); } - Addr remote() const noexcept { return remoteF(*this); } + Addr sock() const noexcept { return sockF(*this); } + Addr peer() const noexcept { return peerF(*this); } template> void connect(std::string ip, unsigned int port) { @@ -114,8 +91,8 @@ public: auto ptr = weak.lock(); if(ptr) { - ptr->addressF = &tAddress; - ptr->remoteF = &tRemote; + ptr->sockF = &tSock; + ptr->peerF = &tPeer; ptr->publish(event); } }; @@ -123,22 +100,22 @@ public: auto connect = loop().resource(); connect->once(listener); connect->once(listener); - connect->connect(get(), reinterpret_cast(&addr)); + connect->connect(&uv_tcp_connect, get(), reinterpret_cast(&addr)); } template> void connect(Addr addr) { connect(addr.ip, addr.port); } - void accept(Tcp &tcp) { + void accept(Tcp &tcp) override { if(0 == invoke(&uv_accept, get(), tcp.get())) { - tcp.addressF = addressF; - tcp.remoteF = remoteF; + tcp.sockF = sockF; + tcp.peerF = peerF; } } private: - AddressFunctionType addressF; - RemoteFunctionType remoteF; + SockFunctionType sockF; + PeerFunctionType peerF; }; diff --git a/src/uvw/udp.hpp b/src/uvw/udp.hpp index 8782b429..aa6270b2 100644 --- a/src/uvw/udp.hpp +++ b/src/uvw/udp.hpp @@ -39,16 +39,16 @@ public: class Udp final: public Handle { - using AddressFunctionType = Addr(*)(const Udp &); - using RemoteFunctionType = Addr(*)(const sockaddr *); + using SockFunctionType = Addr(*)(const Udp &); + using PeerFunctionType = Addr(*)(const sockaddr *); template - static Addr tAddress(const Udp &udp) noexcept { + static Addr tSock(const Udp &udp) noexcept { return details::address(uv_udp_getsockname, udp.get()); } template> - static Addr tRemote(const sockaddr *addr) noexcept { + static Addr tPeer(const sockaddr *addr) noexcept { const typename Traits::Type *aptr = reinterpret_cast(addr); int len = sizeof(*addr); return details::address(aptr, len); @@ -56,8 +56,8 @@ class Udp final: public Handle { explicit Udp(std::shared_ptr ref) : Handle{HandleType{}, std::move(ref)}, - addressF{&tAddress}, - remoteF{&tRemote} + sockF{&tSock}, + peerF{&tPeer} { } static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) { @@ -67,12 +67,12 @@ class Udp final: public Handle { if(nread > 0) { // data available (can be truncated) - udp.publish(UDPDataEvent{udp.remoteF(addr), std::move(data), nread, flags & UV_UDP_PARTIAL}); + udp.publish(UDPDataEvent{udp.peerF(addr), 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.remoteF(addr), std::move(data), nread, false}); + udp.publish(UDPDataEvent{udp.peerF(addr), std::move(data), nread, false}); } else { // transmission error udp.publish(ErrorEvent(nread)); @@ -106,8 +106,8 @@ public: Traits::AddrFunc(ip.data(), port, &addr); if(0 == invoke(&uv_udp_bind, get(), reinterpret_cast(&addr), flags)) { - addressF = &tAddress; - remoteF = &tRemote; + sockF = &tSock; + peerF = &tPeer; } } @@ -116,13 +116,13 @@ public: bind(addr.ip, addr.port, flags); } - Addr address() const noexcept { return addressF(*this); } + Addr sock() const noexcept { return sockF(*this); } 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))) { - addressF = &tAddress; - remoteF = &tRemote; + sockF = &tSock; + peerF = &tPeer; } } @@ -137,8 +137,8 @@ public: template void multicastInterface(std::string interface) { if(0 == invoke(&uv_udp_set_multicast_interface, get(), interface.data())) { - addressF = &tAddress; - remoteF = &tRemote; + sockF = &tSock; + peerF = &tPeer; } } @@ -157,8 +157,8 @@ public: auto ptr = weak.lock(); if(ptr) { - ptr->addressF = &tAddress; - ptr->remoteF = &tRemote; + ptr->sockF = &tSock; + ptr->peerF = &tPeer; ptr->publish(event); } }; @@ -168,8 +168,8 @@ public: send->once(listener); send->send(get(), bufs, 1, reinterpret_cast(&addr)); - addressF = &tAddress; - remoteF = &tRemote; + sockF = &tSock; + peerF = &tPeer; } template> @@ -189,8 +189,8 @@ public: this->publish(ErrorEvent{bw}); bw = 0; } else { - addressF = &tAddress; - remoteF = &tRemote; + sockF = &tSock; + peerF = &tPeer; } return bw; @@ -205,8 +205,8 @@ public: void stop() { invoke(&uv_udp_recv_stop, get()); } private: - AddressFunctionType addressF; - RemoteFunctionType remoteF; + SockFunctionType sockF; + PeerFunctionType peerF; }; diff --git a/test/main.cpp b/test/main.cpp index 4eac3b67..d588e38a 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -30,10 +30,10 @@ void listen(uvw::Loop &loop) { srv.accept(*client); - uvw::Addr local = srv.address(); + uvw::Addr local = srv.sock(); std::cout << "local: " << local.ip << " " << local.port << std::endl; - uvw::Addr remote = client->remote(); + uvw::Addr remote = client->peer(); std::cout << "remote: " << remote.ip << " " << remote.port << std::endl; client->on([](const uvw::DataEvent &event, uvw::Tcp &) {