From 80254b6d509140c85ac5e1968a4126c19b2a3cbc Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Fri, 19 Feb 2021 13:28:59 -0800 Subject: [PATCH] Refactor IRawUDPSocket. Use virtual functions, don't cast. If it can't be inlined, a virtual function is usually only *barely* more expensive than an ordinary function call. --- .../steamnetworkingsockets_lowlevel.cpp | 34 ++++++++++--------- .../steamnetworkingsockets_lowlevel.h | 8 ++--- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp index a6cc451..a9b3b28 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp @@ -667,6 +667,11 @@ public: WSAEVENT m_event = INVALID_HANDLE_VALUE; #endif + // Implements IRawUDPSocket + virtual bool BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t &adrTo ) const override final; + virtual bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const override final; + virtual void Close() override; + //// Send a packet, for really realz right now. (No checking for fake loss or lag.) inline bool BReallySendRawPacket( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const { @@ -959,7 +964,7 @@ void WakeSteamDatagramThread() #endif } -bool IRawUDPSocket::BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t &adrTo ) const +bool CRawUDPSocketImpl::BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t &adrTo ) const { iovec temp; temp.iov_len = cbPkt; @@ -967,7 +972,7 @@ bool IRawUDPSocket::BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t return BSendRawPacketGather( 1, &temp, adrTo ); } -bool IRawUDPSocket::BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const +bool CRawUDPSocketImpl::BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const { SteamNetworkingGlobalLock::AssertHeldByCurrentThread(); @@ -979,8 +984,6 @@ bool IRawUDPSocket::BSendRawPacketGather( int nChunks, const iovec *pChunks, con if ( RandomBoolWithOdds( g_Config_FakePacketLoss_Send.Get() ) ) return true; - const CRawUDPSocketImpl *self = static_cast( this ); - // Fake lag? int32 nPacketFakeLagTotal = g_Config_FakePacketLag_Send.Get(); @@ -995,37 +998,36 @@ bool IRawUDPSocket::BSendRawPacketGather( int nChunks, const iovec *pChunks, con { int32 nDupLag = nPacketFakeLagTotal + WeakRandomInt( 0, g_Config_FakePacketDup_TimeMax.Get() ); nDupLag = std::max( 1, nDupLag ); - s_packetLagQueue.LagPacket( true, self, adrTo, nDupLag, nChunks, pChunks ); + s_packetLagQueue.LagPacket( true, this, adrTo, nDupLag, nChunks, pChunks ); } // Lag the original packet? if ( nPacketFakeLagTotal > 0 ) { - s_packetLagQueue.LagPacket( true, self, adrTo, nPacketFakeLagTotal, nChunks, pChunks ); + s_packetLagQueue.LagPacket( true, this, adrTo, nPacketFakeLagTotal, nChunks, pChunks ); return true; } // Now really send it - return self->BReallySendRawPacket( nChunks, pChunks, adrTo ); + return BReallySendRawPacket( nChunks, pChunks, adrTo ); } -void IRawUDPSocket::Close() +void CRawUDPSocketImpl::Close() { SteamNetworkingGlobalLock::AssertHeldByCurrentThread( "IRawUDPSocket::Close" ); - CRawUDPSocketImpl *self = static_cast( this ); /// Clear the callback, to ensure that no further callbacks will be executed. /// This marks the socket as pending destruction. - Assert( self->m_callback.m_fnCallback ); - self->m_callback.m_fnCallback = nullptr; - Assert( self->m_socket != INVALID_SOCKET ); + Assert( m_callback.m_fnCallback ); + m_callback.m_fnCallback = nullptr; + Assert( m_socket != INVALID_SOCKET ); - DbgVerify( s_vecRawSockets.FindAndFastRemove( self ) ); - DbgVerify( !s_vecRawSocketsPendingDeletion.FindAndFastRemove( self ) ); - s_vecRawSocketsPendingDeletion.AddToTail( self ); + DbgVerify( s_vecRawSockets.FindAndFastRemove( this ) ); + DbgVerify( !s_vecRawSocketsPendingDeletion.FindAndFastRemove( this ) ); + s_vecRawSocketsPendingDeletion.AddToTail( this ); // Clean up lagged packets, if any - s_packetLagQueue.AboutToDestroySocket( self ); + s_packetLagQueue.AboutToDestroySocket( this ); // Make sure we don't delay doing this too long if ( s_bManualPollMode || ( s_pThreadSteamDatagram && s_pThreadSteamDatagram->get_id() != std::this_thread::get_id() ) ) diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h index a916255..6fcf4a7 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h @@ -78,7 +78,7 @@ public: /// Packets sent through this method are subject to fake loss (steamdatagram_fakepacketloss_send), /// lag (steamdatagram_fakepacketlag_send and steamdatagram_fakepacketreorder_send), and /// duplication (steamdatagram_fakepacketdup_send) - bool BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t &adrTo ) const; + virtual bool BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t &adrTo ) const = 0; inline bool BSendRawPacket( const void *pPkt, int cbPkt, const SteamNetworkingIPAddr &adrTo ) const { netadr_t netadrTo; @@ -87,7 +87,7 @@ public: } /// Gather-based send. Simulated lag, loss, etc are applied - bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const; + virtual bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const = 0; inline bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const SteamNetworkingIPAddr &adrTo ) const { netadr_t netadrTo; @@ -98,14 +98,14 @@ public: /// Logically close the socket. This might not actually close the socket IMMEDIATELY, /// there may be a slight delay. (On the order of a few milliseconds.) But you will not /// get any further callbacks. - void Close(); + virtual void Close() = 0; /// The local address we ended up binding to SteamNetworkingIPAddr m_boundAddr; protected: IRawUDPSocket(); - ~IRawUDPSocket(); + virtual ~IRawUDPSocket(); }; const int k_nAddressFamily_Auto = -1; // Will try to use IPv6 dual stack if possible. Falls back to IPv4 if necessary (and possible for your requested bind address)