1
This commit is contained in:
85
filesystem/filesystem_stdio/ThreadSafeRefCountedObject.h
Normal file
85
filesystem/filesystem_stdio/ThreadSafeRefCountedObject.h
Normal file
@ -0,0 +1,85 @@
|
||||
//========= 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
|
Reference in New Issue
Block a user