CDRMonitor: lazy node creation

This commit is contained in:
Michael Davidsaver
2011-02-08 13:28:02 -05:00
parent 29bbaa60f6
commit 7d3e58fcc9
3 changed files with 39 additions and 6 deletions
+3 -3
View File
@@ -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 ");
+6
View File
@@ -86,5 +86,11 @@ CDRNode::show(FILE *fd)
fprintf(fd,"\n");
}
void
onceNode(void* raw)
{
CDRNodeInstance* inst=static_cast<CDRNodeInstance*>(raw);
inst->node=new CDRNode(inst->name);
}
}}
+30 -3
View File
@@ -12,6 +12,7 @@
#include <string.h>
#include <stdio.h>
#include <epicsThread.h>
#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<void*>(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()
}}