fix: hanging client connect, see #33
The asio socket was moved in the eventloop thread, no in the server io context thread. Asio doc don't explicitly say moving is thread safe, so it moste likely isn't.
Dieser Commit ist enthalten in:
Ursprung
f5f85ee438
Commit
cdac489b11
@ -41,10 +41,10 @@ std::string connectionId(const boost::asio::ip::tcp::socket& socket)
|
||||
.append("]");
|
||||
}
|
||||
|
||||
Connection::Connection(Server& server, boost::asio::ip::tcp::socket socket)
|
||||
Connection::Connection(Server& server, std::unique_ptr<boost::asio::ip::tcp::socket> socket)
|
||||
: m_server{server}
|
||||
, m_socket(std::move(socket))
|
||||
, m_id{connectionId(m_socket)}
|
||||
, m_id{connectionId(*m_socket)}
|
||||
, m_authenticated{false}
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
@ -54,8 +54,8 @@ Connection::Connection(Server& server, boost::asio::ip::tcp::socket socket)
|
||||
m_server.m_ioContext.post(
|
||||
[this]()
|
||||
{
|
||||
m_socket.set_option(boost::asio::socket_base::linger(true, 0));
|
||||
m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
|
||||
m_socket->set_option(boost::asio::socket_base::linger(true, 0));
|
||||
m_socket->set_option(boost::asio::ip::tcp::no_delay(true));
|
||||
|
||||
doReadHeader();
|
||||
});
|
||||
@ -65,14 +65,14 @@ Connection::~Connection()
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
assert(!m_session);
|
||||
assert(!m_socket.is_open());
|
||||
assert(!m_socket->is_open());
|
||||
}
|
||||
|
||||
void Connection::doReadHeader()
|
||||
{
|
||||
assert(IS_SERVER_THREAD);
|
||||
|
||||
boost::asio::async_read(m_socket,
|
||||
boost::asio::async_read(*m_socket,
|
||||
boost::asio::buffer(&m_readBuffer.header, sizeof(m_readBuffer.header)),
|
||||
[this, weak=weak_from_this()](const boost::system::error_code& ec, std::size_t /*bytesReceived*/)
|
||||
{
|
||||
@ -110,7 +110,7 @@ void Connection::doReadData()
|
||||
{
|
||||
assert(IS_SERVER_THREAD);
|
||||
|
||||
boost::asio::async_read(m_socket,
|
||||
boost::asio::async_read(*m_socket,
|
||||
boost::asio::buffer(m_readBuffer.message->data(), m_readBuffer.message->dataSize()),
|
||||
//m_strand.wrap(
|
||||
[this, weak=weak_from_this()](const boost::system::error_code& ec, std::size_t /*bytesReceived*/)
|
||||
@ -143,7 +143,7 @@ void Connection::doWrite()
|
||||
{
|
||||
assert(IS_SERVER_THREAD);
|
||||
|
||||
boost::asio::async_write(m_socket, boost::asio::buffer(**m_writeQueue.front(), m_writeQueue.front()->size()),
|
||||
boost::asio::async_write(*m_socket, boost::asio::buffer(**m_writeQueue.front(), m_writeQueue.front()->size()),
|
||||
[this, weak=weak_from_this()](const boost::system::error_code& ec, std::size_t /*bytesTransferred*/)
|
||||
{
|
||||
if(weak.expired())
|
||||
@ -232,13 +232,13 @@ void Connection::disconnect()
|
||||
m_server.m_ioContext.post(
|
||||
[this]()
|
||||
{
|
||||
if(m_socket.is_open())
|
||||
if(m_socket->is_open())
|
||||
{
|
||||
boost::system::error_code ec;
|
||||
m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
|
||||
m_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
|
||||
if(ec && ec != boost::asio::error::not_connected)
|
||||
Log::log(m_id, LogMessage::E1005_SOCKET_SHUTDOWN_FAILED_X, ec);
|
||||
m_socket.close();
|
||||
m_socket->close();
|
||||
}
|
||||
|
||||
EventLoop::call(
|
||||
|
||||
@ -40,7 +40,7 @@ class Connection : public std::enable_shared_from_this<Connection>
|
||||
using ObjectHandle = uint32_t;
|
||||
|
||||
Server& m_server;
|
||||
boost::asio::ip::tcp::socket m_socket;
|
||||
std::unique_ptr<boost::asio::ip::tcp::socket> m_socket;
|
||||
const std::string m_id;
|
||||
struct
|
||||
{
|
||||
@ -62,7 +62,7 @@ class Connection : public std::enable_shared_from_this<Connection>
|
||||
void connectionLost();
|
||||
|
||||
public:
|
||||
Connection(Server& server, boost::asio::ip::tcp::socket socket);
|
||||
Connection(Server& server, std::unique_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
virtual ~Connection();
|
||||
|
||||
void disconnect();
|
||||
|
||||
@ -200,7 +200,7 @@ void Server::doAccept()
|
||||
assert(IS_SERVER_THREAD);
|
||||
|
||||
assert(!m_socketTCP);
|
||||
m_socketTCP = std::make_shared<boost::asio::ip::tcp::socket>(m_ioContext);
|
||||
m_socketTCP = std::make_unique<boost::asio::ip::tcp::socket>(m_ioContext);
|
||||
|
||||
m_acceptor.async_accept(*m_socketTCP,
|
||||
[this](boost::system::error_code ec)
|
||||
@ -208,19 +208,23 @@ void Server::doAccept()
|
||||
if(!ec)
|
||||
{
|
||||
EventLoop::call(
|
||||
[this, socket=std::move(m_socketTCP)]()
|
||||
[this]()
|
||||
{
|
||||
try
|
||||
{
|
||||
m_connections.emplace_back(std::make_shared<Connection>(*this, std::move(*socket)));
|
||||
m_connections.emplace_back(std::make_shared<Connection>(*this, std::move(m_socketTCP)));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
Log::log(id, LogMessage::C1002_CREATING_CONNECTION_FAILED_X, e.what());
|
||||
}
|
||||
});
|
||||
|
||||
doAccept();
|
||||
m_ioContext.post(
|
||||
[this]()
|
||||
{
|
||||
doAccept();
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -42,7 +42,7 @@ class Server : public std::enable_shared_from_this<Server>
|
||||
boost::asio::io_context m_ioContext;
|
||||
std::thread m_thread;
|
||||
boost::asio::ip::tcp::acceptor m_acceptor;
|
||||
std::shared_ptr<boost::asio::ip::tcp::socket> m_socketTCP;
|
||||
std::unique_ptr<boost::asio::ip::tcp::socket> m_socketTCP;
|
||||
boost::asio::ip::udp::socket m_socketUDP;
|
||||
std::array<char, 8> m_udpBuffer;
|
||||
boost::asio::ip::udp::endpoint m_remoteEndpoint;
|
||||
|
||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren