Team Fortress 2 Source Code as on 22/4/2020
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.

85 lines
1.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #ifndef THREADSAFEREFCOUNTEDOBJECT_H
  7. #define THREADSAFEREFCOUNTEDOBJECT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. // This class can be used for fast access to an object from multiple threads,
  12. // and the main thread can wait until the threads are done using the object before it frees the object.
  13. template< class T >
  14. class CThreadSafeRefCountedObject
  15. {
  16. public:
  17. CThreadSafeRefCountedObject( T initVal )
  18. {
  19. m_RefCount = 0;
  20. m_pObject = initVal;
  21. m_RefCount = 0;
  22. }
  23. void Init( T pObj )
  24. {
  25. Assert( ThreadInMainThread() );
  26. Assert( !m_pObject );
  27. m_RefCount = 0;
  28. m_pObject = pObj;
  29. m_RefCount = 1;
  30. }
  31. // Threads that access the object need to use AddRef/Release to access it.
  32. T AddRef()
  33. {
  34. if ( ++m_RefCount > 1 )
  35. {
  36. return m_pObject;
  37. }
  38. else
  39. {
  40. // If the refcount was 0 when we called this, then the whitelist is about to be freed.
  41. --m_RefCount;
  42. return NULL;
  43. }
  44. }
  45. void ReleaseRef( T pObj )
  46. {
  47. if ( --m_RefCount >= 1 )
  48. {
  49. Assert( m_pObject == pObj );
  50. }
  51. }
  52. // The main thread can use this to access the object, since only it can Init() and Free() the object.
  53. T GetInMainThread()
  54. {
  55. Assert( ThreadInMainThread() );
  56. return m_pObject;
  57. }
  58. // The main thread calls this after it has released its last reference to the object.
  59. void ResetWhenNoRemainingReferences( T newValue )
  60. {
  61. Assert( ThreadInMainThread() );
  62. // Wait until we can free it.
  63. while ( m_RefCount > 0 )
  64. {
  65. CThread::Sleep( 20 );
  66. }
  67. m_pObject = newValue;
  68. }
  69. private:
  70. CInterlockedIntT<long> m_RefCount;
  71. T m_pObject;
  72. };
  73. #endif // THREADSAFEREFCOUNTEDOBJECT_H