2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -04:00

Implement Game auto pinger

Evidently, the game connection never actually pinged. Instead, it relied
on the propagation of a redundant game message. This is evil because we
can sometimes hang out in the loading process for quite some time (eg
beyond the socket timeout on either end)
This commit is contained in:
2012-02-25 22:33:55 -05:00
parent 16a30950de
commit dc85bd6f86

View File

@ -74,6 +74,11 @@ struct CliGmConn : AtomicRef {
CliGmConn (); CliGmConn ();
~CliGmConn (); ~CliGmConn ();
// ping
void AutoPing ();
void StopAutoPing ();
void TimerPing ();
void Send (const uintptr_t fields[], unsigned count); void Send (const uintptr_t fields[], unsigned count);
}; };
@ -207,6 +212,8 @@ static void UnlinkAndAbandonConn_CS (CliGmConn * conn) {
//============================================================================ //============================================================================
static bool ConnEncrypt (ENetError error, void * param) { static bool ConnEncrypt (ENetError error, void * param) {
CliGmConn * conn = (CliGmConn *) param; CliGmConn * conn = (CliGmConn *) param;
if (!s_perf[kPingDisabled])
conn->AutoPing();
if (IS_NET_SUCCESS(error)) { if (IS_NET_SUCCESS(error)) {
s_critsect.Enter(); s_critsect.Enter();
@ -262,6 +269,7 @@ static void NotifyConnSocketConnectFailed (CliGmConn * conn) {
//============================================================================ //============================================================================
static void NotifyConnSocketDisconnect (CliGmConn * conn) { static void NotifyConnSocketDisconnect (CliGmConn * conn) {
conn->StopAutoPing();
bool notify; bool notify;
s_critsect.Enter(); s_critsect.Enter();
@ -392,6 +400,19 @@ static void Connect (
* *
***/ ***/
//===========================================================================
static unsigned CliGmConnTimerDestroyed (void * param) {
CliGmConn * conn = (CliGmConn *) param;
conn->DecRef("TimerDestroyed");
return kAsyncTimeInfinite;
}
//===========================================================================
static unsigned CliGmConnPingTimerProc (void * param) {
((CliGmConn *) param)->TimerPing();
return kPingIntervalMs;
}
//============================================================================ //============================================================================
CliGmConn::CliGmConn () { CliGmConn::CliGmConn () {
AtomicAdd(&s_perf[kPerfConnCount], 1); AtomicAdd(&s_perf[kPerfConnCount], 1);
@ -404,6 +425,59 @@ CliGmConn::~CliGmConn () {
AtomicAdd(&s_perf[kPerfConnCount], -1); AtomicAdd(&s_perf[kPerfConnCount], -1);
} }
//============================================================================
void CliGmConn::AutoPing () {
ASSERT(!pingTimer);
IncRef("PingTimer");
critsect.Enter();
{
AsyncTimerCreate(
&pingTimer,
CliGmConnPingTimerProc,
sock ? 0 : kAsyncTimeInfinite,
this
);
}
critsect.Leave();
}
//============================================================================
void CliGmConn::StopAutoPing () {
critsect.Enter();
{
if (AsyncTimer * timer = pingTimer) {
pingTimer = nil;
AsyncTimerDeleteCallback(timer, CliGmConnTimerDestroyed);
}
}
critsect.Leave();
}
//============================================================================
void CliGmConn::TimerPing () {
#if 0
// if the time difference between when we last sent a ping and when we last
// heard from the server is >= 3x the ping interval, the socket is stale.
if (pingSendTimeMs && abs(int(pingSendTimeMs - lastHeardTimeMs)) >= kPingTimeoutMs) {
// ping timed out, disconnect the socket
AsyncSocketDisconnect(sock, true);
}
else
#endif
{
// Send a ping request
pingSendTimeMs = GetNonZeroTimeMs();
const uintptr_t msg[] = {
kCli2Game_PingRequest,
pingSendTimeMs
};
Send(msg, arrsize(msg));
}
}
//============================================================================ //============================================================================
void CliGmConn::Send (const uintptr_t fields[], unsigned count) { void CliGmConn::Send (const uintptr_t fields[], unsigned count) {
critsect.Enter(); critsect.Enter();
@ -710,6 +784,17 @@ unsigned GameGetConnId () {
//============================================================================ //============================================================================
void GamePingEnable (bool enable) { void GamePingEnable (bool enable) {
s_perf[kPingDisabled] = !enable; s_perf[kPingDisabled] = !enable;
s_critsect.Enter();
for (;;) {
if (!s_active)
break;
if (enable)
s_active->AutoPing();
else
s_active->StopAutoPing();
break;
}
s_critsect.Leave();
} }
} using namespace Ngl; } using namespace Ngl;