diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/vmpi/testapps/socket_stresstest/socket_stresstest.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/vmpi/testapps/socket_stresstest/socket_stresstest.cpp')
| -rw-r--r-- | utils/vmpi/testapps/socket_stresstest/socket_stresstest.cpp | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/utils/vmpi/testapps/socket_stresstest/socket_stresstest.cpp b/utils/vmpi/testapps/socket_stresstest/socket_stresstest.cpp new file mode 100644 index 0000000..55ab97d --- /dev/null +++ b/utils/vmpi/testapps/socket_stresstest/socket_stresstest.cpp @@ -0,0 +1,274 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// socket_stresstest.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include "utllinkedlist.h" + + +class CSocketInfo +{ +public: + + bool IsValid() + { + return m_pSocket != 0; + } + + void Term(); + + void ThreadFn(); + + + +public: + ITCPSocket *m_pSocket; + int m_iListenPort; + + DWORD m_CreateTime; // When this socket was created. + DWORD m_ExpireTime; +}; + + + +CSocketInfo g_Infos[132]; +CRITICAL_SECTION g_CS, g_PrintCS; +HANDLE g_hThreads[ ARRAYSIZE( g_Infos ) ]; +bool g_bShouldExit = false; +CUtlLinkedList<int,int> g_ListenPorts; + + +SpewRetval_t StressTestSpew( SpewType_t type, char const *pMsg ) +{ + EnterCriticalSection( &g_PrintCS ); + printf( "%s", pMsg ); + LeaveCriticalSection( &g_PrintCS ); + + if( type == SPEW_ASSERT ) + return SPEW_DEBUGGER; + else if( type == SPEW_ERROR ) + return SPEW_ABORT; + else + return SPEW_CONTINUE; +} + + +void CSocketInfo::Term() +{ + if ( m_pSocket ) + { + m_pSocket->Release(); + m_pSocket = 0; + } +} + + +CSocketInfo* FindOldestSocketInfo( CSocketInfo *pInfos, int nInfos ) +{ + int iOldest = 0; + DWORD oldestTime = 0xFFFFFFFF; + for ( int i=0; i < nInfos; i++ ) + { + if ( !pInfos[i].IsValid() ) + return &pInfos[i]; + + if ( pInfos[i].m_CreateTime < oldestTime ) + { + oldestTime = pInfos[i].m_CreateTime; + iOldest = i; + } + } + return &pInfos[iOldest]; +} + + +int g_iNextExpire = -1; + +void CSocketInfo::ThreadFn() +{ + int iInfo = this - g_Infos; + + while ( !g_bShouldExit ) + { + DWORD curTime = GetTickCount(); + + // Break the connection after a certain amount of time. + if ( m_pSocket && curTime >= m_ExpireTime ) + { + Term(); + Msg( "%02d: expire.\n", iInfo, m_iListenPort ); + } + + if ( m_pSocket ) + { + EnterCriticalSection( &g_CS ); + if ( g_iNextExpire == -1 ) + { + g_iNextExpire = iInfo; + LeaveCriticalSection( &g_CS ); + + Msg( "%02d: forcing an expire.\n", iInfo, m_iListenPort ); + Sleep( 16000 ); + + EnterCriticalSection( &g_CS ); + g_iNextExpire = -1; + } + LeaveCriticalSection( &g_CS ); + + if ( m_pSocket->IsConnected() ) + { + // Receive whatever data it has waiting for it. + CUtlVector<unsigned char> data; + while ( m_pSocket->Recv( data ) ) + { + Msg( "%02d: recv %d.\n", iInfo, data.Count() ); + } + + // Send some data. + int size = rand() % 8192; + data.SetSize( size ); + m_pSocket->Send( data.Base(), data.Count() ); + //Msg( "%02d: send %d.\n", iInfo, data.Count() ); + } + else + { + Term(); + } + } + else + { + // Not initialized.. either listen or connect. + int iConnectPort = -1; + if ( rand() > VALVE_RAND_MAX/2 ) + { + if ( rand() % 100 < 50 ) + Sleep( 500 ); + + EnterCriticalSection( &g_CS ); + int iHead = g_ListenPorts.Head(); + if ( iHead != g_ListenPorts.InvalidIndex() ) + iConnectPort = g_ListenPorts[iHead]; + LeaveCriticalSection( &g_CS ); + } + + if ( iConnectPort != -1 ) + { + CIPAddr addr( 127, 0, 0, 1, iConnectPort ); + + m_pSocket = CreateTCPSocket(); + m_pSocket->BindToAny( 0 ); + m_CreateTime = curTime; + m_ExpireTime = curTime + rand() % 5000; + if ( !TCPSocket_Connect( m_pSocket, &addr, 3.0f ) ) + { + Term(); + } + } + else + { + for ( int iTry=0; iTry < 32; iTry++ ) + { + m_iListenPort = 100 + rand() % (VALVE_RAND_MAX/2); + ITCPListenSocket *pListenSocket = CreateTCPListenSocket( m_iListenPort ); + if ( pListenSocket ) + { + Msg( "%02d: listen on %d.\n", iInfo, m_iListenPort ); + + // Add us to the list of ports to connect to. + EnterCriticalSection( &g_CS ); + g_ListenPorts.AddToTail( m_iListenPort ); + LeaveCriticalSection( &g_CS ); + + // Listen for a connection. + CIPAddr connectedAddr; + m_pSocket = TCPSocket_ListenForOneConnection( pListenSocket, &connectedAddr, 4.0 ); + + // Remove us from the list of ports to connect to. + EnterCriticalSection( &g_CS ); + g_ListenPorts.Remove( g_ListenPorts.Find( m_iListenPort ) ); + LeaveCriticalSection( &g_CS ); + + pListenSocket->Release(); + + if ( m_pSocket ) + { + Msg( "%02d: listen found connection.\n", iInfo ); + m_CreateTime = curTime; + m_ExpireTime = curTime + rand() % 5000; + } + break; + } + } + } + } + + Sleep( 1 ); + } + + g_hThreads[iInfo] = 0; +} + + +DWORD WINAPI ThreadFn( LPVOID lpParameter ) +{ + CSocketInfo *pInfo = (CSocketInfo*)lpParameter; + pInfo->ThreadFn(); + return 0; +} + + +void AllocError( unsigned long size ) +{ + Assert( false ); +} + + +int main(int argc, char* argv[]) +{ + memset( g_Infos, 0, sizeof( g_Infos ) ); + memset( g_hThreads, 0, sizeof( g_hThreads ) ); + + InitializeCriticalSection( &g_CS ); + InitializeCriticalSection( &g_PrintCS ); + + SpewOutputFunc( StressTestSpew ); + Plat_SetAllocErrorFn( AllocError ); + + SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS ); + + for ( int i=0; i < ARRAYSIZE( g_Infos ); i++ ) + { + DWORD dwThreadID = 0; + g_hThreads[i] = CreateThread( + NULL, + 0, + ThreadFn, + &g_Infos[i], + 0, + &dwThreadID ); + } + + + while ( !kbhit() ) + { + } + + g_bShouldExit = true; + + HANDLE hZeroArray[ ARRAYSIZE( g_Infos ) ]; + memset( hZeroArray, 0, sizeof( hZeroArray ) ); + + while ( memcmp( hZeroArray, g_hThreads, sizeof( hZeroArray ) ) != 0 ) + { + Sleep( 10 ); + } + + return 0; +} + |