Skip to content

Commit

Permalink
Update yasio
Browse files Browse the repository at this point in the history
  • Loading branch information
halx99 committed Sep 1, 2021
1 parent 8fd1d82 commit 69a8ae9
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 128 deletions.
57 changes: 31 additions & 26 deletions Plugins/yasio/Source/yasio/Private/yasio/yasio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,9 @@ int io_transport_udp::confgure_remote(const ip::endpoint& peer)
if (connected_) // connected, update peer is pointless and useless
return -1;
this->peer_ = peer;
return this->connect();
if (!yasio__testbits(ctx_->properties_, YCPF_MCAST) || !yasio__testbits(ctx_->properties_, YCM_CLIENT))
this->connect(); // multicast client, don't bind multicast address for we can recvfrom non-multicast address
return 0;
}
int io_transport_udp::connect()
{
Expand All @@ -611,7 +613,6 @@ int io_transport_udp::connect()

int retval = this->socket_->connect_n(this->peer_);
connected_ = (retval == 0);

set_primitives();
return retval;
}
Expand Down Expand Up @@ -1654,27 +1655,7 @@ void io_service::do_nonblocking_accept_completion(io_channel* ctx, fd_set* fds_a
if (n > 0)
{
YASIO_KLOGV("[index: %d] recvfrom peer: %s succeed.", ctx->index_, peer.to_string().c_str());
#if !defined(_WIN32)
auto transport = static_cast<io_transport_udp*>(do_dgram_accept(ctx, peer, error));
#else
/*
Because Bind() the client socket to the socket address of the listening socket. On
Linux this essentially passes the responsibility for receiving data for the client
session from the well-known listening socket, to the newly allocated client socket. It
is important to note that this behavior is not the same on other platforms, like
Windows (unfortunately), detail see:
https://blog.grijjy.com/2018/08/29/creating-high-performance-udp-servers-on-windows-and-linux
https://cloud.tencent.com/developer/article/1004555
So we emulate thus by ourself, don't care the performance, just a workaround implementation.
*/
// for win32, we check exists udp clients by ourself, and only write operation can be
// perform on transports, the read operation still dispatch by channel.
auto it = yasio__find_if(this->transports_, [&peer](const io_transport* transport) {
using namespace std;
return yasio__testbits(transport->ctx_->properties_, YCM_UDP) && static_cast<const io_transport_udp*>(transport)->remote_endpoint() == peer;
});
auto transport = static_cast<io_transport_udp*>(it != this->transports_.end() ? *it : do_dgram_accept(ctx, peer, error));
#endif
if (transport)
{
if (transport->handle_input(ctx->buffer_.data(), n, error, this->wait_duration_) < 0)
Expand All @@ -1698,6 +1679,27 @@ void io_service::do_nonblocking_accept_completion(io_channel* ctx, fd_set* fds_a
}
transport_handle_t io_service::do_dgram_accept(io_channel* ctx, const ip::endpoint& peer, int& error)
{
/*
Because Bind() the client socket to the socket address of the listening socket. On
Linux this essentially passes the responsibility for receiving data for the client
session from the well-known listening socket, to the newly allocated client socket. It
is important to note that this behavior is not the same on other platforms, like
Windows (unfortunately), detail see:
https://blog.grijjy.com/2018/08/29/creating-high-performance-udp-servers-on-windows-and-linux
https://cloud.tencent.com/developer/article/1004555
So we emulate thus by ourself, don't care the performance, just a workaround implementation.
*/
// for win32 or multicast, we check exists udp clients by ourself, and only write operation can be
// perform on transports, the read operation still dispatch by channel.
#if defined(_WIN32) // route on user mode
auto it = yasio__find_if(this->transports_, [&peer](const io_transport* transport) {
using namespace std;
return yasio__testbits(transport->ctx_->properties_, YCM_UDP) && static_cast<const io_transport_udp*>(transport)->remote_endpoint() == peer;
});
if (it != this->transports_.end())
return *it;
#endif

auto new_sock = std::make_shared<xxsocket>();
if (new_sock->open(peer.af(), SOCK_DGRAM))
{
Expand All @@ -1711,10 +1713,10 @@ transport_handle_t io_service::do_dgram_accept(io_channel* ctx, const ip::endpoi
auto transport = static_cast<io_transport_udp*>(allocate_transport(ctx, std::move(new_sock)));
// We always establish 4 tuple with clients
transport->confgure_remote(peer);
#if !defined(_WIN32)
handle_connect_succeed(transport);
#else
#if defined(_WIN32)
notify_connect_succeed(transport);
#else
handle_connect_succeed(transport);
#endif
return transport;
}
Expand Down Expand Up @@ -1812,7 +1814,7 @@ void io_service::deallocate_transport(transport_handle_t t)
void io_service::handle_connect_failed(io_channel* ctx, int error)
{
ctx->properties_ &= 0xffffff; // clear highest byte flags
cleanup_io(ctx);
cleanup_channel(ctx);
YASIO_KLOGE("[index: %d] connect server %s failed, ec=%d, detail:%s", ctx->index_, ctx->format_destination().c_str(), error, io_service::strerror(error));
handle_event(cxx14::make_unique<io_event>(ctx->index_, YEK_ON_OPEN, error, ctx));
}
Expand Down Expand Up @@ -2033,6 +2035,9 @@ highp_time_t io_service::get_timeout(highp_time_t usec)
}
bool io_service::cleanup_channel(io_channel* ctx, bool clear_state)
{
#if YASIO_SSL_BACKEND != 0
ctx->ssl_.destroy();
#endif
bool bret = cleanup_io(ctx, clear_state);
#if defined(YAISO_ENABLE_PASSIVE_EVENT)
if (bret && yasio__testbits(ctx->properties_, YCM_SERVER))
Expand Down
2 changes: 2 additions & 0 deletions Plugins/yasio/Source/yasio/Public/yasio/.clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ KeepEmptyLinesAtTheStartOfBlocks: true

# Indent nested PP directives.
IndentPPDirectives: AfterHash

AlwaysBreakTemplateDeclarations: Yes
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,9 @@ SOFTWARE.
#if !defined(YASIO__NO_EXCEPTIONS)
# define YASIO__THROW(x, retval) throw(x)
# define YASIO__THROW0(x) throw(x)
# define YASIO__THROWV(x, val) (throw(x), (val))
#else
# define YASIO__THROW(x, retval) return (retval)
# define YASIO__THROW0(x) return
# define YASIO__THROWV(x, val) (val)
#endif

// Compatibility with non-clang compilers...
Expand Down
17 changes: 9 additions & 8 deletions Plugins/yasio/Source/yasio/Public/yasio/cxx17/string_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,9 @@ template <typename _CharT, typename _Traits>
inline typename basic_string_view<_CharT, _Traits>::const_reference
basic_string_view<_CharT, _Traits>::at(size_t pos) const
{
return pos < m_size ? m_str[pos]
: YASIO__THROWV(std::out_of_range("Input out of range in basic_string_view::at"), 0);
if (yasio__unlikely(pos >= m_size))
YASIO__THROW(std::out_of_range("Input out of range in basic_string_view::at"), 0);
return m_str[pos];
}

template <typename _CharT, typename _Traits>
Expand Down Expand Up @@ -846,7 +847,7 @@ template <typename _CharT, typename _Traits>
inline typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>::copy(char_type* dest, size_type count, size_type pos) const
{
if (pos >= m_size)
if (yasio__unlikely(pos >= m_size))
YASIO__THROW(std::out_of_range("Index out of range in basic_string_view::copy"), 0);

const size_type rcount = (std::min)(m_size - pos, count + 1);
Expand All @@ -859,10 +860,9 @@ inline basic_string_view<_CharT, _Traits>
basic_string_view<_CharT, _Traits>::substr(size_t pos, size_t len) const
{
const size_type max_length = pos > m_size ? 0 : m_size - pos;

return pos < m_size
? basic_string_view<_CharT, _Traits>(m_str + pos, len > max_length ? max_length : len)
: YASIO__THROWV(std::out_of_range("Index out of range in basic_string_view::substr"), (basic_string_view<_CharT, _Traits>{}));
if (yasio__unlikely(pos >= m_size))
YASIO__THROW(std::out_of_range("Index out of range in basic_string_view::substr"), (basic_string_view<_CharT, _Traits>{}));
return basic_string_view<_CharT, _Traits>(m_str + pos, len > max_length ? max_length : len);
}

//--------------------------------------------------------------------------
Expand Down Expand Up @@ -1428,12 +1428,13 @@ inline cxx17::u32string_view operator"" _sv(const char32_t* _Str, size_t _Len)
namespace cxx17
{
template <typename _CharT, typename _Traits, typename Allocator>
inline void assign(std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs)
inline std::basic_string<_CharT, _Traits, Allocator>& assign(std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs)
{
if (!rhs.empty())
lhs.assign(rhs.data(), rhs.size());
else
lhs.clear();
return lhs;
}
template <typename _CharT, typename _Traits, typename Allocator = std::allocator<_CharT>>
inline std::basic_string<_CharT, _Traits, Allocator> svtos(const basic_string_view<_CharT, _Traits>& value)
Expand Down
2 changes: 1 addition & 1 deletion Plugins/yasio/Source/yasio/Public/yasio/detail/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ SOFTWARE.
/*
** The yasio version macros
*/
#define YASIO_VERSION_NUM 0x033704
#define YASIO_VERSION_NUM 0x033705

/*
** The macros used by io_service.
Expand Down
21 changes: 7 additions & 14 deletions Plugins/yasio/Source/yasio/Public/yasio/detail/endian_portable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ SOFTWARE.
# endif
# include <WinSock2.h>
# include <Windows.h>
# pragma comment(lib, "ws2_32.lib")
#else
# include <arpa/inet.h>
#endif
Expand Down Expand Up @@ -103,16 +104,8 @@ SOFTWARE.

namespace yasio
{

inline uint64_t(htonll)(uint64_t Value)
{
return YASIO__SWAP_LONGLONG(Value);
}

inline uint64_t(ntohll)(uint64_t Value)
{
return YASIO__SWAP_LONGLONG(Value);
}
inline uint64_t (htonll)(uint64_t Value) { return YASIO__SWAP_LONGLONG(Value); }
inline uint64_t (ntohll)(uint64_t Value) { return YASIO__SWAP_LONGLONG(Value); }

YASIO__NS_INLINE
namespace endian
Expand All @@ -130,13 +123,13 @@ template <typename _Ty> struct byte_order_impl<_Ty, sizeof(int16_t)> {
};

template <typename _Ty> struct byte_order_impl<_Ty, sizeof(int32_t)> {
static inline _Ty host_to_network(_Ty value) { return static_cast<_Ty>(htonl(static_cast<uint32_t>(value))); }
static inline _Ty network_to_host(_Ty value) { return static_cast<_Ty>(ntohl(static_cast<uint32_t>(value))); }
static inline _Ty host_to_network(_Ty value) { return (_Ty)(htonl((uint32_t)(value))); }
static inline _Ty network_to_host(_Ty value) { return (_Ty)(ntohl((uint32_t)(value))); }
};

template <typename _Ty> struct byte_order_impl<_Ty, sizeof(int64_t)> {
static inline _Ty host_to_network(_Ty value) { return static_cast<_Ty>((::yasio::htonll)(static_cast<uint64_t>(value))); }
static inline _Ty network_to_host(_Ty value) { return static_cast<_Ty>((::yasio::ntohll)(static_cast<uint64_t>(value))); }
static inline _Ty host_to_network(_Ty value) { return (_Ty)((yasio::htonll)((uint64_t)(value))); }
static inline _Ty network_to_host(_Ty value) { return (_Ty)((yasio::ntohll)((uint64_t)(value))); }
};

#if defined(YASIO_HAVE_HALF_FLOAT)
Expand Down
Loading

0 comments on commit 69a8ae9

Please sign in to comment.