1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Merge pull request #3981 from IvanSavenko/asio_fix

Simple workaround to fix vcmiserver shutdown procedure
This commit is contained in:
Ivan Savenko 2024-05-15 00:14:14 +03:00 committed by GitHub
commit ced21f0837
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 8 deletions

View File

@ -127,6 +127,11 @@ void NetworkConnection::onPacketReceived(const boost::system::error_code & ec, u
startReceiving();
}
void NetworkConnection::setAsyncWritesEnabled(bool on)
{
asyncWritesEnabled = on;
}
void NetworkConnection::sendPacket(const std::vector<std::byte> & message)
{
std::lock_guard<std::mutex> lock(writeMutex);
@ -134,14 +139,27 @@ void NetworkConnection::sendPacket(const std::vector<std::byte> & message)
uint32_t messageSize = message.size();
std::memcpy(headerVector.data(), &messageSize, sizeof(uint32_t));
bool messageQueueEmpty = dataToSend.empty();
dataToSend.push_back(headerVector);
if (message.size() > 0)
dataToSend.push_back(message);
// At the moment, vcmilobby *requires* async writes in order to handle multiple connections with different speeds and at optimal performance
// However server (and potentially - client) can not handle this mode and may shutdown either socket or entire asio service too early, before all writes are performed
if (asyncWritesEnabled)
{
if (messageQueueEmpty)
doSendData();
//else - data sending loop is still active and still sending previous messages
bool messageQueueEmpty = dataToSend.empty();
dataToSend.push_back(headerVector);
if (message.size() > 0)
dataToSend.push_back(message);
if (messageQueueEmpty)
doSendData();
//else - data sending loop is still active and still sending previous messages
}
else
{
boost::system::error_code ec;
boost::asio::write(*socket, boost::asio::buffer(headerVector), ec );
if (message.size() > 0)
boost::asio::write(*socket, boost::asio::buffer(message), ec );
}
}
void NetworkConnection::doSendData()

View File

@ -13,7 +13,7 @@
VCMI_LIB_NAMESPACE_BEGIN
class NetworkConnection : public INetworkConnection, public std::enable_shared_from_this<NetworkConnection>
class NetworkConnection final : public INetworkConnection, public std::enable_shared_from_this<NetworkConnection>
{
static const int messageHeaderSize = sizeof(uint32_t);
static const int messageMaxSize = 64 * 1024 * 1024; // arbitrary size to prevent potential massive allocation if we receive garbage input
@ -25,6 +25,7 @@ class NetworkConnection : public INetworkConnection, public std::enable_shared_f
NetworkBuffer readBuffer;
INetworkConnectionListener & listener;
bool asyncWritesEnabled = false;
void heartbeat();
void onError(const std::string & message);
@ -42,6 +43,7 @@ public:
void start();
void close() override;
void sendPacket(const std::vector<std::byte> & message) override;
void setAsyncWritesEnabled(bool on) override;
};
VCMI_LIB_NAMESPACE_END

View File

@ -17,6 +17,7 @@ class DLL_LINKAGE INetworkConnection : boost::noncopyable
public:
virtual ~INetworkConnection() = default;
virtual void sendPacket(const std::vector<std::byte> & message) = 0;
virtual void setAsyncWritesEnabled(bool on) = 0;
virtual void close() = 0;
};

View File

@ -292,6 +292,7 @@ void LobbyServer::sendChatMessage(const NetworkConnectionPtr & target, const std
void LobbyServer::onNewConnection(const NetworkConnectionPtr & connection)
{
connection->setAsyncWritesEnabled(true);
// no-op - waiting for incoming data
}