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);
_packets_sent++;
_last_send_time = Platform::GetCurrentTimeMS();
_bytes_sent += msg->PacketSize();
{
std::lock_guard<std::mutex> lock(_send_mutex);
_packets_sent++;
_last_send_time = Platform::GetCurrentTimeMS();
_bytes_sent += msg->PacketSize();
msg->hdr.magic = _magic_number;
msg->hdr.sequence_number = _next_send_seq++;
msg->hdr.magic = _magic_number;
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();
}
@ -753,6 +756,7 @@ UdpProtocol::SetDisconnectNotifyStart(int timeout)
void
UdpProtocol::PumpSendQueue()
{
std::lock_guard<std::mutex> lock(_send_mutex);
while (!_send_queue.empty()) {
QueueEntry &entry = _send_queue.front();
@ -793,6 +797,7 @@ UdpProtocol::PumpSendQueue()
void
UdpProtocol::ClearSendQueue()
{
std::lock_guard<std::mutex> lock(_send_mutex);
while (!_send_queue.empty()) {
delete _send_queue.front().msg;
_send_queue.pop();

View File

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

View File

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

View File

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