Browse Source

Make hsRefCnt atomic, and merge with hsAtomicRefCnt

Michael Hansen 11 years ago
parent
commit
aee2f7f7ca
  1. 43
      Sources/Plasma/CoreLib/hsRefCnt.cpp
  2. 55
      Sources/Plasma/CoreLib/hsRefCnt.h
  3. 2
      Sources/Plasma/FeatureLib/pfPython/pyAgeInfoStructGlue.cpp
  4. 2
      Sources/Plasma/FeatureLib/pfPython/pyAgeLinkStructGlue.cpp
  5. 2
      Sources/Plasma/FeatureLib/pfPython/pyNetServerSessionInfo.h
  6. 4
      Sources/Plasma/FeatureLib/pfPython/pyNetServerSessionInfoGlue.cpp
  7. 2
      Sources/Plasma/FeatureLib/pfPython/pyVaultPlayerInfoListNode.cpp
  8. 2
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h
  9. 4
      Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Win32/pnAceW32Thread.cpp
  10. 4
      Sources/Plasma/NucleusLib/pnNetCli/pnNcChannel.cpp
  11. 2
      Sources/Plasma/NucleusLib/pnNetProtocol/Private/pnNpCommon.cpp
  12. 2
      Sources/Plasma/NucleusLib/pnNetProtocol/Private/pnNpCommon.h
  13. 21
      Sources/Plasma/PubUtilLib/plNetCommon/plNetServerSessionInfo.cpp
  14. 2
      Sources/Plasma/PubUtilLib/plNetCommon/plNetServerSessionInfo.h
  15. 2
      Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h
  16. 4
      Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp
  17. 4
      Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp
  18. 4
      Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp
  19. 4
      Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp
  20. 2
      Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp
  21. 2
      Sources/Plasma/PubUtilLib/plNetMessage/plNetCommonMessage.h
  22. 10
      Sources/Plasma/PubUtilLib/plPipeline/plFogEnvironment.cpp
  23. 3
      Sources/Plasma/PubUtilLib/plPipeline/plFogEnvironment.h

43
Sources/Plasma/CoreLib/hsRefCnt.cpp

@ -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);

55
Sources/Plasma/CoreLib/hsRefCnt.h

@ -44,59 +44,40 @@ 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 {
class hsRefCnt {
private:
int fRefCnt;
std::atomic<int> fRefCnt;
public:
hsRefCnt(int initRefs = 1) : fRefCnt(initRefs) { }
hsRefCnt(int initRefs = 1);
virtual ~hsRefCnt();
inline int RefCnt() const { return fRefCnt; }
void UnRef();
inline void Ref() { ++fRefCnt; }
void UnRef(const char* tag = nullptr);
void Ref(const char* tag = nullptr);
// 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_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) \
#define hsRefCnt_SafeAssign(dst, src) \
do { \
hsRefCnt_SafeRef(src); \
hsRefCnt_SafeUnRef(dst); \
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
{
private:
std::atomic<int> fRefCnt;
public:
hsAtomicRefCnt(int initRefs = 1) : fRefCnt(initRefs) { }
virtual ~hsAtomicRefCnt();
inline int RefCnt() const { return fRefCnt; }
void UnRef(const char* tag = nullptr);
void Ref(const char* tag = nullptr);
// Useless, but left here for debugging compatibility with AtomicRef
void TransferRef(const char* oldTag, const char* newTag);
};
template <class _Ref>
class hsRef
{

2
Sources/Plasma/FeatureLib/pfPython/pyAgeInfoStructGlue.cpp

@ -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;
}

2
Sources/Plasma/FeatureLib/pfPython/pyAgeLinkStructGlue.cpp

@ -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;
}

2
Sources/Plasma/FeatureLib/pfPython/pyNetServerSessionInfo.h

@ -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

4
Sources/Plasma/FeatureLib/pfPython/pyNetServerSessionInfoGlue.cpp

@ -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;
}

2
Sources/Plasma/FeatureLib/pfPython/pyVaultPlayerInfoListNode.cpp

@ -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 )

2
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h

@ -88,7 +88,7 @@ public:
BOOL TryEnter () { return TryEnterCriticalSection(&m_handle); }
};
class CNtWaitHandle : public hsAtomicRefCnt {
class CNtWaitHandle : public hsRefCnt {
HANDLE m_event;
public:

4
Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Win32/pnAceW32Thread.cpp

@ -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);
}

4
Sources/Plasma/NucleusLib/pnNetCli/pnNcChannel.cpp

@ -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;

2
Sources/Plasma/NucleusLib/pnNetProtocol/Private/pnNpCommon.cpp

@ -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)

2
Sources/Plasma/NucleusLib/pnNetProtocol/Private/pnNpCommon.h

@ -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

21
Sources/Plasma/PubUtilLib/plNetCommon/plNetServerSessionInfo.cpp

@ -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
{

2
Sources/Plasma/PubUtilLib/plNetCommon/plNetServerSessionInfo.h

@ -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;

2
Sources/Plasma/PubUtilLib/plNetGameLib/Intern.h

@ -287,7 +287,7 @@ enum ENetTransState {
kTransStateComplete,
};
struct NetTrans : hsAtomicRefCnt {
struct NetTrans : hsRefCnt {
LINK(NetTrans) m_link;
ENetTransState m_state;
ENetError m_result;

4
Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglAuth.cpp

@ -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)

4
Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglFile.cpp

@ -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)

4
Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGame.cpp

@ -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)
{

4
Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglGateKeeper.cpp

@ -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)

2
Sources/Plasma/PubUtilLib/plNetGameLib/Private/plNglTrans.cpp

@ -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)

2
Sources/Plasma/PubUtilLib/plNetMessage/plNetCommonMessage.h

@ -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

10
Sources/Plasma/PubUtilLib/plPipeline/plFogEnvironment.cpp

@ -71,6 +71,16 @@ plFogEnvironment::~plFogEnvironment()
{
}
plFogEnvironment &plFogEnvironment::operator=(const plFogEnvironment &copy)
{
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 )

3
Sources/Plasma/PubUtilLib/plPipeline/plFogEnvironment.h

@ -85,6 +85,9 @@ class plFogEnvironment : public hsKeyedObject
plFogEnvironment( FogType type, float end, float density, hsColorRGBA &color );
~plFogEnvironment();
plFogEnvironment(const plFogEnvironment &copy) { operator=(copy); }
plFogEnvironment &operator=(const plFogEnvironment &copy);
// Sets the parameters for linear fog
void Set( float start, float end, float density, const hsColorRGBA *color = nil );

Loading…
Cancel
Save