|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef VMPI_H
#define VMPI_H
#ifdef _WIN32
#pragma once
#endif
#include "vmpi_defs.h"
#include "messbuf.h"
#include "iphelpers.h"
// These are called to handle incoming messages.
// Return true if you handled the message and false otherwise.
// Note: the first byte in each message is the packet ID.
typedef bool (*VMPIDispatchFn)( MessageBuffer *pBuf, int iSource, int iPacketID );
typedef void (*VMPI_Disconnect_Handler)( int procID, const char *pReason );
// Which machine is the master.
#define VMPI_MASTER_ID 0
#define VMPI_SEND_TO_ALL -2
#define VMPI_PERSISTENT -3 // If this is set as the destination for a packet, it is sent to all
// workers, and also to new workers that connect.
#define MAX_VMPI_PACKET_IDS 32
#define VMPI_TIMEOUT_INFINITE 0xFFFFFFFF
#define VMPI_PACKET_SIZE 768
// Instantiate one of these to register a dispatch.
class CDispatchReg { public: CDispatchReg( int iPacketID, VMPIDispatchFn fn ); };
// Enums for all the command line parameters.
#define VMPI_PARAM_SDK_HIDDEN 0x0001 // Hidden in SDK mode.
#define VMPI_PARAM( paramName, paramFlags, helpText ) paramName,
enum EVMPICmdLineParam { k_eVMPICmdLineParam_FirstParam=0, k_eVMPICmdLineParam_VMPIParam, #include "vmpi_parameters.h"
k_eVMPICmdLineParam_LastParam }; #undef VMPI_PARAM
// Shared by all the tools.
extern bool g_bUseMPI; extern bool g_bMPIMaster; // Set to true if we're the master in a VMPI session.
extern int g_iVMPIVerboseLevel; // Higher numbers make it spit out more data.
extern bool g_bMPI_Stats; // Send stats to the MySQL database?
extern bool g_bMPI_StatsTextOutput; // Send text output in the stats?
// These can be watched or modified to check bandwidth statistics.
extern int g_nBytesSent; extern int g_nMessagesSent; extern int g_nBytesReceived; extern int g_nMessagesReceived;
extern int g_nMulticastBytesSent; extern int g_nMulticastBytesReceived;
extern int g_nMaxWorkerCount;
enum VMPIRunMode { VMPI_RUN_NETWORKED, VMPI_RUN_LOCAL // Just make a local process and have it do the work.
};
enum VMPIFileSystemMode { VMPI_FILESYSTEM_MULTICAST, // Multicast out, find workers, have them do work.
VMPI_FILESYSTEM_BROADCAST, // Broadcast out, find workers, have them do work.
VMPI_FILESYSTEM_TCP // TCP filesystem.
};
// If this precedes the dependency filename, then it will transfer all the files in the specified directory.
#define VMPI_DEPENDENCY_DIRECTORY_TOKEN '*'
// It's good to specify a disconnect handler here immediately. If you don't have a handler
// and the master disconnects, you'll lockup forever inside a dispatch loop because you
// never handled the master disconnecting.
//
// Note: runMode is only relevant for the VMPI master. The worker always connects to the master
// the same way.
bool VMPI_Init( int &argc, char **&argv, const char *pDependencyFilename, VMPI_Disconnect_Handler handler = NULL, VMPIRunMode runMode = VMPI_RUN_NETWORKED, // Networked or local?,
bool bConnectingAsService = false );
// Used when hosting a patch.
void VMPI_Init_PatchMaster( int argc, char **argv );
void VMPI_Finalize();
VMPIRunMode VMPI_GetRunMode(); VMPIFileSystemMode VMPI_GetFileSystemMode();
// Note: this number can change on the master.
int VMPI_GetCurrentNumberOfConnections();
// Dispatch messages until it gets one with the specified packet ID.
// If subPacketID is not set to -1, then the second byte must match that as well.
//
// Note: this WILL dispatch packets with matching packet IDs and give them a chance to handle packets first.
//
// If bWait is true, then this function either succeeds or Error() is called. If it's false, then if the first available message
// is handled by a dispatch, this function returns false.
bool VMPI_DispatchUntil( MessageBuffer *pBuf, int *pSource, int packetID, int subPacketID = -1, bool bWait = true );
// This waits for the next message and dispatches it.
// You can specify a timeout in milliseconds. If the timeout expires, the function returns false.
bool VMPI_DispatchNextMessage( unsigned long timeout=VMPI_TIMEOUT_INFINITE );
// This should be called periodically in modal loops that don't call other VMPI functions. This will
// check for disconnected sockets and call disconnect handlers so the app can error out if
// it loses all of its connections.
//
// This can be used in place of a Sleep() call by specifying a timeout value.
void VMPI_HandleSocketErrors( unsigned long timeout=0 );
enum VMPISendFlags { k_eVMPISendFlags_GroupPackets = 0x0001 }; // Use these to send data to one of the machines.
// If iDest is VMPI_SEND_TO_ALL, then the message goes to all the machines.
// Flags is a combination of the VMPISendFlags enums.
bool VMPI_SendData( void *pData, int nBytes, int iDest, int fVMPISendFlags=0 ); bool VMPI_SendChunks( void const * const *pChunks, const int *pChunkLengths, int nChunks, int iDest, int fVMPISendFlags=0 ); bool VMPI_Send2Chunks( const void *pChunk1, int chunk1Len, const void *pChunk2, int chunk2Len, int iDest, int fVMPISendFlags=0 ); // for convenience..
bool VMPI_Send3Chunks( const void *pChunk1, int chunk1Len, const void *pChunk2, int chunk2Len, const void *pChunk3, int chunk3Len, int iDest, int fVMPISendFlags=0 );
// Flush any groups that were queued with k_eVMPISendFlags_GroupPackets.
// If msInterval is > 0, then it will check a timer and only flush that often (so you can call this a lot, and have it check).
void VMPI_FlushGroupedPackets( unsigned long msInterval=0 );
// This registers a function that gets called when a connection is terminated ungracefully.
void VMPI_AddDisconnectHandler( VMPI_Disconnect_Handler handler );
// is this a valid process
bool VMPI_IsProcValid( int procID );
// Returns false if the process has disconnected ungracefully (disconnect handlers
// would have been called for it too).
bool VMPI_IsProcConnected( int procID );
// Returns true if the process is just a service (in which case it should only get file IO traffic).
bool VMPI_IsProcAService( int procID );
// Simple wrapper for Sleep() so people can avoid including windows.h
void VMPI_Sleep( unsigned long ms );
// VMPI sends machine names around first thing.
const char* VMPI_GetLocalMachineName(); const char* VMPI_GetMachineName( int iProc ); bool VMPI_HasMachineNameBeenSet( int iProc );
// Returns 0xFFFFFFFF if the ID hasn't been set.
unsigned long VMPI_GetJobWorkerID( int iProc ); void VMPI_SetJobWorkerID( int iProc, unsigned long jobWorkerID );
// Search a command line to find arguments. Looks for pName, and if it finds it, returns the
// argument following it. If pName is the last argument, it returns pDefault. If it doesn't
// find pName, returns NULL.
const char* VMPI_FindArg( int argc, char **argv, const char *pName, const char *pDefault = "" );
// (Threadsafe) get and set the current stage. This info winds up in the VMPI database.
void VMPI_GetCurrentStage( char *pOut, int strLen ); void VMPI_SetCurrentStage( const char *pCurStage );
// VMPI is always broadcasting this job in the background.
// This changes the password to 'debugworker' and allows more workers in.
// This can be used if workers are dying on certain work units. Then a programmer
// can run vmpi_service with -superdebug and debug the whole thing.
void VMPI_InviteDebugWorkers();
bool VMPI_IsSDKMode();
// Lookup a command line parameter string.
const char* VMPI_GetParamString( EVMPICmdLineParam eParam ); int VMPI_GetParamFlags( EVMPICmdLineParam eParam ); const char* VMPI_GetParamHelpString( EVMPICmdLineParam eParam ); bool VMPI_IsParamUsed( EVMPICmdLineParam eParam ); // Returns true if the specified parameter is on the command line.
// Can be called from error handlers and if -mpi_Restart is used, it'll automatically restart the process.
bool VMPI_HandleAutoRestart();
// These are optional debug helpers. When VMPI_SuperSpew is enabled, VMPI can spit out messages
// with strings for packet IDs instead of numbers.
#define VMPI_REGISTER_PACKET_ID( idDefine ) static CVMPIPacketIDReg g_VMPIPacketIDReg_##idDefine( idDefine, -1, #idDefine );
#define VMPI_REGISTER_SUBPACKET_ID( idPacketIDDefine, idSubPacketIDDefine ) static CVMPIPacketIDReg g_VMPISubPacketIDReg_##idSubPacketIDDefine( idPacketIDDefine, idSubPacketIDDefine, #idSubPacketIDDefine );
class CVMPIPacketIDReg { public: CVMPIPacketIDReg( int nPacketID, int nSubPacketID, const char *pName );
static void Lookup( int nPacketID, int nSubPacketID, char *pPacketIDString, int nPacketIDStringSize, char *pSubPacketIDString, int nSubPacketIDStringSize );
private: int m_nPacketID; int m_nSubPacketID; const char *m_pName; CVMPIPacketIDReg *m_pNext; };
#endif // VMPI_H
|