diff --git a/pvDataApp/factory/FieldCreateFactory.cpp b/pvDataApp/factory/FieldCreateFactory.cpp index e8164c4..5200be0 100644 --- a/pvDataApp/factory/FieldCreateFactory.cpp +++ b/pvDataApp/factory/FieldCreateFactory.cpp @@ -36,7 +36,7 @@ public : FieldPvt::FieldPvt(String fieldName,Type type) : fieldName(fieldName),type(type),referenceCount(1) -{field_node.incRef();} +{PVDATA_REFCOUNT_MONITOR_INCREF(field);} static Mutex refCountMutex; @@ -69,7 +69,7 @@ void Field::renameField(String newName) } void Field::incReferenceCount() const { - field_node.incRef(); + PVDATA_REFCOUNT_MONITOR_INCREF(field); Lock xx(&refCountMutex); pImpl->referenceCount++; if(pImpl->type!=structure) return; @@ -82,7 +82,7 @@ void Field::incReferenceCount() const { } void Field::decReferenceCount() const { - field_node.decRef(); + PVDATA_REFCOUNT_MONITOR_DECREF(field); Lock xx(&refCountMutex); if(pImpl->referenceCount<=0) { String message("logicError field "); diff --git a/pvDataApp/misc/CDRMonitor.cpp b/pvDataApp/misc/CDRMonitor.cpp index 7d9c1a4..0e6364b 100644 --- a/pvDataApp/misc/CDRMonitor.cpp +++ b/pvDataApp/misc/CDRMonitor.cpp @@ -86,5 +86,11 @@ CDRNode::show(FILE *fd) fprintf(fd,"\n"); } +void +onceNode(void* raw) +{ + CDRNodeInstance* inst=static_cast(raw); + inst->node=new CDRNode(inst->name); +} }} diff --git a/pvDataApp/misc/CDRMonitor.h b/pvDataApp/misc/CDRMonitor.h index 2ad7d22..924de2f 100644 --- a/pvDataApp/misc/CDRMonitor.h +++ b/pvDataApp/misc/CDRMonitor.h @@ -12,6 +12,7 @@ #include #include +#include #include "noDefaultMethods.h" #include "lock.h" #include "pvType.h" @@ -83,11 +84,37 @@ private: CDRNode * const nextNode; }; -#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) static CDRNode NAME ## _node(#NAME) +struct CDRNodeInstance +{ + CDRNode *node; + epicsThreadOnceId once; + const char* const name; +}; -#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) NAME ## _node.destruct() +void onceNode(void* raw); -#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) NAME ## _node.construct() +static inline +CDRNode* +getNode(CDRNodeInstance *inst) +{ + epicsThreadOnce(&inst->once,&onceNode, + static_cast(inst)); + return inst->node; +} + +#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) \ +static CDRNodeInstance NAME ## _node={0,EPICS_THREAD_ONCE_INIT,#NAME} + +#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) \ + getNode(&NAME ## _node)->destruct() + +#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) \ + getNode(&NAME ## _node)->construct() + +#define PVDATA_REFCOUNT_MONITOR_INCREF(NAME) \ + getNode(&NAME ## _node)->incRef() +#define PVDATA_REFCOUNT_MONITOR_DECREF(NAME) \ + getNode(&NAME ## _node)->decRef() }}