Fix P2P scheduling bug related to processing timeouts and anti-flap checking.

CSteamNetworkConnectionP2P was scheduleing a wakeup call EXACTLY at the same
time as the timeout.  But it was not actually responsible for processing the
timeout, the transport does that.  The transport did properly have a method
scheduled to deal with it -- but they were both using the same wake up time.
So the connection kept waking up first, and scheduling the same wake up time
as the transport, and then winning the tie, repeatedly.  The fix is to make
sure that we wake up *just* after the transport has dealt with the timeout.

It's possible that the thinker system could deal with these sorts of cycles
better, but I'd rather avoid adding that complication until I find a problem
that doesn't have a simple solution like this.

P4:6653586
This commit is contained in:
Fletcher Dunn
2021-07-06 15:35:35 -07:00
parent c76bd36be5
commit e5e8052485
2 changed files with 8 additions and 1 deletions
@@ -1417,7 +1417,12 @@ void CSteamNetworkConnectionP2P::ThinkSelectTransport( SteamNetworkingMicrosecon
} \
else if ( pTransport->m_usecEndToEndInFlightReplyTimeout > 0 ) \
{ \
m_usecNextEvaluateTransport = std::min( m_usecNextEvaluateTransport, pTransport->m_usecEndToEndInFlightReplyTimeout ); \
/* The transport *should* be scheduled to deal with the timeout */ \
Assert( pTransport->GetP2PTransportThinkScheduleTime() <= pTransport->m_usecEndToEndInFlightReplyTimeout ); \
/* In case not, use the max so we don't wake up and try to deal with it before it has taken care of it and get into a loop */ \
SteamNetworkingMicroseconds usecAfterTimeOut = std::max( pTransport->GetP2PTransportThinkScheduleTime(), pTransport->m_usecEndToEndInFlightReplyTimeout ); \
++usecAfterTimeOut; /* because we need to make sure we do our processing AFTER the transport has had a chance to deal with the timeout */ \
m_usecNextEvaluateTransport = std::min( m_usecNextEvaluateTransport, usecAfterTimeOut ); \
} \
else \
{ \
@@ -163,6 +163,8 @@ public:
bool TryLock() { return m_pSelfAsConnectionTransport->m_connection.TryLock(); }
void Unlock() const { return m_pSelfAsConnectionTransport->m_connection.Unlock(); }
inline SteamNetworkingMicroseconds GetP2PTransportThinkScheduleTime() const { return m_scheduleP2PTransportThink.GetScheduleTime(); }
protected:
CConnectionTransportP2PBase( const char *pszDebugName, CConnectionTransport *pSelfBase );
virtual ~CConnectionTransportP2PBase();