diff options
Diffstat (limited to 'utils/vmpi/testapps/socket_stresstest')
4 files changed, 532 insertions, 0 deletions
diff --git a/utils/vmpi/testapps/socket_stresstest/StdAfx.cpp b/utils/vmpi/testapps/socket_stresstest/StdAfx.cpp new file mode 100644 index 0000000..2b565b0 --- /dev/null +++ b/utils/vmpi/testapps/socket_stresstest/StdAfx.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.cpp : source file that includes just the standard includes +// socket_stresstest.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/utils/vmpi/testapps/socket_stresstest/StdAfx.h b/utils/vmpi/testapps/socket_stresstest/StdAfx.h new file mode 100644 index 0000000..3c554be --- /dev/null +++ b/utils/vmpi/testapps/socket_stresstest/StdAfx.h @@ -0,0 +1,33 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__7E382B26_1CB4_461A_8087_762358153941__INCLUDED_) +#define AFX_STDAFX_H__7E382B26_1CB4_461A_8087_762358153941__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include <windows.h> +#include <stdio.h> +#include "tcpsocket.h" +#include <conio.h> +#include <stdlib.h> + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__7E382B26_1CB4_461A_8087_762358153941__INCLUDED_) 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; +} + diff --git a/utils/vmpi/testapps/socket_stresstest/socket_stresstest.vcproj b/utils/vmpi/testapps/socket_stresstest/socket_stresstest.vcproj new file mode 100644 index 0000000..89b144e --- /dev/null +++ b/utils/vmpi/testapps/socket_stresstest/socket_stresstest.vcproj @@ -0,0 +1,210 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="socket_stresstest" + ProjectGUID="{46DE8944-1A71-4A43-98FE-7A96CB8E5596}" + SccProjectName="" + SccAuxPath="" + SccLocalPath="" + SccProvider=""> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory=".\Debug" + IntermediateDirectory=".\Debug" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..,..\..\common,..\..\..\public,..\..\..\public\tier1" + PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;PROTECTED_THINGS_DISABLE" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + PrecompiledHeaderFile=".\Debug/socket_stresstest.pch" + AssemblerListingLocation=".\Debug/" + ObjectFile=".\Debug/" + ProgramDataBaseFileName=".\Debug/" + WarningLevel="3" + SuppressStartupBanner="TRUE" + DebugInformationFormat="4" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib" + OutputFile=".\Debug/socket_stresstest.exe" + LinkIncremental="1" + SuppressStartupBanner="TRUE" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile=".\Debug/socket_stresstest.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\Debug/socket_stresstest.tlb" + HeaderFileName=""/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory=".\Release" + IntermediateDirectory=".\Release" + ConfigurationType="1" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="FALSE" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="1" + AdditionalIncludeDirectories="..,..\..\common,..\..\..\public,..\..\..\public\tier1" + PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;PROTECTED_THINGS_DISABLE" + StringPooling="TRUE" + RuntimeLibrary="0" + EnableFunctionLevelLinking="TRUE" + PrecompiledHeaderFile=".\Release/socket_stresstest.pch" + AssemblerListingLocation=".\Release/" + ObjectFile=".\Release/" + ProgramDataBaseFileName=".\Release/" + WarningLevel="3" + SuppressStartupBanner="TRUE" + CompileAs="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="ws2_32.lib odbc32.lib odbccp32.lib" + OutputFile=".\Release/socket_stresstest.exe" + LinkIncremental="1" + SuppressStartupBanner="TRUE" + ProgramDatabaseFile=".\Release/socket_stresstest.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool" + TypeLibraryName=".\Release/socket_stresstest.tlb" + HeaderFileName=""/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG" + Culture="1033"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"> + <File + RelativePath="..\iphelpers.cpp"> + </File> + <File + RelativePath="socket_stresstest.cpp"> + </File> + <File + RelativePath="StdAfx.cpp"> + </File> + <File + RelativePath="..\tcpsocket.cpp"> + </File> + <File + RelativePath="..\threadhelpers.cpp"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl"> + <File + RelativePath="StdAfx.h"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"> + </Filter> + <File + RelativePath="ReadMe.txt"> + </File> + <File + RelativePath="..\..\..\lib\public\tier0.lib"> + <FileConfiguration + Name="Debug|Win32"> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine=""/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32"> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine=""/> + </FileConfiguration> + </File> + <File + RelativePath="..\..\..\lib\public\vstdlib.lib"> + <FileConfiguration + Name="Debug|Win32"> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine=""/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32"> + <Tool + Name="VCCustomBuildTool" + Description="" + CommandLine=""/> + </FileConfiguration> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> |