fix problem in PVField::replaceStructure.

There is still a memory leak
This commit is contained in:
Marty Kraimer
2011-01-19 14:29:12 -05:00
parent bb6437fd86
commit f73f18d692
15 changed files with 281 additions and 101 deletions

View File

@@ -314,17 +314,29 @@ void PVField::computeOffset(PVField * pvField,int offset) {
void PVField::replaceStructure(PVStructure *pvStructure,int length)
{
PVFieldPtrArray pvFields = pvStructure->getPVFields();
StructureConstPtr old = static_cast<StructureConstPtr>(pImpl->field);
if(old->getNumberFields() == length) {
FieldConstPtrArray fields = old->getFields();
for(int i=0; i<length; i++) {
FieldConstPtr newField = pvFields[i]->getField();
FieldConstPtr oldField = fields[i];
if(newField==oldField) continue;
oldField->decReferenceCount();
fields[i] = newField;
}
return;
}
FieldConstPtrArray newFields = new FieldConstPtr[length];
for(int i=0; i<length; i++) {
newFields[i] = pvFields[i]->getField();
FieldConstPtr field = pvFields[i]->getField();
field->incReferenceCount();
newFields[i] = field;
}
StructureConstPtr newStructure = getFieldCreate()->createStructure(
pImpl->field->getFieldName(),length, newFields);
PVStructure *parent = pImpl->parent;
if(parent==0) {
pImpl->field->decReferenceCount();
}
pImpl->field->decReferenceCount();
pImpl->field = newStructure;
PVStructure *parent = pImpl->parent;
if(parent!=0) {
parent->replaceStructure(
parent,parent->getStructure()->getNumberFields());

View File

@@ -1,72 +0,0 @@
/*TypeFunc.cpp*/
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <cstddef>
#include <cstdlib>
#include <string>
#include <cstdio>
#include "pvIntrospect.h"
namespace epics { namespace pvData {
void TypeFunc::toString(StringBuilder buf,const Type type) {
static String unknownString = "logic error unknown Type";
switch(type) {
case pvScalar : *buf += "scalar"; break;
case pvScalarArray : *buf += "scalarArray"; break;
case pvStructure : *buf += "structure"; break;
case pvStructureArray : *buf += "structureArray"; break;
default:
throw std::invalid_argument(unknownString);
}
}
bool ScalarTypeFunc::isInteger(ScalarType type) {
if(type>=pvByte && type<=pvLong) return true;
return false;
}
bool ScalarTypeFunc::isNumeric(ScalarType type) {
if(type>=pvByte && type<=pvDouble) return true;
return false;
}
bool ScalarTypeFunc::isPrimitive(ScalarType type) {
if(type>=pvBoolean && type<=pvDouble) return true;
return false;
}
ScalarType ScalarTypeFunc::getScalarType(String pvalue) {
static String unknownString = "error unknown ScalarType";
if(pvalue.compare("boolean")==0) return pvBoolean;
if(pvalue.compare("byte")==0) return pvByte;
if(pvalue.compare("short")==0) return pvShort;
if(pvalue.compare("int")==0) return pvInt;
if(pvalue.compare("long")==0) return pvLong;
if(pvalue.compare("float")==0) return pvFloat;
if(pvalue.compare("double")==0) return pvDouble;
if(pvalue.compare("string")==0) return pvString;
throw std::invalid_argument(unknownString);
}
void ScalarTypeFunc::toString(StringBuilder buf,const ScalarType scalarType) {
static String unknownString = "logic error unknown ScalarType";
switch(scalarType) {
case pvBoolean : *buf += "boolean"; return;
case pvByte : *buf += "byte"; return;;
case pvShort : *buf += "short"; return;
case pvInt : *buf += "int"; return;
case pvLong : *buf += "long"; return;
case pvFloat : *buf += "float"; return;
case pvDouble : *buf += "double"; return;
case pvString : *buf += "string"; return;
}
throw std::invalid_argument(unknownString);
}
}}

View File

@@ -1,20 +1,20 @@
Time test
diff 23.623024 milliSeconds
time per iteration 23.623024 microseconds
time per addTail/removeHead 0.011812 microseconds
diff 23.288030 milliSeconds
time per iteration 23.288030 microseconds
time per addTail/removeHead 0.011644 microseconds
Time test locked
diff 178.929120 milliSeconds
time per iteration 178.929120 microseconds
time per addTail/removeHead 0.089465 microseconds
diff 175.968013 milliSeconds
time per iteration 175.968013 microseconds
time per addTail/removeHead 0.087984 microseconds
Time std::list test
diff 632.698846 milliSeconds
time per iteration 632.698846 microseconds
time per addTail/removeHead 0.316349 microseconds
diff 631.892603 milliSeconds
time per iteration 631.892603 microseconds
time per addTail/removeHead 0.315946 microseconds
Time std::list test locked
diff 788.837800 milliSeconds
time per iteration 788.837800 microseconds
time per addTail/removeHead 0.394419 microseconds
diff 791.255075 milliSeconds
time per iteration 791.255075 microseconds
time per addTail/removeHead 0.395628 microseconds

14
test/testPVAppend Normal file
View File

@@ -0,0 +1,14 @@
structure request
string fieldList value,timeStamp
structure request
string fieldList value,timeStamp
string extra junk
structure parent
structure child1
string value bla
structure child2
string value bla
field: totalConstruct 107 totalDestruct 101 ACTIVE 6
pvField: totalConstruct 8 totalDestruct 8
linkedListNode: totalConstruct 5 totalDestruct 5
linkedList: totalConstruct 1 totalDestruct 1

12
test/testPVAppend.pl Executable file
View File

@@ -0,0 +1,12 @@
eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
if $running_under_some_shell; # testPVAppend.pl
use Env;
system ("rm testPVAppend");
system ("rm testPVAppendDiff");
system ("../bin/${EPICS_HOST_ARCH}/testPVAppend testPVAppend");
system ("diff testPVAppend testPVAppendGold >> testPVAppendDiff");
if(-z "testPVAppendDiff") {
print "testPVAppend OK\n";
} else {
print "testPVAppend Failed\n";
}

0
test/testPVAppendDiff Normal file
View File

14
test/testPVAppendGold Normal file
View File

@@ -0,0 +1,14 @@
structure request
string fieldList value,timeStamp
structure request
string fieldList value,timeStamp
string extra junk
structure parent
structure child1
string value bla
structure child2
string value bla
field: totalConstruct 107 totalDestruct 101 ACTIVE 6
pvField: totalConstruct 8 totalDestruct 8
linkedListNode: totalConstruct 5 totalDestruct 5
linkedList: totalConstruct 1 totalDestruct 1

View File

@@ -283,7 +283,7 @@ structure string
timeStamp timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
field: totalConstruct 136 totalDestruct 136
field: totalConstruct 136 totalDestruct 135 ACTIVE 1
pvField: totalConstruct 281 totalDestruct 281
linkedListNode: totalConstruct 5 totalDestruct 5
linkedList: totalConstruct 1 totalDestruct 1

View File

@@ -0,0 +1,4 @@
286c286
< field: totalConstruct 136 totalDestruct 135 ACTIVE 1
---
> field: totalConstruct 136 totalDestruct 136

View File

@@ -1 +1 @@
time per call 37.293004 microseconds
time per call 40.057018 microseconds

View File

@@ -1,5 +1,5 @@
current 1294842528 236065826 milliSec 1294842528236
2011.01.12 09:28:48 236065826 nanoSeconds isDst false
current 1295462802 840097682 milliSec 1295462802840
2011.01.19 13:46:42 840097682 nanoSeconds isDst false
fromTime_t
current 1294842528 0 milliSec 1294842528000
2011.01.12 09:28:48 0 nanoSeconds isDst false
current 1295462802 0 milliSec 1295462802000
2011.01.19 13:46:42 0 nanoSeconds isDst false

View File

@@ -1,6 +1,6 @@
one requested 0.400000 diff 0.400196 seconds
two requested 0.200000 diff 0.200182 seconds
one requested 0.200000 diff 0.200248 seconds
two requested 0.400000 diff 0.400307 seconds
one requested 0.000000 diff 0.000033 seconds
two requested 0.000000 diff 0.000049 seconds
one requested 0.400000 diff 0.400263 seconds
two requested 0.200000 diff 0.200168 seconds
one requested 0.200000 diff 0.200136 seconds
two requested 0.400000 diff 0.400176 seconds
one requested 0.000000 diff 0.000011 seconds
two requested 0.000000 diff 0.000018 seconds

View File

@@ -2,6 +2,10 @@ TOP=../..
include $(TOP)/configure/CONFIG
PROD_HOST += testPVAppend
testPVAppend_SRCS += testPVAppend.cpp
testPVAppend_LIBS += pvData Com
PROD_HOST += testPVType
testPVType_SRCS += testPVType.cpp
testPVType_LIBS += pvData Com

96
testApp/pv/temp.cpp Normal file
View File

@@ -0,0 +1,96 @@
/* testPVAppend.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/* Author: Marty Kraimer Date: 2010.11 */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <epicsAssert.h>
#include "requester.h"
#include "pvIntrospect.h"
#include "pvData.h"
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
#include "showConstructDestruct.h"
using namespace epics::pvData;
static FieldCreate * fieldCreate = 0;
static PVDataCreate * pvDataCreate = 0;
static StandardField *standardField = 0;
static StandardPVField *standardPVField = 0;
static Convert *convert = 0;
static String builder("");
static String alarmTimeStamp("alarm,timeStamp");
static String alarmTimeStampValueAlarm("alarm,timeStamp,valueAlarm");
static String allProperties("alarm,timeStamp,display,control,valueAlarm");
static void testAppend(FILE * fd)
{
FieldConstPtrArray fields = new FieldConstPtr[0];
PVStructure *pvParent = pvDataCreate->createPVStructure(
0,String("request"),0,fields);
PVString* pvStringField = static_cast<PVString*>(
pvDataCreate->createPVScalar(pvParent, "fieldList", pvString));
pvStringField->put(String("value,timeStamp"));
pvParent->appendPVField(pvStringField);
builder.clear();
pvParent->toString(&builder);
fprintf(fd,"%s\n",builder.c_str());
pvStringField = static_cast<PVString*>(
pvDataCreate->createPVScalar(pvParent, "extra", pvString));
pvStringField->put(String("junk"));
pvParent->appendPVField(pvStringField);
builder.clear();
pvParent->toString(&builder);
fprintf(fd,"%s\n",builder.c_str());
delete pvParent;
PVStructure* pvStructure = pvDataCreate->createPVStructure(
0,"parent", 0);
PVStructure* pvChild1 = pvDataCreate->createPVStructure(
pvStructure, "child1", 0);
pvStringField = static_cast<PVString*>(
pvDataCreate->createPVScalar(pvChild1,"value", pvString));
pvStringField->put("bla");
pvChild1->appendPVField(pvStringField);
pvStructure->appendPVField(pvChild1);
PVStructure* pvChild2 = pvDataCreate->createPVStructure(
pvStructure, "child2", 0);
pvStringField = static_cast<PVString*>(
pvDataCreate->createPVScalar(pvChild2,"value", pvString));
pvStringField->put("bla");
pvChild2->appendPVField(pvStringField);
pvStructure->appendPVField(pvChild2);
builder.clear();
pvStructure->toString(&builder);
fprintf(fd,"%s\n",builder.c_str());
delete pvStructure;
}
int main(int argc,char *argv[])
{
char *fileName = 0;
if(argc>1) fileName = argv[1];
FILE * fd = stdout;
if(fileName!=0 && fileName[0]!=0) {
fd = fopen(fileName,"w+");
}
fieldCreate = getFieldCreate();
pvDataCreate = getPVDataCreate();
standardField = getStandardField();
standardPVField = getStandardPVField();
convert = getConvert();
testAppend(fd);
getShowConstructDestruct()->showDeleteStaticExit(fd);
return(0);
}

View File

@@ -0,0 +1,96 @@
/* testPVAppend.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/* Author: Marty Kraimer Date: 2010.11 */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <epicsAssert.h>
#include "requester.h"
#include "pvIntrospect.h"
#include "pvData.h"
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
#include "showConstructDestruct.h"
using namespace epics::pvData;
static FieldCreate * fieldCreate = 0;
static PVDataCreate * pvDataCreate = 0;
static StandardField *standardField = 0;
static StandardPVField *standardPVField = 0;
static Convert *convert = 0;
static String builder("");
static String alarmTimeStamp("alarm,timeStamp");
static String alarmTimeStampValueAlarm("alarm,timeStamp,valueAlarm");
static String allProperties("alarm,timeStamp,display,control,valueAlarm");
static void testAppend(FILE * fd)
{
FieldConstPtrArray fields = new FieldConstPtr[0];
PVStructure *pvParent = pvDataCreate->createPVStructure(
0,String("request"),0,fields);
PVString* pvStringField = static_cast<PVString*>(
pvDataCreate->createPVScalar(pvParent, "fieldList", pvString));
pvStringField->put(String("value,timeStamp"));
pvParent->appendPVField(pvStringField);
builder.clear();
pvParent->toString(&builder);
fprintf(fd,"%s\n",builder.c_str());
pvStringField = static_cast<PVString*>(
pvDataCreate->createPVScalar(pvParent, "extra", pvString));
pvStringField->put(String("junk"));
pvParent->appendPVField(pvStringField);
builder.clear();
pvParent->toString(&builder);
fprintf(fd,"%s\n",builder.c_str());
delete pvParent;
PVStructure* pvStructure = pvDataCreate->createPVStructure(
0,"parent", 0);
PVStructure* pvChild1 = pvDataCreate->createPVStructure(
pvStructure, "child1", 0);
pvStringField = static_cast<PVString*>(
pvDataCreate->createPVScalar(pvChild1,"value", pvString));
pvStringField->put("bla");
pvChild1->appendPVField(pvStringField);
pvStructure->appendPVField(pvChild1);
PVStructure* pvChild2 = pvDataCreate->createPVStructure(
pvStructure, "child2", 0);
pvStringField = static_cast<PVString*>(
pvDataCreate->createPVScalar(pvChild2,"value", pvString));
pvStringField->put("bla");
pvChild2->appendPVField(pvStringField);
pvStructure->appendPVField(pvChild2);
builder.clear();
pvStructure->toString(&builder);
fprintf(fd,"%s\n",builder.c_str());
delete pvStructure;
}
int main(int argc,char *argv[])
{
char *fileName = 0;
if(argc>1) fileName = argv[1];
FILE * fd = stdout;
if(fileName!=0 && fileName[0]!=0) {
fd = fopen(fileName,"w+");
}
fieldCreate = getFieldCreate();
pvDataCreate = getPVDataCreate();
standardField = getStandardField();
standardPVField = getStandardPVField();
convert = getConvert();
testAppend(fd);
getShowConstructDestruct()->showDeleteStaticExit(fd);
return(0);
}