There is a potential data race when writeToOutputBuffer (and by extension methods like sendStoreBalance) is called directly from the network thread. The output buffer is only safe to access from the dispatcher thread, and calling it from the network thread can lead to race conditions and corrupted msgs.
void ProtocolGame::parseMarketCancelOffer(NetworkMessage& msg)
{
uint32_t timestamp = msg.get<uint32_t>();
uint16_t counter = msg.get<uint16_t>();
g_dispatcher.addTask(
[=, playerID = player->getID()]() {
g_game.playerCancelMarketOffer(playerID, timestamp, counter);
});
// ❌ This is called from the network thread
// It writes to the output buffer directly
sendStoreBalance();
}
g_dispatcher.addTask(
[=, playerID = player->getID(), self = shared_from_this()]() {
g_game.playerCancelMarketOffer(playerID, timestamp, counter);
self->sendStoreBalance(); // ✅ Now, called in dispatcher thread
});
}
There is a potential data race when
writeToOutputBuffer(and by extension methods likesendStoreBalance) is called directly from the network thread. The output buffer is only safe to access from the dispatcher thread, and calling it from the network thread can lead to race conditions and corrupted msgs.g_dispatcher.addTask( [=, playerID = player->getID(), self = shared_from_this()]() { g_game.playerCancelMarketOffer(playerID, timestamp, counter); self->sendStoreBalance(); // ✅ Now, called in dispatcher thread }); }