This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

215 lines
8.0 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef VMPI_H
#define VMPI_H
#ifdef _WIN32
#pragma once
#endif
#include "iphelpers.h"
#include "messbuf.h"
#include "vmpi_defs.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
// 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);
// 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();
#endif // VMPI_H