mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-17 10:52:46 +00:00
Make hsRefCnt atomic, and merge with hsAtomicRefCnt
This commit is contained in:
@ -67,7 +67,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
|
||||
struct _RefCountLeakCheck
|
||||
{
|
||||
std::unordered_set<_hsRefCnt_Base *> m_refs;
|
||||
std::unordered_set<hsRefCnt *> m_refs;
|
||||
unsigned m_added, m_removed;
|
||||
std::mutex m_mutex;
|
||||
|
||||
@ -81,7 +81,7 @@ struct _RefCountLeakCheck
|
||||
return;
|
||||
|
||||
_LeakDebug(plFormat(" {} objects leaked...\n", m_refs.size()).c_str());
|
||||
for (_hsRefCnt_Base *ref : m_refs) {
|
||||
for (hsRefCnt *ref : m_refs) {
|
||||
_LeakDebug(plFormat(" 0x{_08x} {}: {} refs remain\n",
|
||||
(uintptr_t)ref, typeid(*ref).name(), ref->RefCnt()).c_str());
|
||||
}
|
||||
@ -93,7 +93,7 @@ struct _RefCountLeakCheck
|
||||
return &s_instance;
|
||||
}
|
||||
|
||||
static void add(_hsRefCnt_Base *ref)
|
||||
static void add(hsRefCnt *ref)
|
||||
{
|
||||
_RefCountLeakCheck *this_p = _instance();
|
||||
std::lock_guard<std::mutex> lock(this_p->m_mutex);
|
||||
@ -101,7 +101,7 @@ struct _RefCountLeakCheck
|
||||
this_p->m_refs.insert(ref);
|
||||
}
|
||||
|
||||
static void del(_hsRefCnt_Base *ref)
|
||||
static void del(hsRefCnt *ref)
|
||||
{
|
||||
_RefCountLeakCheck *this_p = _instance();
|
||||
std::lock_guard<std::mutex> lock(this_p->m_mutex);
|
||||
@ -111,47 +111,26 @@ struct _RefCountLeakCheck
|
||||
};
|
||||
#endif
|
||||
|
||||
_hsRefCnt_Base::_hsRefCnt_Base(int)
|
||||
hsRefCnt::hsRefCnt(int initRefs)
|
||||
: fRefCnt(initRefs)
|
||||
{
|
||||
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
|
||||
_RefCountLeakCheck::add(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
_hsRefCnt_Base::~_hsRefCnt_Base()
|
||||
{
|
||||
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
|
||||
_RefCountLeakCheck::del(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
hsRefCnt::~hsRefCnt()
|
||||
{
|
||||
#ifdef HS_DEBUGGING
|
||||
hsThrowIfFalse(fRefCnt == 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hsRefCnt::UnRef()
|
||||
{
|
||||
#ifdef HS_DEBUGGING
|
||||
hsThrowIfFalse(fRefCnt >= 1);
|
||||
#endif
|
||||
|
||||
if (fRefCnt == 1) // don't decrement if we call delete
|
||||
delete this;
|
||||
else
|
||||
--fRefCnt;
|
||||
}
|
||||
|
||||
hsAtomicRefCnt::~hsAtomicRefCnt()
|
||||
{
|
||||
#ifdef HS_DEBUGGING
|
||||
hsThrowIfFalse(fRefCnt == 1);
|
||||
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_LEAKS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
|
||||
_RefCountLeakCheck::del(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hsAtomicRefCnt::UnRef(const char* tag)
|
||||
void hsRefCnt::UnRef(const char* tag)
|
||||
{
|
||||
#ifdef HS_DEBUGGING
|
||||
hsThrowIfFalse(fRefCnt >= 1);
|
||||
@ -170,7 +149,7 @@ void hsAtomicRefCnt::UnRef(const char* tag)
|
||||
--fRefCnt;
|
||||
}
|
||||
|
||||
void hsAtomicRefCnt::Ref(const char* tag)
|
||||
void hsRefCnt::Ref(const char* tag)
|
||||
{
|
||||
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_REFS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
|
||||
if (tag)
|
||||
@ -182,7 +161,7 @@ void hsAtomicRefCnt::Ref(const char* tag)
|
||||
++fRefCnt;
|
||||
}
|
||||
|
||||
void hsAtomicRefCnt::TransferRef(const char* oldTag, const char* newTag)
|
||||
void hsRefCnt::TransferRef(const char* oldTag, const char* newTag)
|
||||
{
|
||||
#if (REFCOUNT_DEBUGGING == REFCOUNT_DBG_REFS) || (REFCOUNT_DEBUGGING == REFCOUNT_DBG_ALL)
|
||||
DEBUG_MSG("Inc %p %s: (xfer)", this, newTag);
|
||||
|
@ -44,50 +44,13 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
|
||||
#include <atomic>
|
||||
|
||||
// For easier debugging
|
||||
class _hsRefCnt_Base
|
||||
{
|
||||
public:
|
||||
_hsRefCnt_Base(int initRefs = 1);
|
||||
virtual ~_hsRefCnt_Base();
|
||||
|
||||
virtual int RefCnt() const = 0;
|
||||
};
|
||||
|
||||
class hsRefCnt : public _hsRefCnt_Base {
|
||||
private:
|
||||
int fRefCnt;
|
||||
|
||||
public:
|
||||
hsRefCnt(int initRefs = 1) : fRefCnt(initRefs) { }
|
||||
virtual ~hsRefCnt();
|
||||
|
||||
inline int RefCnt() const { return fRefCnt; }
|
||||
void UnRef();
|
||||
inline void Ref() { ++fRefCnt; }
|
||||
};
|
||||
|
||||
#define hsRefCnt_SafeRef(obj) do { if (obj) (obj)->Ref(); } while (0)
|
||||
#define hsRefCnt_SafeUnRef(obj) do { if (obj) (obj)->UnRef(); } while (0)
|
||||
|
||||
#define hsRefCnt_SafeAssign(dst, src) \
|
||||
do { \
|
||||
hsRefCnt_SafeRef(src); \
|
||||
hsRefCnt_SafeUnRef(dst); \
|
||||
dst = src; \
|
||||
} while (0)
|
||||
|
||||
|
||||
// Thread-safe version. TODO: Evaluate whether this is fast enough to
|
||||
// merge with hsRefCnt above.
|
||||
class hsAtomicRefCnt : public _hsRefCnt_Base
|
||||
{
|
||||
class hsRefCnt {
|
||||
private:
|
||||
std::atomic<int> fRefCnt;
|
||||
|
||||
public:
|
||||
hsAtomicRefCnt(int initRefs = 1) : fRefCnt(initRefs) { }
|
||||
virtual ~hsAtomicRefCnt();
|
||||
hsRefCnt(int initRefs = 1);
|
||||
virtual ~hsRefCnt();
|
||||
|
||||
inline int RefCnt() const { return fRefCnt; }
|
||||
void UnRef(const char* tag = nullptr);
|
||||
@ -95,8 +58,26 @@ public:
|
||||
|
||||
// Useless, but left here for debugging compatibility with AtomicRef
|
||||
void TransferRef(const char* oldTag, const char* newTag);
|
||||
|
||||
|
||||
// The stored reference count of an hsRefCnt-derived object should never
|
||||
// be copied! Therefore, if you want a copyable hsRefCnt-based class, you
|
||||
// should implement your own copy constructor / assignment operator.
|
||||
hsRefCnt(const hsRefCnt &) = delete;
|
||||
hsRefCnt &operator=(const hsRefCnt &) = delete;
|
||||
};
|
||||
|
||||
#define hsRefCnt_SafeRef(obj) do { if (obj) (obj)->Ref(); } while (0)
|
||||
#define hsRefCnt_SafeUnRef(obj) do { if (obj) (obj)->UnRef(); } while (0)
|
||||
|
||||
#define hsRefCnt_SafeAssign(dst, src) \
|
||||
do { \
|
||||
hsRefCnt_SafeRef(src); \
|
||||
hsRefCnt_SafeUnRef(dst); \
|
||||
dst = src; \
|
||||
} while (0)
|
||||
|
||||
|
||||
template <class _Ref>
|
||||
class hsRef
|
||||
{
|
||||
|
@ -435,7 +435,7 @@ PLASMA_DEFAULT_TYPE(ptAgeInfoStructRef, "Class to hold AgeInfo struct data");
|
||||
PyObject *pyAgeInfoStructRef::New(plAgeInfoStruct &info)
|
||||
{
|
||||
ptAgeInfoStructRef *newObj = (ptAgeInfoStructRef*)ptAgeInfoStructRef_type.tp_new(&ptAgeInfoStructRef_type, NULL, NULL);
|
||||
newObj->fThis->fAgeInfo = info;
|
||||
newObj->fThis->fAgeInfo.CopyFrom(&info);
|
||||
return (PyObject*)newObj;
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,7 @@ PLASMA_DEFAULT_TYPE(ptAgeLinkStructRef, "Class to hold the data of the AgeLink s
|
||||
PyObject *pyAgeLinkStructRef::New(plAgeLinkStruct &link)
|
||||
{
|
||||
ptAgeLinkStructRef *newObj = (ptAgeLinkStructRef*)ptAgeLinkStructRef_type.tp_new(&ptAgeLinkStructRef_type, NULL, NULL);
|
||||
newObj->fThis->fAgeLink = link;
|
||||
newObj->fThis->fAgeLink.CopyFrom(&link);
|
||||
return (PyObject*)newObj;
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ private:
|
||||
|
||||
protected:
|
||||
pyNetServerSessionInfo() {}
|
||||
pyNetServerSessionInfo( const plNetServerSessionInfo & info ): fInfo( info ) {}
|
||||
pyNetServerSessionInfo(const plNetServerSessionInfo & info) { fInfo.CopyFrom(&info); }
|
||||
|
||||
public:
|
||||
// required functions for PyObject interoperability
|
||||
|
@ -193,7 +193,7 @@ PYTHON_CLASS_NEW_IMPL(ptNetServerSessionInfo, pyNetServerSessionInfo)
|
||||
PyObject *pyNetServerSessionInfo::New(const plNetServerSessionInfo &info)
|
||||
{
|
||||
ptNetServerSessionInfo *newObj = (ptNetServerSessionInfo*)ptNetServerSessionInfo_type.tp_new(&ptNetServerSessionInfo_type, NULL, NULL);
|
||||
newObj->fThis->fInfo = info;
|
||||
newObj->fThis->fInfo.CopyFrom(&info);
|
||||
return (PyObject*)newObj;
|
||||
}
|
||||
|
||||
@ -354,7 +354,7 @@ PLASMA_DEFAULT_TYPE(ptNetServerSessionInfoRef, "Basic server session info class"
|
||||
PyObject *pyNetServerSessionInfoRef::New(plNetServerSessionInfo &info)
|
||||
{
|
||||
ptNetServerSessionInfoRef *newObj = (ptNetServerSessionInfoRef*)ptNetServerSessionInfoRef_type.tp_new(&ptNetServerSessionInfoRef_type, NULL, NULL);
|
||||
newObj->fThis->fInfo = info;
|
||||
newObj->fThis->fInfo.CopyFrom(&info);
|
||||
return (PyObject*)newObj;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ void pyVaultPlayerInfoListNode::AddPlayer( uint32_t playerID )
|
||||
if (nodeIds.Count())
|
||||
VaultAddChildNode(fNode->GetNodeId(), nodeIds[0], VaultGetPlayerId(), nullptr, nullptr);
|
||||
else
|
||||
VaultFindNodes(templateNode, IAddPlayer_NodesFound, fNode);
|
||||
VaultFindNodes(templateNode, IAddPlayer_NodesFound, (NetVaultNode *)fNode);
|
||||
}
|
||||
|
||||
void pyVaultPlayerInfoListNode::RemovePlayer( uint32_t playerID )
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
BOOL TryEnter () { return TryEnterCriticalSection(&m_handle); }
|
||||
};
|
||||
|
||||
class CNtWaitHandle : public hsAtomicRefCnt {
|
||||
class CNtWaitHandle : public hsRefCnt {
|
||||
HANDLE m_event;
|
||||
|
||||
public:
|
||||
|
@ -57,7 +57,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
*
|
||||
***/
|
||||
|
||||
struct AsyncThreadTaskList : hsAtomicRefCnt {
|
||||
struct AsyncThreadTaskList : hsRefCnt {
|
||||
ENetError error;
|
||||
AsyncThreadTaskList ();
|
||||
~AsyncThreadTaskList ();
|
||||
@ -81,7 +81,7 @@ static HANDLE s_taskPort;
|
||||
|
||||
//===========================================================================
|
||||
AsyncThreadTaskList::AsyncThreadTaskList ()
|
||||
: hsAtomicRefCnt(0), error(kNetSuccess)
|
||||
: hsRefCnt(0), error(kNetSuccess)
|
||||
{
|
||||
PerfAddCounter(kAsyncPerfThreadTaskListCount, 1);
|
||||
}
|
||||
|
@ -73,8 +73,8 @@ private:
|
||||
hsMutex m_critsect;
|
||||
};
|
||||
|
||||
struct NetMsgChannel : hsAtomicRefCnt {
|
||||
NetMsgChannel() : hsAtomicRefCnt(0) { }
|
||||
struct NetMsgChannel : hsRefCnt {
|
||||
NetMsgChannel() : hsRefCnt(0) { }
|
||||
|
||||
uint32_t m_protocol;
|
||||
bool m_server;
|
||||
|
@ -315,7 +315,7 @@ void NetVaultNode::DeallocNodeFields () {
|
||||
|
||||
//============================================================================
|
||||
NetVaultNode::NetVaultNode ()
|
||||
: hsAtomicRefCnt(0), fieldFlags(0), dirtyFlags(0)
|
||||
: hsRefCnt(0), fieldFlags(0), dirtyFlags(0)
|
||||
, nodeId(0), createTime(0), modifyTime(0)
|
||||
, createAgeName(nil), creatorId(0)
|
||||
, nodeType(0)
|
||||
|
@ -157,7 +157,7 @@ struct NetGameRank {
|
||||
// NetVaultNode
|
||||
//============================================================================
|
||||
// Threaded apps: App is responsible for locking node->critsect before accessing *any* field in this struct
|
||||
struct NetVaultNode : hsAtomicRefCnt {
|
||||
struct NetVaultNode : hsRefCnt {
|
||||
enum RwOptions {
|
||||
kRwDirtyOnly = 1<<0, // READ : No meaning
|
||||
// WRITE: Only write fields marked dirty
|
||||
|
@ -132,6 +132,20 @@ bool plAgeInfoStruct::IsEqualTo( const plAgeInfoStruct * other ) const
|
||||
return match;
|
||||
}
|
||||
|
||||
void plAgeInfoStruct::CopyFrom(const plAgeInfoStruct * other)
|
||||
{
|
||||
hsAssert(other, "CopyFrom called with null struct");
|
||||
|
||||
fFlags = other->fFlags;
|
||||
fAgeFilename = other->fAgeFilename;
|
||||
fAgeInstanceName = other->fAgeInstanceName;
|
||||
fAgeInstanceGuid = other->fAgeInstanceGuid;
|
||||
fAgeUserDefinedName = other->fAgeUserDefinedName;
|
||||
fAgeDescription = other->fAgeDescription;
|
||||
fAgeSequenceNumber = other->fAgeSequenceNumber;
|
||||
fAgeLanguage = other->fAgeLanguage;
|
||||
}
|
||||
|
||||
void plAgeInfoStruct::CopyFrom( const plVaultAgeInfoNode * node )
|
||||
{
|
||||
hsAssert(false, "eric, port me");
|
||||
@ -441,7 +455,12 @@ void plAgeLinkStruct::CopyFrom( const plAgeLinkStruct * other )
|
||||
{
|
||||
if ( other )
|
||||
{
|
||||
*this=*other;
|
||||
fFlags = other->fFlags;
|
||||
fAgeInfo.CopyFrom(&other->fAgeInfo);
|
||||
fLinkingRules = other->fLinkingRules;
|
||||
fSpawnPoint = other->fSpawnPoint;
|
||||
fAmCCR = other->fAmCCR;
|
||||
fParentAgeFilename = other->fParentAgeFilename;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -112,7 +112,7 @@ public:
|
||||
|
||||
void Clear();
|
||||
void UpdateFlags() const;
|
||||
void CopyFrom( const plAgeInfoStruct * other ) { *this=*other; }
|
||||
void CopyFrom( const plAgeInfoStruct * other );
|
||||
void CopyFrom( const plVaultAgeInfoNode * node );
|
||||
void CopyFrom(const struct NetAgeInfo & info);
|
||||
bool IsEqualTo( const plAgeInfoStruct * other ) const;
|
||||
|
@ -287,7 +287,7 @@ enum ENetTransState {
|
||||
kTransStateComplete,
|
||||
};
|
||||
|
||||
struct NetTrans : hsAtomicRefCnt {
|
||||
struct NetTrans : hsRefCnt {
|
||||
LINK(NetTrans) m_link;
|
||||
ENetTransState m_state;
|
||||
ENetError m_result;
|
||||
|
@ -57,7 +57,7 @@ namespace Ngl { namespace Auth {
|
||||
*
|
||||
***/
|
||||
|
||||
struct CliAuConn : hsAtomicRefCnt {
|
||||
struct CliAuConn : hsRefCnt {
|
||||
CliAuConn ();
|
||||
~CliAuConn ();
|
||||
|
||||
@ -1588,7 +1588,7 @@ static unsigned CliAuConnPingTimerProc (void * param) {
|
||||
|
||||
//============================================================================
|
||||
CliAuConn::CliAuConn ()
|
||||
: hsAtomicRefCnt(0), reconnectTimer(nil), reconnectStartMs(0)
|
||||
: hsRefCnt(0), reconnectTimer(nil), reconnectStartMs(0)
|
||||
, pingTimer(nil), pingSendTimeMs(0), lastHeardTimeMs(0)
|
||||
, sock(nil), cli(nil), seq(0), serverChallenge(0)
|
||||
, cancelId(nil), abandoned(false)
|
||||
|
@ -60,7 +60,7 @@ namespace Ngl { namespace File {
|
||||
*
|
||||
***/
|
||||
|
||||
struct CliFileConn : hsAtomicRefCnt {
|
||||
struct CliFileConn : hsRefCnt {
|
||||
LINK(CliFileConn) link;
|
||||
hsReaderWriterLock sockLock; // to protect the socket pointer so we don't nuke it while using it
|
||||
AsyncSocket sock;
|
||||
@ -581,7 +581,7 @@ static void AsyncLookupCallback (
|
||||
|
||||
//============================================================================
|
||||
CliFileConn::CliFileConn ()
|
||||
: hsAtomicRefCnt(0), sock(nil), seq(0), cancelId(nil), abandoned(false)
|
||||
: hsRefCnt(0), sock(nil), seq(0), cancelId(nil), abandoned(false)
|
||||
, buildId(0), serverType(0)
|
||||
, reconnectTimer(nil), reconnectStartMs(0), connectStartMs(0)
|
||||
, numImmediateDisconnects(0), numFailedConnects(0)
|
||||
|
@ -55,7 +55,7 @@ namespace Ngl { namespace Game {
|
||||
*
|
||||
***/
|
||||
|
||||
struct CliGmConn : hsAtomicRefCnt {
|
||||
struct CliGmConn : hsRefCnt {
|
||||
LINK(CliGmConn) link;
|
||||
|
||||
CCritSect critsect;
|
||||
@ -415,7 +415,7 @@ static unsigned CliGmConnPingTimerProc (void * param) {
|
||||
|
||||
//============================================================================
|
||||
CliGmConn::CliGmConn ()
|
||||
: hsAtomicRefCnt(0), sock(nil), cancelId(nil), cli(nil)
|
||||
: hsRefCnt(0), sock(nil), cancelId(nil), cli(nil)
|
||||
, seq(0), abandoned(false)
|
||||
, pingTimer(nil), pingSendTimeMs(0), lastHeardTimeMs(0)
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ namespace Ngl { namespace GateKeeper {
|
||||
*
|
||||
***/
|
||||
|
||||
struct CliGkConn : hsAtomicRefCnt {
|
||||
struct CliGkConn : hsRefCnt {
|
||||
CliGkConn ();
|
||||
~CliGkConn ();
|
||||
|
||||
@ -525,7 +525,7 @@ static unsigned CliGkConnPingTimerProc (void * param) {
|
||||
|
||||
//============================================================================
|
||||
CliGkConn::CliGkConn ()
|
||||
: hsAtomicRefCnt(0), reconnectTimer(nil), reconnectStartMs(0)
|
||||
: hsRefCnt(0), reconnectTimer(nil), reconnectStartMs(0)
|
||||
, pingTimer(nil), pingSendTimeMs(0), lastHeardTimeMs(0)
|
||||
, sock(nil), cli(nil), seq(0), serverChallenge(0)
|
||||
, cancelId(nil), abandoned(false)
|
||||
|
@ -117,7 +117,7 @@ static void CancelTrans_CS (NetTrans * trans, ENetError error) {
|
||||
|
||||
//============================================================================
|
||||
NetTrans::NetTrans (ENetProtocol protocol, ETransType transType)
|
||||
: hsAtomicRefCnt(0)
|
||||
: hsRefCnt(0)
|
||||
, m_state(kTransStateWaitServerConnect)
|
||||
, m_result(kNetPending)
|
||||
, m_transId(0)
|
||||
|
@ -48,7 +48,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
//
|
||||
// refcntable data
|
||||
//
|
||||
class plNetCommonMessageData : public hsAtomicRefCnt
|
||||
class plNetCommonMessageData : public hsRefCnt
|
||||
{
|
||||
private:
|
||||
char *fData; // sent
|
||||
|
@ -71,6 +71,16 @@ plFogEnvironment::~plFogEnvironment()
|
||||
{
|
||||
}
|
||||
|
||||
plFogEnvironment &plFogEnvironment::operator=(const plFogEnvironment ©)
|
||||
{
|
||||
fType = copy.fType;
|
||||
fStart = copy.fStart;
|
||||
fEnd = copy.fEnd;
|
||||
fDensity = copy.fDensity;
|
||||
fColor = copy.fColor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//// Set /////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plFogEnvironment::Set( float start, float end, float density, const hsColorRGBA *color )
|
||||
|
@ -85,6 +85,9 @@ class plFogEnvironment : public hsKeyedObject
|
||||
plFogEnvironment( FogType type, float end, float density, hsColorRGBA &color );
|
||||
~plFogEnvironment();
|
||||
|
||||
plFogEnvironment(const plFogEnvironment ©) { operator=(copy); }
|
||||
plFogEnvironment &operator=(const plFogEnvironment ©);
|
||||
|
||||
// Sets the parameters for linear fog
|
||||
void Set( float start, float end, float density, const hsColorRGBA *color = nil );
|
||||
|
||||
|
Reference in New Issue
Block a user