mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 06:36:54 +00:00
86 lines
1.7 KiB
C
86 lines
1.7 KiB
C
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================
|
||
|
|
||
|
#ifndef THREADSAFEREFCOUNTEDOBJECT_H
|
||
|
#define THREADSAFEREFCOUNTEDOBJECT_H
|
||
|
#ifdef _WIN32
|
||
|
#pragma once
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// This class can be used for fast access to an object from multiple threads,
|
||
|
// and the main thread can wait until the threads are done using the object before it frees the object.
|
||
|
template< class T >
|
||
|
class CThreadSafeRefCountedObject
|
||
|
{
|
||
|
public:
|
||
|
CThreadSafeRefCountedObject( T initVal )
|
||
|
{
|
||
|
m_RefCount = 0;
|
||
|
m_pObject = initVal;
|
||
|
m_RefCount = 0;
|
||
|
}
|
||
|
|
||
|
void Init( T pObj )
|
||
|
{
|
||
|
Assert( ThreadInMainThread() );
|
||
|
Assert( !m_pObject );
|
||
|
m_RefCount = 0;
|
||
|
m_pObject = pObj;
|
||
|
m_RefCount = 1;
|
||
|
}
|
||
|
|
||
|
// Threads that access the object need to use AddRef/Release to access it.
|
||
|
T AddRef()
|
||
|
{
|
||
|
if ( ++m_RefCount > 1 )
|
||
|
{
|
||
|
return m_pObject;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// If the refcount was 0 when we called this, then the whitelist is about to be freed.
|
||
|
--m_RefCount;
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
void ReleaseRef( T pObj )
|
||
|
{
|
||
|
if ( --m_RefCount >= 1 )
|
||
|
{
|
||
|
Assert( m_pObject == pObj );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// The main thread can use this to access the object, since only it can Init() and Free() the object.
|
||
|
T GetInMainThread()
|
||
|
{
|
||
|
Assert( ThreadInMainThread() );
|
||
|
return m_pObject;
|
||
|
}
|
||
|
|
||
|
// The main thread calls this after it has released its last reference to the object.
|
||
|
void ResetWhenNoRemainingReferences( T newValue )
|
||
|
{
|
||
|
Assert( ThreadInMainThread() );
|
||
|
|
||
|
// Wait until we can free it.
|
||
|
while ( m_RefCount > 0 )
|
||
|
{
|
||
|
CThread::Sleep( 20 );
|
||
|
}
|
||
|
|
||
|
m_pObject = newValue;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
CInterlockedIntT<long> m_RefCount;
|
||
|
T m_pObject;
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif // THREADSAFEREFCOUNTEDOBJECT_H
|