Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

326 lines
8.6 KiB

  1. //================ Copyright (c) 1996-2009 Valve Corporation. All Rights Reserved. =================
  2. //
  3. //
  4. //
  5. //==================================================================================================
  6. #ifndef VWATCHCLIENT_H
  7. #define VWATCHCLIENT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "tier0/threadtools.h"
  12. #include "tier1/utlvector.h"
  13. #include "tier1/checksum_crc.h"
  14. #include "tier1/utlstring.h"
  15. class CSharedMemoryMgr;
  16. class CVWatchHeader;
  17. class IFileSystem;
  18. class CAppSignal;
  19. enum GetSnapshotStatus_t
  20. {
  21. GETSNAPSHOT_OK, // Got the snapshot.
  22. GETSNAPSHOT_NOTDONESCANNING, // The vwatch service is still scanning this tree.
  23. GETSNAPSHOT_ERROR
  24. };
  25. enum GetCRCStatus_t
  26. {
  27. GETCRC_GOT_CACHED, // This is the best case. We did a fast lookup and got a valid CRC.
  28. GETCRC_CALCULATED_AND_CACHED, // 2nd best. We had to calculate the CRC but vwatch was around so we cached the value.
  29. GETCRC_CALCULATED_AND_DIDNT_CACHE, // 3rd best. We got the CRC but no vwatch, so it's not cached for next time.
  30. GETCRC_FAIL // Fail.
  31. };
  32. enum StartWatchingDirStatus_t
  33. {
  34. STARTWATCHINGDIR_STARTED,
  35. STARTWATCHINGDIR_ALREADYWATCHING,
  36. STARTWATCHINGDIR_ERROR
  37. };
  38. class CVWatchStats
  39. {
  40. public:
  41. uint32 m_nFileEntriesCreated;
  42. uint32 m_nDirectoryEntriesCreated;
  43. uint64 m_nMemoryBytesUsed;
  44. uint64 m_nMemoryBytesLimit;
  45. // If this is true, then it has run out of memory and it's going to sit there and not scan anything
  46. // until CVWatchClient::SendRestartSignal() has been called.
  47. bool m_bHasRunOutOfMemory;
  48. // Some breakdown of how the memory is used.
  49. uint64 m_nWatchedFileBytes;
  50. uint64 m_nWatchedDirBytes;
  51. uint64 m_nWatchedDirLongNameBytes; // This is part of m_nWatchedDirBytes.
  52. uint32 m_nFilesIterated;
  53. uint32 m_nClientLocks; // # of times CVWatchClient has locked the shared memory buffer
  54. };
  55. // ------------------------------------------------------------------------------------------------ //
  56. // COffsetPtr is the most common type and convenient type of pointer used in shared memory.
  57. // It can be used between any two nonmoving structures (even if they're not in shared memory).
  58. // ------------------------------------------------------------------------------------------------ //
  59. template< class T >
  60. class COffsetPtr
  61. {
  62. public:
  63. COffsetPtr& operator=( T *p )
  64. {
  65. if ( p )
  66. m_nOffset = (char*)p - (char*)this;
  67. else
  68. m_nOffset = 0;
  69. return *this;
  70. }
  71. COffsetPtr& operator=( COffsetPtr<T> &p )
  72. {
  73. return ( *this = (T*)p );
  74. }
  75. T* operator->()
  76. {
  77. return ( m_nOffset ? (T*)( ((char*)this) + m_nOffset ) : (T*)NULL );
  78. }
  79. operator const T*() const
  80. {
  81. return ( m_nOffset ? (T*)( ((char*)this) + m_nOffset ) : (T*)NULL );
  82. }
  83. operator T*()
  84. {
  85. return ( m_nOffset ? (T*)( ((char*)this) + m_nOffset ) : (T*)NULL );
  86. }
  87. const T* Get() const
  88. {
  89. return ( m_nOffset ? (T*)( ((char*)this) + m_nOffset ) : (T*)NULL );
  90. }
  91. T* Get()
  92. {
  93. return ( m_nOffset ? (T*)( ((char*)this) + m_nOffset ) : (T*)NULL );
  94. }
  95. private:
  96. intp m_nOffset;
  97. };
  98. class CSnapshotDir;
  99. class CSnapshotFile
  100. {
  101. public:
  102. CSnapshotFile();
  103. // Get the full filename.
  104. void GetLongName( char *pOut, int maxLen );
  105. public:
  106. uint64 m_nFileSize;
  107. COffsetPtr<char> m_pShortName;
  108. COffsetPtr<CSnapshotFile> m_pNextFile;
  109. COffsetPtr<CSnapshotDir> m_pDir;
  110. };
  111. class CSnapshotDir
  112. {
  113. public:
  114. CSnapshotDir();
  115. uint64 GetFileDataSize_R();
  116. int GetNumFiles_R();
  117. CSnapshotFile* GetFile( const char *pShortName );
  118. CSnapshotDir* GetDir( const char *pLongName );
  119. public:
  120. // This does NOT include a trailing slash.
  121. COffsetPtr<char> m_pLongName;
  122. COffsetPtr<CSnapshotDir> m_pFirstDir;
  123. COffsetPtr<CSnapshotDir> m_pNextDir;
  124. COffsetPtr<CSnapshotFile> m_pFirstFile;
  125. };
  126. class CVWatchSnapshot
  127. {
  128. public:
  129. CVWatchSnapshot();
  130. void AddRef();
  131. void Release();
  132. // This can return null if there are no files in this snapshot.
  133. virtual CSnapshotDir* GetRootDir();
  134. // Figure out what we'd need to send and delete from pTo in order to make it look like us.
  135. static void CalcDelta( CVWatchSnapshot *pFrom, CVWatchSnapshot *pTo, CUtlVector<CSnapshotFile*> &filesToSend, CUtlVector<CSnapshotFile*> &filesToDelete );
  136. int GetNumFiles();
  137. uint64 GetFileDataSize();
  138. protected:
  139. virtual ~CVWatchSnapshot();
  140. protected:
  141. int m_nRefCount;
  142. };
  143. // Flags for CVWatchClient::GetSnapshot.
  144. // GETSNAPSHOT_MACHINE_LEVEL_ROOT means that a GetSnapshot of c:\test will look like this:
  145. // +- (empty string)
  146. // +- c:
  147. // +- c:\test
  148. // etc...
  149. //
  150. // Without this flag, the CVWatchSnapshot's root directory would be c:\test in the example above.
  151. #define GETSNAPSHOT_MACHINE_LEVEL_ROOT 0x01
  152. class CVWatchClient
  153. {
  154. public:
  155. CVWatchClient();
  156. ~CVWatchClient();
  157. //
  158. // Connection-management functions.
  159. //
  160. // Connect to the running vwatch service.
  161. // nTimeout tells it how long to wait. Use TT_INFINITE to wait forever.
  162. bool Connect( uint32 nTimeout );
  163. void Term();
  164. // Note: This can return false even if Connect() returned true because the vwatch_service
  165. // process might have died.
  166. bool IsConnected();
  167. // You can do this to tell the service to completely drop all its current results and start scanning again. Mostly for debugging.
  168. bool SendRestartSignal();
  169. //
  170. // Control what directories VWatch is scanning.
  171. //
  172. // Start and stop watching specific directories.
  173. StartWatchingDirStatus_t StartWatchingDir( const char *pDirName );
  174. bool StopWatchingDir( const char *pDirName );
  175. // Tells us if vwatch_service is watching the specified directory.
  176. bool IsWatchingDir( const char *pDirName );
  177. // Get a list of the directories that it's currently watching.
  178. bool GetWatchedDirectories( CUtlVector<CUtlString> &dirs );
  179. //
  180. // Status.
  181. //
  182. // This is mostly here for testing. It communicates with the service to see
  183. // how many files it has scanned so far.
  184. bool GetNumFilesScanned( int *pnFilesScanned, uint32 nTimeout=TT_INFINITE );
  185. // This is only updated periodically to get an idea of the stats. It may not be 100% up-to-date at all times.
  186. // Also, it'll return null if you aren't connected to the service.
  187. const CVWatchStats* GetStats();
  188. //
  189. // CRC query.
  190. //
  191. // This gets the file's CRC. If it's cached and we can access it, we use that.
  192. // If not, we calculate it (and cache it if vwatch_service is running).
  193. GetCRCStatus_t GetFileCRC( const char *pFilename, CRC32_t &crc );
  194. //
  195. // Snapshots.
  196. //
  197. // Get a snapshot of the specified directory.
  198. // Flags is a combination of GETSNAPSHOT_ flags.
  199. GetSnapshotStatus_t GetSnapshotForDir( const char *pDirName, CVWatchSnapshot **pSnapshot, int nFlags );
  200. // Load/save snapshots.
  201. CVWatchSnapshot* LoadSnapshot( IFileSystem *pFileSystem, const char *pFilename );
  202. bool SaveSnapshot( CVWatchSnapshot *pSnapshot, IFileSystem *pFileSystem, const char *pFilename );
  203. // Calculate a snapshot given a starting one that has added and removed files.
  204. // This is used by RemoteMirror to remember what files the remote machine has on it.
  205. CVWatchSnapshot* CalcMergedSnapshot( CVWatchSnapshot *pFrom, CUtlVector<CSnapshotFile*> &filesSent, CUtlVector<CSnapshotFile*> &filesDeleted );
  206. // Used by RemoteMirror if it can't load a previous snapshot. It simplifies the code if we can have a non-null snapshot
  207. // that's rooted in the right place.
  208. CVWatchSnapshot* CreateEmptySnapshot( const char *pLongRootDirName );
  209. private:
  210. // This assumes you have the mutex locked!
  211. CVWatchHeader* GetVWatchHeader();
  212. // Start writing a signal to overwatch.
  213. // If it returns NULL, then that means it couldn't access vwatch or it couldn't get an app signal slot.
  214. // If it returns a pointer, then you MUST UnlockMutex( m_hDataMutex ) afterwards.
  215. CAppSignal* StartAppSignal( int nTimeout );
  216. // Lock the shared data. This also increments CVWatchHeader::m_nClientLocks.
  217. bool LockSharedDataMutex( uint32 nTimeout=TT_INFINITE );
  218. void UnlockSharedDataMutex();
  219. private:
  220. // Library fallback routine - generates a manual snapshot for when we're not connected to service
  221. GetSnapshotStatus_t GetSlowSnapshotForDir( const char *pDirName, CVWatchSnapshot **pSnapshot, int nFlags );
  222. CSharedMemoryMgr *m_pSharedMemoryMgr;
  223. void *m_hDataMutex; // From VWATCH_MUTEX_NAME
  224. // Process handle for vwatch_service.
  225. void *m_hServiceProcess;
  226. // Set in and returned by GetStats().
  227. CVWatchStats m_BackedUpVWatchStats;
  228. // The buffer and event for AppSignal responses.
  229. char m_AppSignalMemoryName[32];
  230. char m_AppSignalEventName[32];
  231. CSharedMemoryMgr *m_pAppSignalMemory;
  232. void *m_hAppSignalEvent;
  233. };
  234. #endif // VWATCHCLIENT_H