ggpo: make chat thread-safe. Deadlock on early rollback

Make ggpo_send_message() thread-safe
Deadlock UI/emu threads if rollback happens before first render
Disable rollback wait in single-thread mode
This commit is contained in:
Flyinghead 2021-10-20 14:41:18 +02:00
parent 6d8e1794a0
commit 808a161d39
4 changed files with 17 additions and 7 deletions

View File

@ -286,14 +286,17 @@ UdpProtocol::SendMsg(UdpMsg *msg)
{ {
LogMsg("send", msg); LogMsg("send", msg);
_packets_sent++; {
_last_send_time = Platform::GetCurrentTimeMS(); std::lock_guard<std::mutex> lock(_send_mutex);
_bytes_sent += msg->PacketSize(); _packets_sent++;
_last_send_time = Platform::GetCurrentTimeMS();
_bytes_sent += msg->PacketSize();
msg->hdr.magic = _magic_number; msg->hdr.magic = _magic_number;
msg->hdr.sequence_number = _next_send_seq++; msg->hdr.sequence_number = _next_send_seq++;
_send_queue.push(QueueEntry(Platform::GetCurrentTimeMS(), _peer_addr, msg)); _send_queue.push(QueueEntry(Platform::GetCurrentTimeMS(), _peer_addr, msg));
}
PumpSendQueue(); PumpSendQueue();
} }
@ -753,6 +756,7 @@ UdpProtocol::SetDisconnectNotifyStart(int timeout)
void void
UdpProtocol::PumpSendQueue() UdpProtocol::PumpSendQueue()
{ {
std::lock_guard<std::mutex> lock(_send_mutex);
while (!_send_queue.empty()) { while (!_send_queue.empty()) {
QueueEntry &entry = _send_queue.front(); QueueEntry &entry = _send_queue.front();
@ -793,6 +797,7 @@ UdpProtocol::PumpSendQueue()
void void
UdpProtocol::ClearSendQueue() UdpProtocol::ClearSendQueue()
{ {
std::lock_guard<std::mutex> lock(_send_mutex);
while (!_send_queue.empty()) { while (!_send_queue.empty()) {
delete _send_queue.front().msg; delete _send_queue.front().msg;
_send_queue.pop(); _send_queue.pop();

View File

@ -16,6 +16,7 @@
#include "ggponet.h" #include "ggponet.h"
#include "ring_buffer.h" #include "ring_buffer.h"
#include <vector> #include <vector>
#include <mutex>
class UdpProtocol : public IPollSink class UdpProtocol : public IPollSink
{ {
@ -153,6 +154,7 @@ protected:
UdpMsg* msg; UdpMsg* msg;
} _oo_packet; } _oo_packet;
RingBuffer<QueueEntry, 64> _send_queue; RingBuffer<QueueEntry, 64> _send_queue;
std::mutex _send_mutex;
std::vector<uint8> verification; std::vector<uint8> verification;

View File

@ -466,7 +466,8 @@ void rend_allow_rollback()
void rend_start_rollback() void rend_start_rollback()
{ {
vramRollback.Wait(); if (config::ThreadedRendering)
vramRollback.Wait();
} }
void rend_serialize(void **data, unsigned int *total_size) void rend_serialize(void **data, unsigned int *total_size)

View File

@ -159,6 +159,7 @@ struct Inputs
u8 keys[6]; u8 keys[6];
} u; } u;
}; };
static_assert(sizeof(Inputs) == 10, "wrong Inputs size");
struct GameEvent struct GameEvent
{ {
@ -183,6 +184,7 @@ struct GameEvent
static bool begin_game(const char *) static bool begin_game(const char *)
{ {
DEBUG_LOG(NETWORK, "Game begin"); DEBUG_LOG(NETWORK, "Game begin");
rend_allow_rollback();
return true; return true;
} }