From fe94ab195174e8e5e556c3e045d2e0c467ad8faf Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Wed, 3 Apr 2013 11:25:48 +0200 Subject: [PATCH] ident fix, testGetPerformance configurable via command-line --- testApp/remote/eget.cpp | 1019 ++++++++--------- testApp/remote/testGetPerformance.cpp | 569 +++++----- testApp/remote/testServer.cpp | 1497 +++++++++++++------------ 3 files changed, 1578 insertions(+), 1507 deletions(-) diff --git a/testApp/remote/eget.cpp b/testApp/remote/eget.cpp index c019f5b..f85e6f8 100644 --- a/testApp/remote/eget.cpp +++ b/testApp/remote/eget.cpp @@ -38,7 +38,7 @@ void formatNTAny(std::ostream& o, PVStructurePtr const & pvStruct) PVFieldPtr value = pvStruct->getSubField("value"); if (value.get() == 0) { - std::cerr << "no 'value' field in NTAny" << std::endl; + std::cerr << "no 'value' field in NTAny" << std::endl; return; } @@ -50,7 +50,7 @@ void formatNTScalar(std::ostream& o, PVStructurePtr const & pvStruct) PVScalarPtr value = dynamic_pointer_cast(pvStruct->getSubField("value")); if (value.get() == 0) { - std::cerr << "no scalar_t 'value' field in NTScalar" << std::endl; + std::cerr << "no scalar_t 'value' field in NTScalar" << std::endl; return; } @@ -58,57 +58,57 @@ void formatNTScalar(std::ostream& o, PVStructurePtr const & pvStruct) } std::ostream& formatVector(std::ostream& o, - String label, - PVScalarArrayPtr const & pvScalarArray, - bool transpose) + String label, + PVScalarArrayPtr const & pvScalarArray, + bool transpose) { - size_t len = pvScalarArray->getLength(); + size_t len = pvScalarArray->getLength(); - if (!transpose) - { - if (!label.empty()) - o << label << std::endl; + if (!transpose) + { + if (!label.empty()) + o << label << std::endl; - for (size_t i = 0; i < len; i++) - pvScalarArray->dumpValue(o, i) << std::endl; - } - else - { - bool first = true; - if (!label.empty()) - { - o << label; - first = false; - } + for (size_t i = 0; i < len; i++) + pvScalarArray->dumpValue(o, i) << std::endl; + } + else + { + bool first = true; + if (!label.empty()) + { + o << label; + first = false; + } - for (size_t i = 0; i < len; i++) { - if (first) - first = false; - else - o << fieldSeparator; + for (size_t i = 0; i < len; i++) { + if (first) + first = false; + else + o << fieldSeparator; - pvScalarArray->dumpValue(o, i); - } - } + pvScalarArray->dumpValue(o, i); + } + } - return o; + return o; } /* std::ostream& formatScalarArray(std::ostream& o, PVScalarArrayPtr const & pvScalarArray) { - size_t len = pvScalarArray->getLength(); - if (len == 0) - { - // TODO do we really want this - o << "(empty)" << std::endl; - } - else - { - for (size_t i = 0; i < len; i++) - pvScalarArray->dumpValue(o, i) << std::endl; - } - return o; + size_t len = pvScalarArray->getLength(); + if (len == 0) + { + // TODO do we really want this + o << "(empty)" << std::endl; + } + else + { + for (size_t i = 0; i < len; i++) + pvScalarArray->dumpValue(o, i) << std::endl; + } + return o; } */ @@ -117,7 +117,7 @@ void formatNTScalarArray(std::ostream& o, PVStructurePtr const & pvStruct) PVScalarArrayPtr value = dynamic_pointer_cast(pvStruct->getSubField("value")); if (value.get() == 0) { - std::cerr << "no scalar_t[] 'value' field in NTScalarArray" << std::endl; + std::cerr << "no scalar_t[] 'value' field in NTScalarArray" << std::endl; return; } @@ -128,30 +128,30 @@ void formatNTScalarArray(std::ostream& o, PVStructurePtr const & pvStruct) size_t getLongestString(vector const & array) { - size_t max = 0; - size_t len = array.size(); + size_t max = 0; + size_t len = array.size(); for (size_t i = 0; i < len; i++) { - size_t l = array[i].size(); - if (l > max) max = l; + size_t l = array[i].size(); + if (l > max) max = l; } return max; } size_t getLongestString(PVScalarArrayPtr const & array) { - size_t max = 0; + size_t max = 0; - string empty; + string empty; - ostringstream oss; - size_t len = array->getLength(); + ostringstream oss; + size_t len = array->getLength(); for (size_t i = 0; i < len; i++) { - oss.str(empty); - array->dumpValue(oss, i); - size_t l = oss.tellp(); - if (l > max) max = l; + oss.str(empty); + array->dumpValue(oss, i); + size_t l = oss.tellp(); + if (l > max) max = l; } return max; } @@ -159,11 +159,11 @@ size_t getLongestString(PVScalarArrayPtr const & array) // labels are optional // if provided labels.size() must equals columnData.size() void formatTable(std::ostream& o, - vector const & labels, - vector const & columnData, - bool transpose) + vector const & labels, + vector const & columnData, + bool transpose) { - // array with maximum number of elements + // array with maximum number of elements size_t maxValues = 0; // value with longest string form @@ -175,15 +175,15 @@ void formatTable(std::ostream& o, size_t numColumns = columnData.size(); for (size_t i = 0; i < numColumns; i++) { - PVScalarArrayPtr array = columnData[i]; - if (array.get()) - { - size_t arrayLength = array->getLength(); - if (maxValues < arrayLength) maxValues = arrayLength; + PVScalarArrayPtr array = columnData[i]; + if (array.get()) + { + size_t arrayLength = array->getLength(); + if (maxValues < arrayLength) maxValues = arrayLength; - size_t colLen = getLongestString(array); - if (colLen > maxColumnLength) maxColumnLength = colLen; - } + size_t colLen = getLongestString(array); + if (colLen > maxColumnLength) maxColumnLength = colLen; + } } // add some space @@ -193,62 +193,62 @@ void formatTable(std::ostream& o, if (!transpose) { - // - // , , ... - // values values ... - // + // + // , , ... + // values values ... + // - // first print labels - if (labels.size()) - { - for (size_t i = 0; i < numColumns; i++) - { - o << std::setw(maxColumnLength) << std::right << labels[i]; - } - o << std::endl; - } + // first print labels + if (labels.size()) + { + for (size_t i = 0; i < numColumns; i++) + { + o << std::setw(maxColumnLength) << std::right << labels[i]; + } + o << std::endl; + } - // then values - for (size_t r = 0; r < maxValues; r++) - { - for (size_t i = 0; i < numColumns; i++) - { - o << std::setw(maxColumnLength) << std::right; - PVScalarArrayPtr array = columnData[i]; - if (array.get() && r < array->getLength()) - array->dumpValue(o, r); - else - o << ""; - } - o << std::endl; - } + // then values + for (size_t r = 0; r < maxValues; r++) + { + for (size_t i = 0; i < numColumns; i++) + { + o << std::setw(maxColumnLength) << std::right; + PVScalarArrayPtr array = columnData[i]; + if (array.get() && r < array->getLength()) + array->dumpValue(o, r); + else + o << ""; + } + o << std::endl; + } } else { - // - // values... - // values... - // ... - // + // + // values... + // values... + // ... + // - for (size_t i = 0; i < numColumns; i++) - { - if (labels.size()) - o << std::setw(maxColumnLength) << std::left << labels[i]; + for (size_t i = 0; i < numColumns; i++) + { + if (labels.size()) + o << std::setw(maxColumnLength) << std::left << labels[i]; - for (size_t r = 0; r < maxValues; r++) - { - o << std::setw(maxColumnLength) << std::right; - PVScalarArrayPtr array = columnData[i]; - if (array.get() && r < array->getLength()) - array->dumpValue(o, r); - else - o << ""; - } - o << std::endl; - } + for (size_t r = 0; r < maxValues; r++) + { + o << std::setw(maxColumnLength) << std::right; + PVScalarArrayPtr array = columnData[i]; + if (array.get() && r < array->getLength()) + array->dumpValue(o, r); + else + o << ""; + } + o << std::endl; + } } } @@ -258,14 +258,14 @@ void formatNTTable(std::ostream& o, PVStructurePtr const & pvStruct) PVStringArrayPtr labels = dynamic_pointer_cast(pvStruct->getScalarArrayField("labels", pvString)); if (labels.get() == 0) { - std::cerr << "no string[] 'labels' field in NTTable" << std::endl; + std::cerr << "no string[] 'labels' field in NTTable" << std::endl; return; } PVStructurePtr value = pvStruct->getStructureField("value"); if (value.get() == 0) { - std::cerr << "no 'value' structure in NTTable" << std::endl; + std::cerr << "no 'value' structure in NTTable" << std::endl; return; } @@ -275,18 +275,18 @@ void formatNTTable(std::ostream& o, PVStructurePtr const & pvStruct) if (labels->getLength() != numColumns) { - std::cerr << "malformed NTTable, length of 'labels' array does not equal to a number of 'value' structure subfields" << std::endl; - return; + std::cerr << "malformed NTTable, length of 'labels' array does not equal to a number of 'value' structure subfields" << std::endl; + return; } for (size_t i = 0; i < numColumns; i++) { - PVScalarArrayPtr array = dynamic_pointer_cast(fields[i]); - if (array.get() == 0) - { - std::cerr << "malformed NTTable, " << (i+1) << ". field is not scalar_t[]" << std::endl; - return; - } + PVScalarArrayPtr array = dynamic_pointer_cast(fields[i]); + if (array.get() == 0) + { + std::cerr << "malformed NTTable, " << (i+1) << ". field is not scalar_t[]" << std::endl; + return; + } columnData.push_back(array); } @@ -304,7 +304,7 @@ void formatNTMatrix(std::ostream& o, PVStructurePtr const & pvStruct) PVDoubleArrayPtr value = dynamic_pointer_cast(pvStruct->getScalarArrayField("value", pvDouble)); if (value.get() == 0) { - std::cerr << "no double[] 'value' field in NTMatrix" << std::endl; + std::cerr << "no double[] 'value' field in NTMatrix" << std::endl; return; } @@ -313,30 +313,30 @@ void formatNTMatrix(std::ostream& o, PVStructurePtr const & pvStruct) PVIntArrayPtr dim = dynamic_pointer_cast(pvStruct->getScalarArrayField("dim", pvInt)); if (dim.get() != 0) { - // dim[] = { rows, columns } - size_t dims = dim->getLength(); - if (dims != 1 && dims != 2) - { - std::cerr << "malformed NTMatrix, dim[] must contain 1 or 2 elements instead of " << dims << std::endl; - return; - } + // dim[] = { rows, columns } + size_t dims = dim->getLength(); + if (dims != 1 && dims != 2) + { + std::cerr << "malformed NTMatrix, dim[] must contain 1 or 2 elements instead of " << dims << std::endl; + return; + } - IntArrayData data; - dim->get(0, dims, data); - rows = data.data[0]; - cols = (dims == 2) ? data.data[1] : 1; + IntArrayData data; + dim->get(0, dims, data); + rows = data.data[0]; + cols = (dims == 2) ? data.data[1] : 1; - if (rows <= 0 || cols <= 0) - { - std::cerr << "malformed NTMatrix, dim[] must contain elements > 0" << std::endl; - return; - } + if (rows <= 0 || cols <= 0) + { + std::cerr << "malformed NTMatrix, dim[] must contain elements > 0" << std::endl; + return; + } } else { - // column vector - rows = value->getLength(); - cols = 1; + // column vector + rows = value->getLength(); + cols = 1; } o << std::left; @@ -344,8 +344,8 @@ void formatNTMatrix(std::ostream& o, PVStructurePtr const & pvStruct) size_t len = static_cast(rows*cols); if (len != value->getLength()) { - std::cerr << "malformed NTMatrix, values[] must contain " << len << " elements instead of " << value->getLength() << std::endl; - return; + std::cerr << "malformed NTMatrix, values[] must contain " << len << " elements instead of " << value->getLength() << std::endl; + return; } // add some space @@ -356,46 +356,46 @@ void formatNTMatrix(std::ostream& o, PVStructurePtr const & pvStruct) if (mode != TerseMode) { - // - // el1 el2 el3 - // el4 el5 el6 - // + // + // el1 el2 el3 + // el4 el5 el6 + // - size_t ix = 0; - for (int32 r = 0; r < rows; r++) - { - for (int32 c = 0; c < cols; c++) - { - o << std::setw(maxColumnLength) << std::right; - if (columnMajor) - value->dumpValue(o, r + c * rows); - else - value->dumpValue(o, ix++); - } - o << std::endl; - } + size_t ix = 0; + for (int32 r = 0; r < rows; r++) + { + for (int32 c = 0; c < cols; c++) + { + o << std::setw(maxColumnLength) << std::right; + if (columnMajor) + value->dumpValue(o, r + c * rows); + else + value->dumpValue(o, ix++); + } + o << std::endl; + } } else { - // - // el1 el4 - // el2 el5 - // el3 el6 - // - size_t ix = 0; - for (int32 c = 0; c < cols; c++) - { - for (int32 r = 0; r < rows; r++) - { - o << std::setw(maxColumnLength) << std::right; - if (columnMajor) - value->dumpValue(o, ix++); - else - value->dumpValue(o, r * cols + c); - } - o << std::endl; - } + // + // el1 el4 + // el2 el5 + // el3 el6 + // + size_t ix = 0; + for (int32 c = 0; c < cols; c++) + { + for (int32 r = 0; r < rows; r++) + { + o << std::setw(maxColumnLength) << std::right; + if (columnMajor) + value->dumpValue(o, ix++); + else + value->dumpValue(o, r * cols + c); + } + o << std::endl; + } } } @@ -405,41 +405,41 @@ void formatNTNameValue(std::ostream& o, PVStructurePtr const & pvStruct) PVStringArrayPtr name = dynamic_pointer_cast(pvStruct->getScalarArrayField("name", pvString)); if (name.get() == 0) { - std::cerr << "no string[] 'name' field in NTNameValue" << std::endl; + std::cerr << "no string[] 'name' field in NTNameValue" << std::endl; return; } PVFieldPtr value = pvStruct->getSubField("value"); if (value.get() == 0) { - std::cerr << "no 'value' field in NTNameValue" << std::endl; + std::cerr << "no 'value' field in NTNameValue" << std::endl; return; } - PVScalarArrayPtr array = dynamic_pointer_cast(value); - if (array.get() == 0) - { - std::cerr << "malformed NTNameValue, 'value' field is not scalar_t[]" << std::endl; - return; - } - - if (name->getLength() != array->getLength()) + PVScalarArrayPtr array = dynamic_pointer_cast(value); + if (array.get() == 0) { - std::cerr << "malformed NTNameValue, length of 'name' and 'value' array does not equal" << std::endl; - return; + std::cerr << "malformed NTNameValue, 'value' field is not scalar_t[]" << std::endl; + return; } - size_t numColumns = name->getLength(); + if (name->getLength() != array->getLength()) + { + std::cerr << "malformed NTNameValue, length of 'name' and 'value' array does not equal" << std::endl; + return; + } - // get names + size_t numColumns = name->getLength(); + + // get names StringArrayData nameData; name->get(0, name->getLength(), nameData); // get max column size size_t maxColumnLength = getLongestString(nameData.data); - size_t valueLen = getLongestString(array); - if (valueLen > maxColumnLength) maxColumnLength = valueLen; + size_t valueLen = getLongestString(array); + if (valueLen > maxColumnLength) maxColumnLength = valueLen; // add some space size_t padding = 2; @@ -449,42 +449,42 @@ void formatNTNameValue(std::ostream& o, PVStructurePtr const & pvStruct) if (transpose) { - // - // , , ... - // value values ... - // + // + // , , ... + // value values ... + // - // first print names - for (size_t i = 0; i < numColumns; i++) - { - o << std::setw(maxColumnLength) << std::right << nameData.data[i]; - } - o << std::endl; + // first print names + for (size_t i = 0; i < numColumns; i++) + { + o << std::setw(maxColumnLength) << std::right << nameData.data[i]; + } + o << std::endl; - // then values - for (size_t i = 0; i < numColumns; i++) - { - o << std::setw(maxColumnLength) << std::right; - array->dumpValue(o, i); - } - o << std::endl; + // then values + for (size_t i = 0; i < numColumns; i++) + { + o << std::setw(maxColumnLength) << std::right; + array->dumpValue(o, i); + } + o << std::endl; } else { - // - // values... - // values... - // ... - // + // + // values... + // values... + // ... + // - for (size_t i = 0; i < numColumns; i++) - { - o << std::setw(maxColumnLength) << std::left << nameData.data[i]; - o << std::setw(maxColumnLength) << std::right; - array->dumpValue(o, i); - o << std::endl; - } + for (size_t i = 0; i < numColumns; i++) + { + o << std::setw(maxColumnLength) << std::left << nameData.data[i]; + o << std::setw(maxColumnLength) << std::right; + array->dumpValue(o, i); + o << std::endl; + } } @@ -495,7 +495,7 @@ void formatNTURI(std::ostream& o, PVStructurePtr const & pvStruct) PVStringPtr scheme = dynamic_pointer_cast(pvStruct->getStringField("scheme")); if (scheme.get() == 0) { - std::cerr << "no string 'scheme' field in NTURI" << std::endl; + std::cerr << "no string 'scheme' field in NTURI" << std::endl; } PVStringPtr authority = dynamic_pointer_cast(pvStruct->getSubField("authority")); @@ -503,36 +503,36 @@ void formatNTURI(std::ostream& o, PVStructurePtr const & pvStruct) PVStringPtr path = dynamic_pointer_cast(pvStruct->getStringField("path")); if (path.get() == 0) { - std::cerr << "no string 'path' field in NTURI" << std::endl; + std::cerr << "no string 'path' field in NTURI" << std::endl; return; } PVStructurePtr query = dynamic_pointer_cast(pvStruct->getSubField("query")); - o << scheme->get() << "://"; + o << scheme->get() << "://"; if (authority.get()) o << authority->get(); o << '/' << path->get(); // query if (query.get()) { - PVFieldPtrArray fields = query->getPVFields(); - size_t numColumns = fields.size(); + PVFieldPtrArray fields = query->getPVFields(); + size_t numColumns = fields.size(); - if (numColumns > 0) - { - o << '?'; + if (numColumns > 0) + { + o << '?'; - for (size_t i = 0; i < numColumns; i++) - { - if (i) - o << '&'; + for (size_t i = 0; i < numColumns; i++) + { + if (i) + o << '&'; - // TODO encode value!!! - o << fields[i]->getFieldName() << '=' << *(fields[i].get()); - } - } - } + // TODO encode value!!! + o << fields[i]->getFieldName() << '=' << *(fields[i].get()); + } + } + } o << std::endl; } @@ -590,20 +590,20 @@ void formatNTImage(std::ostream& /*o*/, PVStructurePtr const & pvStruct) else { std::cerr << "malformed NTImage, dim[] is invalid for specified color mode" << std::endl; - return; + return; } if (rows <= 0 || cols <= 0) { - std::cerr << "malformed NTImage, dim[] must contain elements > 0" << std::endl; - return; + std::cerr << "malformed NTImage, dim[] must contain elements > 0" << std::endl; + return; } PVByteArrayPtr array = dynamic_pointer_cast(value); if (array.get() == 0) { std::cerr << "currently only byte[] value field is supported" << std::endl; - return; + return; } if (array->getLength() != imageSize) @@ -672,24 +672,30 @@ NTFormatterLUTMap ntFormatterLUT; void initializeNTFormatterLUT() { - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTScalar"] = formatNTScalar; - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTScalarArray"] = formatNTScalarArray; - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTTable"] = formatNTTable; - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTMatrix"] = formatNTMatrix; - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTAny"] = formatNTAny; - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTNameValue"] = formatNTNameValue; - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTURI"] = formatNTURI; - ntFormatterLUT["uri:ev4:nt/2012/pwd:NTImage"] = formatNTImage; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTScalar"] = formatNTScalar; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTScalarArray"] = formatNTScalarArray; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTTable"] = formatNTTable; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTMatrix"] = formatNTMatrix; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTAny"] = formatNTAny; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTNameValue"] = formatNTNameValue; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTURI"] = formatNTURI; + ntFormatterLUT["uri:ev4:nt/2012/pwd:NTImage"] = formatNTImage; } void formatNT(std::ostream& o, PVFieldPtr const & pv) { - static bool lutInitialized = false; - if (!lutInitialized) - { - initializeNTFormatterLUT(); - lutInitialized = true; - } + static bool lutInitialized = false; + if (!lutInitialized) + { + initializeNTFormatterLUT(); + lutInitialized = true; + } + + if (pv.get() == 0) + { + o << "(null)" << std::endl; + return; + } Type type = pv->getField()->getType(); if (type==structure) @@ -701,7 +707,7 @@ void formatNT(std::ostream& o, PVFieldPtr const & pv) NTFormatterLUTMap::const_iterator formatter = ntFormatterLUT.find(id); if (formatter != ntFormatterLUT.end()) { - (formatter->second)(o, pvStruct); + (formatter->second)(o, pvStruct); } else { @@ -721,86 +727,86 @@ void formatNT(std::ostream& o, PVFieldPtr const & pv) void printValue(String const & channelName, PVStructure::shared_pointer const & pv) { - if (mode == ValueOnlyMode) - { - PVField::shared_pointer value = pv->getSubField("value"); - if (value.get() == 0) - { - std::cerr << "no 'value' field" << std::endl; - std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; - } - else - { - Type valueType = value->getField()->getType(); - if (valueType == scalar) - std::cout << *(value.get()) << std::endl; - else if (valueType == scalarArray) - { - //formatScalarArray(std::cout, dynamic_pointer_cast(value)); - formatVector(std::cout, "", dynamic_pointer_cast(value), false); - } - else - { - // switch to structure mode - std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; - } - } - } - else if (mode == TerseMode) - terseStructure(std::cout, pv) << std::endl; - else - std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; + if (mode == ValueOnlyMode) + { + PVField::shared_pointer value = pv->getSubField("value"); + if (value.get() == 0) + { + std::cerr << "no 'value' field" << std::endl; + std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; + } + else + { + Type valueType = value->getField()->getType(); + if (valueType == scalar) + std::cout << *(value.get()) << std::endl; + else if (valueType == scalarArray) + { + //formatScalarArray(std::cout, dynamic_pointer_cast(value)); + formatVector(std::cout, "", dynamic_pointer_cast(value), false); + } + else + { + // switch to structure mode + std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; + } + } + } + else if (mode == TerseMode) + terseStructure(std::cout, pv) << std::endl; + else + std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; } // only in ValueOnlyMode void printValues(vector const & names, vector const & values) { - size_t len = values.size(); + size_t len = values.size(); - vector scalars; - vector scalarArrays; + vector scalars; + vector scalarArrays; - for (size_t i = 0; i < len; i++) - { - PVField::shared_pointer value = values[i]->getSubField("value"); - if (value.get() != 0) - { - Type type = value->getField()->getType(); - if (type == scalarArray) - scalarArrays.push_back(dynamic_pointer_cast(value)); - else if (type == scalar) - { - scalars.push_back(dynamic_pointer_cast(value)); + for (size_t i = 0; i < len; i++) + { + PVField::shared_pointer value = values[i]->getSubField("value"); + if (value.get() != 0) + { + Type type = value->getField()->getType(); + if (type == scalarArray) + scalarArrays.push_back(dynamic_pointer_cast(value)); + else if (type == scalar) + { + scalars.push_back(dynamic_pointer_cast(value)); - // TODO also try to make an PVStringArray out of a scalar - } - } - } + // TODO also try to make an PVStringArray out of a scalar + } + } + } - if (scalars.size() == len) - { - bool first = true; - for (size_t i = 0; i < len; i++) - { - if (first) - first = false; - else - std::cout << fieldSeparator; - std::cout << *(scalars[i].get()); - } - std::cout << std::endl; - } - else if (scalarArrays.size() == len) - { - // TODO labels switch - formatTable(std::cout, names, scalarArrays, false); - } - else - { - // classic output - for (size_t i = 0; i < len; i++) - printValue(names[i], values[i]); - } + if (scalars.size() == len) + { + bool first = true; + for (size_t i = 0; i < len; i++) + { + if (first) + first = false; + else + std::cout << fieldSeparator; + std::cout << *(scalars[i].get()); + } + std::cout << std::endl; + } + else if (scalarArrays.size() == len) + { + // TODO labels switch + formatTable(std::cout, names, scalarArrays, false); + } + else + { + // classic output + for (size_t i = 0; i < len; i++) + printValue(names[i], values[i]); + } } #define DEFAULT_TIMEOUT 3.0 @@ -813,36 +819,36 @@ string request(DEFAULT_REQUEST); void usage (void) { fprintf (stderr, "\nUsage: eget [options] [... | -s ]\n\n" - " -h: Help: Print this message\n" - "\noptions:\n" - " -s : Service API compliant based RPC service name (accepts NTURI request argument)\n" - " -a : Service argument in form 'name[=value]'\n" - " -r : Get request string, specifies what fields to return and options, default is '%s'\n" - " -w : Wait time, specifies timeout, default is %f second(s)\n" - " -q: Pure pvAccess RPC based service (send NTURI.query as request argument)\n" - " -n: Do not format NT types, dump structure instead.\n" - " -t: Terse mode / transpose vector, table, matrix.\n" - " -x: Use column-major order to decode matrix.\n" - " -d: Enable debug output\n" - " -F : Use as an alternate output field separator\n" - " -c: Wait for clean shutdown and report used instance count (for expert users)" - "\n\nexamples:\n\n" -"#! Get the value of the PV corr:li32:53:bdes\n" -"> eget corr:li32:53:bdes\n" -"\n" -"#! Get the table of all correctors from the rdb service\n" -"> eget -s rdbService -a entity=swissfel:devicenames\n" -"\n" -"#! Get the archive history of quad45:bdes;history between 2 times, from the archive service\n" -"> eget -s archiveService -a entity=quad45:bdes;history -a starttime=2012-02-12T10:04:56 -a endtime=2012-02-01T10:04:56\n" -"\n" + " -h: Help: Print this message\n" + "\noptions:\n" + " -s : Service API compliant based RPC service name (accepts NTURI request argument)\n" + " -a : Service argument in form 'name[=value]'\n" + " -r : Get request string, specifies what fields to return and options, default is '%s'\n" + " -w : Wait time, specifies timeout, default is %f second(s)\n" + " -q: Pure pvAccess RPC based service (send NTURI.query as request argument)\n" + " -n: Do not format NT types, dump structure instead.\n" + " -t: Terse mode / transpose vector, table, matrix.\n" + " -x: Use column-major order to decode matrix.\n" + " -d: Enable debug output\n" + " -F : Use as an alternate output field separator\n" + " -c: Wait for clean shutdown and report used instance count (for expert users)" + "\n\nexamples:\n\n" + "#! Get the value of the PV corr:li32:53:bdes\n" + "> eget corr:li32:53:bdes\n" + "\n" + "#! Get the table of all correctors from the rdb service\n" + "> eget -s rdbService -a entity=swissfel:devicenames\n" + "\n" + "#! Get the archive history of quad45:bdes;history between 2 times, from the archive service\n" + "> eget -s archiveService -a entity=quad45:bdes;history -a starttime=2012-02-12T10:04:56 -a endtime=2012-02-01T10:04:56\n" + "\n" , DEFAULT_REQUEST, DEFAULT_TIMEOUT); } class ChannelGetRequesterImpl : public ChannelGetRequester { - private: +private: String m_channelName; bool m_printValue; @@ -854,12 +860,12 @@ class ChannelGetRequesterImpl : public ChannelGetRequester bool m_done; - public: +public: ChannelGetRequesterImpl(String channelName, bool printValue) : - m_channelName(channelName), - m_printValue(printValue), - m_done(false) + m_channelName(channelName), + m_printValue(printValue), + m_done(false) { } @@ -874,7 +880,7 @@ class ChannelGetRequesterImpl : public ChannelGetRequester } virtual void channelGetConnect(const epics::pvData::Status& status,ChannelGet::shared_pointer const & channelGet, - epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::PVStructure::shared_pointer const & pvStructure, epics::pvData::BitSet::shared_pointer const & bitSet) { if (status.isSuccess()) @@ -916,15 +922,15 @@ class ChannelGetRequesterImpl : public ChannelGetRequester { Lock lock(m_pointerMutex); { - m_done = true; + m_done = true; - if (m_printValue) - { - // needed since we access the data - ScopedLock dataLock(m_channelGet); + if (m_printValue) + { + // needed since we access the data + ScopedLock dataLock(m_channelGet); - printValue(m_channelName, m_pvStructure); - } + printValue(m_channelName, m_pvStructure); + } } // this is OK since callee holds also owns it @@ -952,22 +958,22 @@ class ChannelGetRequesterImpl : public ChannelGetRequester bool waitUntilGet(double timeOut) { - bool signaled = m_event.wait(timeOut); - if (!signaled) - { + bool signaled = m_event.wait(timeOut); + if (!signaled) + { std::cerr << "[" << m_channelName << "] get timeout" << std::endl; return false; - } + } - Lock lock(m_pointerMutex); - return m_done; + Lock lock(m_pointerMutex); + return m_done; } }; class ChannelRPCRequesterImpl : public ChannelRPCRequester { - private: +private: ChannelRPC::shared_pointer m_channelRPC; Mutex m_pointerMutex; Event m_event; @@ -977,7 +983,7 @@ class ChannelRPCRequesterImpl : public ChannelRPCRequester PVStructure::shared_pointer m_lastResponse; bool m_done; - public: +public: ChannelRPCRequesterImpl(String channelName) : m_channelName(channelName), m_done(false) {} @@ -1071,32 +1077,32 @@ class ChannelRPCRequesterImpl : public ChannelRPCRequester bool waitUntilRPC(double timeOut) { - bool signaled = m_event.wait(timeOut); - if (!signaled) - { + bool signaled = m_event.wait(timeOut); + if (!signaled) + { std::cerr << "[" << m_channelName << "] RPC timeout" << std::endl; return false; - } + } - Lock lock(m_pointerMutex); - return m_done; + Lock lock(m_pointerMutex); + return m_done; } bool waitUntilConnected(double timeOut) { - bool signaled = m_connectionEvent.wait(timeOut); - if (!signaled) - { + bool signaled = m_connectionEvent.wait(timeOut); + if (!signaled) + { std::cerr << "[" << m_channelName << "] RPC create timeout" << std::endl; return false; - } + } bool connected; - { - Lock lock(m_pointerMutex); + { + Lock lock(m_pointerMutex); connected = (m_channelRPC.get() != 0); } - return connected ? true : false; + return connected ? true : false; } }; @@ -1148,9 +1154,9 @@ int main (int argc, char *argv[]) request = optarg; // do not override terse mode if (mode == ValueOnlyMode) mode = StructureMode; - break; + break; case 'a': /* Service parameters */ - { + { string param = optarg; size_t eqPos = param.find('='); if (eqPos==string::npos) @@ -1165,7 +1171,7 @@ int main (int argc, char *argv[]) } /* if (urlEncodedRequest.size()) - urlEncodedRequest += '&'; + urlEncodedRequest += '&'; char* encoded = url_encode(optarg); urlEncodedRequest += encoded; free(encoded); @@ -1262,20 +1268,20 @@ int main (int argc, char *argv[]) pvs.push_back(argv[optind]); /* Copy PV names from command line */ PVStructure::shared_pointer pvRequest = - getCreateRequest()->createRequest(request, requester); + getCreateRequest()->createRequest(request, requester); if(pvRequest.get()==0) { - fprintf(stderr, "failed to parse request string\n"); + fprintf(stderr, "failed to parse request string\n"); return 1; } ClientFactory::start(); ChannelProvider::shared_pointer provider = getChannelAccess()->getProvider("pvAccess"); - + // first connect to all, this allows resource (e.g. TCP connection) sharing vector channels(nPvs); for (int n = 0; n < nPvs; n++) { - shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); + shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); channels[n] = provider->createChannel(pvs[n], channelRequesterImpl); } @@ -1291,65 +1297,65 @@ int main (int argc, char *argv[]) for (int n = 0; n < nPvs; n++) { /* - shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); + shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); Channel::shared_pointer channel = provider->createChannel(pvs[n], channelRequesterImpl); */ Channel::shared_pointer channel = channels[n]; shared_ptr channelRequesterImpl = dynamic_pointer_cast(channel->getChannelRequester()); - + if (channelRequesterImpl->waitUntilConnected(timeOut)) { - shared_ptr getFieldRequesterImpl; + shared_ptr getFieldRequesterImpl; - // probe for value field - // but only if there is only one PV request (otherwise mode change makes a mess) - if (mode == ValueOnlyMode && nPvs == 1) - { - getFieldRequesterImpl.reset(new GetFieldRequesterImpl(channel)); - // get all to be immune to bad clients not supporting selective getField request - channel->getField(getFieldRequesterImpl, ""); - } + // probe for value field + // but only if there is only one PV request (otherwise mode change makes a mess) + if (mode == ValueOnlyMode && nPvs == 1) + { + getFieldRequesterImpl.reset(new GetFieldRequesterImpl(channel)); + // get all to be immune to bad clients not supporting selective getField request + channel->getField(getFieldRequesterImpl, ""); + } - if (getFieldRequesterImpl.get() == 0 || - getFieldRequesterImpl->waitUntilFieldGet(timeOut)) - { - // check probe - if (getFieldRequesterImpl.get()) - { - Structure::const_shared_pointer structure = - dynamic_pointer_cast(getFieldRequesterImpl->getField()); - if (structure.get() == 0 || structure->getField("value").get() == 0) - { - // fallback to structure - mode = StructureMode; - pvRequest = getCreateRequest()->createRequest("field()", requester); - } - } + if (getFieldRequesterImpl.get() == 0 || + getFieldRequesterImpl->waitUntilFieldGet(timeOut)) + { + // check probe + if (getFieldRequesterImpl.get()) + { + Structure::const_shared_pointer structure = + dynamic_pointer_cast(getFieldRequesterImpl->getField()); + if (structure.get() == 0 || structure->getField("value").get() == 0) + { + // fallback to structure + mode = StructureMode; + pvRequest = getCreateRequest()->createRequest("field()", requester); + } + } - shared_ptr getRequesterImpl( - new ChannelGetRequesterImpl(channel->getChannelName(), false) - ); + shared_ptr getRequesterImpl( + new ChannelGetRequesterImpl(channel->getChannelName(), false) + ); ChannelGet::shared_pointer channelGet = channel->createChannelGet(getRequesterImpl, pvRequest); bool ok = getRequesterImpl->waitUntilGet(timeOut); allOK &= ok; if (ok && collectValues) { - collectedValues.push_back(getRequesterImpl->getPVStructure()); - // no labels collectedNames.push_back(channel->getChannelName()); + collectedValues.push_back(getRequesterImpl->getPVStructure()); + // no labels collectedNames.push_back(channel->getChannelName()); } else { - // print immediately - printValue(channel->getChannelName(), getRequesterImpl->getPVStructure()); + // print immediately + printValue(channel->getChannelName(), getRequesterImpl->getPVStructure()); } - } - else - { - allOK = false; + } + else + { + allOK = false; channel->destroy(); std::cerr << "[" << channel->getChannelName() << "] failed to get channel introspection data" << std::endl; - } + } } else { @@ -1360,64 +1366,64 @@ int main (int argc, char *argv[]) } if (collectValues) - printValues(collectedNames, collectedValues); - + printValues(collectedNames, collectedValues); + ClientFactory::stop(); } // service RPC mode else { - String authority; + String authority; - if (validURI) - { - if (uri.protocol != "pva") - { + if (validURI) + { + if (uri.protocol != "pva") + { std::cerr << "invalid URI scheme '" << uri.protocol << "', only 'pva' is supported" << std::endl; - // TODO + // TODO return 1; - } + } - authority = uri.host; + authority = uri.host; - if (uri.path.length() <= 1) - { + if (uri.path.length() <= 1) + { std::cerr << "invalid URI, empty path" << std::endl; - // TODO + // TODO return 1; - } + } - // skip trailing '/' - service = uri.path.substr(1); + // skip trailing '/' + service = uri.path.substr(1); - string::const_iterator end_i = uri.query.end(); - string::const_iterator begin_i = uri.query.begin(); - while (begin_i != end_i) - { - string::const_iterator pair_end_i = find(begin_i, end_i, '&'); + string::const_iterator end_i = uri.query.end(); + string::const_iterator begin_i = uri.query.begin(); + while (begin_i != end_i) + { + string::const_iterator pair_end_i = find(begin_i, end_i, '&'); - string::const_iterator name_end_i = find(begin_i, pair_end_i, '='); - if (name_end_i != pair_end_i) - { - string name(begin_i, name_end_i); - string value(name_end_i+1, pair_end_i); - parameters.push_back(pair(name, value)); - } - else - { + string::const_iterator name_end_i = find(begin_i, pair_end_i, '='); + if (name_end_i != pair_end_i) + { + string name(begin_i, name_end_i); + string value(name_end_i+1, pair_end_i); + parameters.push_back(pair(name, value)); + } + else + { //fprintf(stderr, "Parameter not specified in name=value form. ('eget -h' for help.)\n"); //return 1; string name(begin_i, pair_end_i); parameters.push_back(pair(name, "")); } - begin_i = pair_end_i; - if (begin_i != end_i) - begin_i++; // skip '&' - } - } + begin_i = pair_end_i; + if (begin_i != end_i) + begin_i++; // skip '&' + } + } - /* + /* std::cerr << "service : " << service << std::endl; std::cerr << "parameters : " << std::endl; @@ -1425,13 +1431,13 @@ int main (int argc, char *argv[]) for (; iter != parameters.end(); iter++) std::cerr << " " << iter->first << " = " << iter->second << std::endl; //std::cerr << "encoded URL request: '" << urlEncodedRequest << "'" << std::endl; - */ + */ // simply empty PVStructure::shared_pointer pvRequest = - getCreateRequest()->createRequest(request, requester); + getCreateRequest()->createRequest(request, requester); if(pvRequest.get()==NULL) { - fprintf(stderr, "failed to parse request string\n"); + fprintf(stderr, "failed to parse request string\n"); return 1; } @@ -1442,16 +1448,16 @@ int main (int argc, char *argv[]) iter != parameters.end(); iter++) { - queryFieldNames.push_back(iter->first); - queryFields.push_back(getFieldCreate()->createScalar(pvString)); + queryFieldNames.push_back(iter->first); + queryFields.push_back(getFieldCreate()->createScalar(pvString)); } Structure::const_shared_pointer queryStructure( - getFieldCreate()->createStructure( - queryFieldNames, - queryFields - ) - ); + getFieldCreate()->createStructure( + queryFieldNames, + queryFields + ) + ); @@ -1468,18 +1474,18 @@ int main (int argc, char *argv[]) uriFields.push_back(queryStructure); Structure::const_shared_pointer uriStructure( - getFieldCreate()->createStructure( - "uri:ev4:nt/2012/pwd:NTURI", - uriFieldNames, - uriFields - ) - ); + getFieldCreate()->createStructure( + "uri:ev4:nt/2012/pwd:NTURI", + uriFieldNames, + uriFields + ) + ); PVStructure::shared_pointer request( - getPVDataCreate()->createPVStructure(uriStructure) - ); + getPVDataCreate()->createPVStructure(uriStructure) + ); request->getStringField("scheme")->put("pva"); if (!authority.empty()) request->getStringField("authority")->put(authority); @@ -1489,26 +1495,26 @@ int main (int argc, char *argv[]) iter != parameters.end(); iter++) { - query->getStringField(iter->first)->put(iter->second); + query->getStringField(iter->first)->put(iter->second); } PVStructure::shared_pointer arg = onlyQuery ? query : request; if (debug) { - std::cout << "Request structure: " << std::endl << *(arg.get()) << std::endl; + std::cout << "Request structure: " << std::endl << *(arg.get()) << std::endl; } ClientFactory::start(); ChannelProvider::shared_pointer provider = getChannelAccess()->getProvider("pvAccess"); - shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); + shared_ptr channelRequesterImpl(new ChannelRequesterImpl()); Channel::shared_pointer channel = - authority.empty() ? - provider->createChannel(service, channelRequesterImpl) : - provider->createChannel(service, channelRequesterImpl, - ChannelProvider::PRIORITY_DEFAULT, authority); + authority.empty() ? + provider->createChannel(service, channelRequesterImpl) : + provider->createChannel(service, channelRequesterImpl, + ChannelProvider::PRIORITY_DEFAULT, authority); if (channelRequesterImpl->waitUntilConnected(timeOut)) { @@ -1517,17 +1523,22 @@ int main (int argc, char *argv[]) if (rpcRequesterImpl->waitUntilConnected(timeOut)) { - channelRPC->request(arg, true); - allOK &= rpcRequesterImpl->waitUntilRPC(timeOut); - if (allOK) - { + channelRPC->request(arg, true); + allOK &= rpcRequesterImpl->waitUntilRPC(timeOut); + if (allOK) + { if (dumpStructure) - std::cout << *(rpcRequesterImpl->getLastResponse().get()) << std::endl; + { + if (rpcRequesterImpl->getLastResponse().get() == 0) + std::cout << "(null)" << std::endl; + else + std::cout << *(rpcRequesterImpl->getLastResponse().get()) << std::endl; + } else formatNT(std::cout, rpcRequesterImpl->getLastResponse()); - std::cout << std::endl; - } - } + std::cout << std::endl; + } + } else { allOK = false; diff --git a/testApp/remote/testGetPerformance.cpp b/testApp/remote/testGetPerformance.cpp index 77b6c5e..8fa85b3 100644 --- a/testApp/remote/testGetPerformance.cpp +++ b/testApp/remote/testGetPerformance.cpp @@ -23,10 +23,18 @@ using namespace std::tr1; using namespace epics::pvData; using namespace epics::pvAccess; -#define COUNT 10000 // repetitions per result -#define CHANNELS 1 -#define ARRAY_SIZE 0 // 0 means scalar -#define LOOP_FOREVER 1 +#define DEFAULT_TIMEOUT 600.0 +#define DEFAULT_REQUEST "field(value)" +#define DEFAULT_ITERATIONS 10000 +#define DEFAULT_CHANNELS 1 +#define DEFAULT_ARRAY_SIZE 0 +#define DEFAULT_RUNS 1 +#define DEFAULT_BULK false + +int iterations = DEFAULT_ITERATIONS; +int channels = DEFAULT_CHANNELS; +int runs = DEFAULT_RUNS; +bool bulkMode = DEFAULT_BULK; #define DEFAULT_TIMEOUT 600.0 #define DEFAULT_REQUEST "field(value)" @@ -37,7 +45,7 @@ string request(DEFAULT_REQUEST); PVStructure::shared_pointer pvRequest; class RequesterImpl : public Requester, - public std::tr1::enable_shared_from_this + public std::tr1::enable_shared_from_this { public: @@ -52,334 +60,369 @@ public: } }; - void usage (void) { - fprintf (stderr, "\nUsage: testGetPerformance [options] ...\n\n" - " -h: Help: Print this message\n" - "options:\n" - " -r : Request, specifies what fields to return and options, default is '%s'\n" - " -w : Wait time, specifies timeout, default is %f second(s)\n\n" - , DEFAULT_REQUEST, DEFAULT_TIMEOUT); + fprintf (stderr, "\nUsage: testGetPerformance [options] ...\n\n" + " -h: Help: Print this message\n" + "options:\n" + " -r : pvRequest string, specifies what fields to return and options, default is '%s'\n" + " -i : number of iterations per each run, default is '%d'\n" + " -c : number of channels, default is '%d'\n" + " -s : number of array elements (0 means scalar), default is '%d'\n" + " -l : number of runs (0 means execute runs continuously), default is '%d'\n" + //" -b: bulk mode (send request messages in bulks), default is %d\n" + " -w : Wait time, specifies timeout, default is %f second(s)\n\n" + , DEFAULT_REQUEST, DEFAULT_ITERATIONS, DEFAULT_CHANNELS, DEFAULT_ARRAY_SIZE, DEFAULT_RUNS, DEFAULT_BULK, DEFAULT_TIMEOUT); } -vector getCs; +// TODO thread-safety +ChannelProvider::shared_pointer provider; +vector channelGetList; int channelCount = 0; -int allCount = 0; +int iterationCount = 0; +int runCount = 0; timeval startTime; void get_all() { - ChannelGet::shared_pointer last; - for (vector::const_iterator i = getCs.begin(); - i != getCs.end(); - i++) - { + for (vector::const_iterator i = channelGetList.begin(); + i != channelGetList.end(); + i++) (*i)->get(false); - last = *i; - } - // bulk testing dirty trigger last->get(true); + + // we assume all channels are from the same provider + if (bulkMode) provider->flush(); } +// NOTE: it is assumed that all the callbacks are called from the same thread, i.e. same TCP connection class ChannelGetRequesterImpl : public ChannelGetRequester { - private: - ChannelGet::shared_pointer m_channelGet; - PVStructure::shared_pointer m_pvStructure; - BitSet::shared_pointer m_bitSet; - Event m_event; - Event m_connectionEvent; - String m_channelName; - int m_count; +private: + ChannelGet::shared_pointer m_channelGet; + PVStructure::shared_pointer m_pvStructure; + BitSet::shared_pointer m_bitSet; + Event m_event; + Event m_connectionEvent; + String m_channelName; + int m_count; - timeval m_startTime; + timeval m_startTime; - public: +public: - ChannelGetRequesterImpl(String channelName) : m_channelName(channelName) {}; - - virtual String getRequesterName() - { - return "ChannelGetRequesterImpl"; - }; - - virtual void message(String const & message,MessageType messageType) - { - std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; - } - - virtual void channelGetConnect(const epics::pvData::Status& status, - ChannelGet::shared_pointer const & channelGet, - epics::pvData::PVStructure::shared_pointer const & pvStructure, - epics::pvData::BitSet::shared_pointer const & bitSet) - { - if (status.isSuccess()) - { - // show warning - if (!status.isOK()) - { - std::cout << "[" << m_channelName << "] channel get create: " << status.toString() << std::endl; - } - - m_channelGet = channelGet; - m_pvStructure = pvStructure; - m_bitSet = bitSet; - - m_connectionEvent.signal(); - -/* - m_count = COUNT; - - gettimeofday(&m_startTime, NULL); -*/ - } - else - { - std::cout << "[" << m_channelName << "] failed to create channel get: " << status.toString() << std::endl; - } - } - - virtual void getDone(const epics::pvData::Status& status) - { - if (status.isSuccess()) - { - // show warning - if (!status.isOK()) - { - std::cout << "[" << m_channelName << "] channel get: " << status.toString() << std::endl; - } - - channelCount++; - if (channelCount == CHANNELS) + ChannelGetRequesterImpl(String channelName) : + m_channelName(channelName) { - allCount++; - channelCount = 0; } -//printf("channelCount %d\n", channelCount); - - if (allCount == COUNT) - { - timeval endTime; - gettimeofday(&endTime, NULL); - - - long seconds, nseconds; - double duration; - seconds = endTime.tv_sec - startTime.tv_sec; - nseconds = endTime.tv_usec - startTime.tv_usec; - - duration = seconds + nseconds/1000000.0; - - printf("%5.6f seconds, %5.3f (x %d = %5.3f) gets/s\n", duration, COUNT/duration, CHANNELS, COUNT*CHANNELS/duration); - - allCount = 0; - gettimeofday(&startTime, NULL); - if (LOOP_FOREVER) - get_all(); + virtual String getRequesterName() + { + return "ChannelGetRequesterImpl"; + } + + virtual void message(String const & message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + } + + virtual void channelGetConnect(const epics::pvData::Status& status, + ChannelGet::shared_pointer const & channelGet, + epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::BitSet::shared_pointer const & bitSet) + { + if (status.isSuccess()) + { + // show warning + if (!status.isOK()) + { + std::cout << "[" << m_channelName << "] channel get create: " << status.toString() << std::endl; + } + + m_channelGet = channelGet; + m_pvStructure = pvStructure; + m_bitSet = bitSet; + + m_connectionEvent.signal(); + } else - exit(0); // TODO not the nicest way to exit - + { + std::cout << "[" << m_channelName << "] failed to create channel get: " << status.toString() << std::endl; + } } - else if (channelCount == 0) + + virtual void getDone(const epics::pvData::Status& status) { - - get_all(); + if (status.isSuccess()) + { + // show warning + if (!status.isOK()) + { + std::cout << "[" << m_channelName << "] channel get: " << status.toString() << std::endl; + } + + channelCount++; + if (channelCount == channels) + { + iterationCount++; + channelCount = 0; + } + + if (iterationCount == iterations) + { + timeval endTime; + gettimeofday(&endTime, NULL); + + + long seconds, nseconds; + double duration; + seconds = endTime.tv_sec - startTime.tv_sec; + nseconds = endTime.tv_usec - startTime.tv_usec; + + duration = seconds + nseconds/1000000.0; + + printf("%5.6f seconds, %5.3f (x %d = %5.3f) gets/s\n", duration, iterations/duration, channels, iterations*channels/duration); + + iterationCount = 0; + gettimeofday(&startTime, NULL); + + runCount++; + if (runs == 0 || runCount < runs) + get_all(); + else + exit(0); // all done, not the nicest way to exit + } + else if (channelCount == 0) + { + get_all(); + } + } + else + { + std::cout << "[" << m_channelName << "] failed to get: " << status.toString() << std::endl; + } + } - - - } - else - { - std::cout << "[" << m_channelName << "] failed to get: " << status.toString() << std::endl; - } - - } - -/* - void get() - { - return m_event.wait(timeOut); - } -*/ - bool waitUntilConnected(double timeOut) - { - return m_connectionEvent.wait(timeOut); - } + bool waitUntilConnected(double timeOut) + { + return m_connectionEvent.wait(timeOut); + } }; class ChannelRequesterImpl : public ChannelRequester { private: - Event m_event; + Event m_event; public: - virtual String getRequesterName() - { - return "ChannelRequesterImpl"; - }; + virtual String getRequesterName() + { + return "ChannelRequesterImpl"; + }; - virtual void message(String const & message,MessageType messageType) - { - std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; - } + virtual void message(String const & message,MessageType messageType) + { + std::cout << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl; + } - virtual void channelCreated(const epics::pvData::Status& status, - Channel::shared_pointer const & channel) - { - if (status.isSuccess()) - { - // show warning - if (!status.isOK()) - { - std::cout << "[" << channel->getChannelName() << "] channel create: " << status.toString() << std::endl; - } - } - else - { - std::cout << "[" << channel->getChannelName() << "] failed to create a channel: " << status.toString() << std::endl; - } - } + virtual void channelCreated(const epics::pvData::Status& status, + Channel::shared_pointer const & channel) + { + if (status.isSuccess()) + { + // show warning + if (!status.isOK()) + { + std::cout << "[" << channel->getChannelName() << "] channel create: " << status.toString() << std::endl; + } + } + else + { + std::cout << "[" << channel->getChannelName() << "] failed to create a channel: " << status.toString() << std::endl; + } + } - virtual void channelStateChange(Channel::shared_pointer const & /*channel*/, Channel::ConnectionState connectionState) - { - if (connectionState == Channel::CONNECTED) - { - m_event.signal(); - } - } + virtual void channelStateChange(Channel::shared_pointer const & /*channel*/, Channel::ConnectionState connectionState) + { + if (connectionState == Channel::CONNECTED) + { + m_event.signal(); + } + else + { + // ups... connection loss + std::cout << Channel::ConnectionStateNames[connectionState] << std::endl; + exit(3); + } + } - bool waitUntilConnected(double timeOut) - { - return m_event.wait(timeOut); - } + bool waitUntilConnected(double timeOut) + { + return m_event.wait(timeOut); + } }; int main (int argc, char *argv[]) { - int opt; // getopt() current option + int opt; // getopt() current option + int arraySize = DEFAULT_ARRAY_SIZE; // 0 means scalar - Requester::shared_pointer requester(new RequesterImpl()); + Requester::shared_pointer requester(new RequesterImpl()); - setvbuf(stdout,NULL,_IOLBF,BUFSIZ); // Set stdout to line buffering + setvbuf(stdout,NULL,_IOLBF,BUFSIZ); // Set stdout to line buffering - while ((opt = getopt(argc, argv, ":hr:w:t")) != -1) { - switch (opt) { - case 'h': // Print usage - usage(); - return 0; - case 'w': // Set CA timeout value - if(epicsScanDouble(optarg, &timeOut) != 1) - { - fprintf(stderr, "'%s' is not a valid timeout value " - "- ignored. ('cainfo -h' for help.)\n", optarg); - timeOut = DEFAULT_TIMEOUT; - } - break; - case 'r': // Set CA timeout value - request = optarg; - break; - case '?': - fprintf(stderr, - "Unrecognized option: '-%c'. ('testGetPerformance -h' for help.)\n", - optopt); - return 1; - case ':': - fprintf(stderr, - "Option '-%c' requires an argument. ('testGetPerformance -h' for help.)\n", - optopt); - return 1; - default : - usage(); - return 1; - } - } + while ((opt = getopt(argc, argv, ":hr:w:i:c:s:l:b")) != -1) { + switch (opt) { + case 'h': // Print usage + usage(); + return 0; + case 'w': // Set CA timeout value + if(epicsScanDouble(optarg, &timeOut) != 1) + { + fprintf(stderr, "'%s' is not a valid timeout value " + "- ignored. ('cainfo -h' for help.)\n", optarg); + timeOut = DEFAULT_TIMEOUT; + } + break; + case 'r': // pvRequest string + request = optarg; + break; + case 'i': // iterations + iterations = atoi(optarg); + break; + case 'c': // channels + channels = atoi(optarg); + break; + case 's': // arraySize + arraySize = atoi(optarg); + break; + case 'l': // runs + runs = atoi(optarg); + break; + //case 'b': // bulk mode + // bulkMode = true; + // break; + case '?': + fprintf(stderr, + "Unrecognized option: '-%c'. ('testGetPerformance -h' for help.)\n", + optopt); + return 1; + case ':': + fprintf(stderr, + "Option '-%c' requires an argument. ('testGetPerformance -h' for help.)\n", + optopt); + return 1; + default : + usage(); + return 1; + } + } - printf("%d channels of double array size of %d elements (0==scalar), %d repetitions per sample\n", CHANNELS, ARRAY_SIZE, COUNT); - - vector pvs; + printf("%d channel(s) of double array size of %d element(s) (0==scalar), %d iteration(s) per run, %d run(s) (0==forever)\n", channels, arraySize, iterations, runs); + + vector channelNames; char buf[64]; - for (int i = 0; i < CHANNELS; i++) + for (int i = 0; i < channels; i++) { - if (ARRAY_SIZE > 0) - sprintf(buf, "testArray%d_%d", ARRAY_SIZE, i); + if (arraySize > 0) + sprintf(buf, "testArray%d_%d", arraySize, i); else sprintf(buf, "test%d", i); - pvs.push_back(buf); - //printf("%s\n", buf); + channelNames.push_back(buf); } pvRequest = getCreateRequest()->createRequest(request,requester); - if(pvRequest.get()==NULL) { + if (pvRequest.get() == 0) { printf("failed to parse request string\n"); return 1; } - // typedef enum {logLevelInfo, logLevelDebug, logLevelError, errlogFatal} errlogSevEnum; - SET_LOG_LEVEL(logLevelError); + // typedef enum {logLevelInfo, logLevelDebug, logLevelError, errlogFatal} errlogSevEnum; + SET_LOG_LEVEL(logLevelError); - bool allOK = 1; + bool allOK = 1; - ClientFactory::start(); - ChannelProvider::shared_pointer provider = getChannelAccess()->getProvider("pvAccess"); + ClientFactory::start(); + provider = getChannelAccess()->getProvider("pvAccess"); + vector channels; + for (vector::const_iterator i = channelNames.begin(); + i != channelNames.end(); + i++) + { + shared_ptr channelRequesterImpl( + new ChannelRequesterImpl() + ); + Channel::shared_pointer channel = provider->createChannel(*i, channelRequesterImpl); + channels.push_back(channel); + } - vector chs; - - for (vector::iterator i = pvs.begin(); - i != pvs.end(); - i++) + bool differentConnectionsWarningIssued = false; + String theRemoteAddress; + for (vector::iterator i = channels.begin(); + i != channels.end(); + i++) + { + Channel::shared_pointer channel = *i; + shared_ptr channelRequesterImpl = + dynamic_pointer_cast(channel->getChannelRequester()); + if (bulkMode) provider->flush(); + if (channelRequesterImpl->waitUntilConnected(5.0)) { + String remoteAddress = channel->getRemoteAddress(); + if (theRemoteAddress.empty()) + { + theRemoteAddress = remoteAddress; + } + else if (theRemoteAddress != remoteAddress) + { + if (!differentConnectionsWarningIssued) + { + std::cout << "not all channels are hosted by the same connection: " << + theRemoteAddress << " != " << remoteAddress << std::endl; + differentConnectionsWarningIssued = true; + // the assumes same connection (thread-safety) + return 2; + } + } + shared_ptr getRequesterImpl( + new ChannelGetRequesterImpl(channel->getChannelName()) + ); + ChannelGet::shared_pointer channelGet = channel->createChannelGet(getRequesterImpl, pvRequest); + if (bulkMode) provider->flush(); + + allOK = getRequesterImpl->waitUntilConnected(timeOut); + + if (!allOK) + { + std::cout << "[" << channel->getChannelName() << "] failed to get all the gets" << std::endl; + return 1; + } + + channelGetList.push_back(channelGet); - shared_ptr channelRequesterImpl(new - ChannelRequesterImpl()); - Channel::shared_pointer channel = provider->createChannel(*i, channelRequesterImpl); - chs.push_back(channel); } - - for (vector::iterator i = chs.begin(); - i != chs.end(); - i++) + else { - Channel::shared_pointer channel = *i; - shared_ptr channelRequesterImpl = dynamic_pointer_cast(channel->getChannelRequester()); - if (channelRequesterImpl->waitUntilConnected(5.0)) - { - shared_ptr getRequesterImpl(new - ChannelGetRequesterImpl(channel->getChannelName())); - ChannelGet::shared_pointer channelGet = channel->createChannelGet(getRequesterImpl, pvRequest); - - allOK = getRequesterImpl->waitUntilConnected(timeOut); - - if (!allOK) - { - std::cout << "[" << channel->getChannelName() << "] failed to get all the gets" << std::endl; - return 1; - } - - getCs.push_back(channelGet); - - } - else - { - std::cout << "[" << channel->getChannelName() << "] connection timeout" << std::endl; - return 1; - } -} - std::cout << "all connected" << std::endl; + std::cout << "[" << channel->getChannelName() << "] connection timeout" << std::endl; + return 1; + } + } + std::cout << "all connected" << std::endl; gettimeofday(&startTime, NULL); - get_all(); - - epicsThreadSleep(DEFAULT_TIMEOUT); - //ClientFactory::stop(); + get_all(); - return allOK ? 0 : 1; + while (true) + epicsThreadSleep(600.0); + + //ClientFactory::stop(); + + return allOK ? 0 : 1; } diff --git a/testApp/remote/testServer.cpp b/testApp/remote/testServer.cpp index 248dfaa..a83e208 100644 --- a/testApp/remote/testServer.cpp +++ b/testApp/remote/testServer.cpp @@ -25,6 +25,9 @@ using namespace std; using std::tr1::static_pointer_cast; using std::tr1::dynamic_pointer_cast; +// forward declaration +void testServerShutdown(); + // TODO temp #include "testNTImage.cpp" @@ -32,166 +35,166 @@ map structureStore; class StructureChangedCallback { public: - POINTER_DEFINITIONS(StructureChangedCallback); - // TODO for now no BitSets, etc. - virtual void structureChanged() = 0; + POINTER_DEFINITIONS(StructureChangedCallback); + // TODO for now no BitSets, etc. + virtual void structureChanged() = 0; }; map > structureChangedListeners; static void notifyStructureChanged(String const & name) { - // NOTE: not thread-safe - if (structureChangedListeners.find(name) != structureChangedListeners.end()) - { - vector & vec = structureChangedListeners[name]; - for (vector::iterator iter = vec.begin(); - iter != vec.end(); - iter++) - { - (*iter)->structureChanged(); - } - } + // NOTE: not thread-safe + if (structureChangedListeners.find(name) != structureChangedListeners.end()) + { + vector & vec = structureChangedListeners[name]; + for (vector::iterator iter = vec.begin(); + iter != vec.end(); + iter++) + { + (*iter)->structureChanged(); + } + } } static PVStructure::shared_pointer getRequestedStructure( - PVStructure::shared_pointer const & pvStructure, - PVStructure::shared_pointer const & pvRequest, - String subfieldName = "field") + PVStructure::shared_pointer const & pvStructure, + PVStructure::shared_pointer const & pvRequest, + String subfieldName = "field") { - // if pvRequest is empty, just use pvStructure - if (pvRequest.get() && pvRequest->getPVFields().size() > 0) - { - PVStructure::shared_pointer pvRequestFields; - if (pvRequest->getSubField(subfieldName)) - pvRequestFields = pvRequest->getStructureField(subfieldName); - else - pvRequestFields = pvRequest; + // if pvRequest is empty, just use pvStructure + if (pvRequest.get() && pvRequest->getPVFields().size() > 0) + { + PVStructure::shared_pointer pvRequestFields; + if (pvRequest->getSubField(subfieldName)) + pvRequestFields = pvRequest->getStructureField(subfieldName); + else + pvRequestFields = pvRequest; - // if pvRequest is empty, just use pvStructure - if (pvRequestFields->getPVFields().size() > 0) - { - StringArray const & fieldNames = pvRequestFields->getStructure()->getFieldNames(); - PVFieldPtrArray pvFields; - StringArray actualFieldNames; - for (StringArray::const_iterator iter = fieldNames.begin(); - iter != fieldNames.end(); - iter++) - { - PVFieldPtr pvField = pvStructure->getSubField(*iter); - if (pvField) - { - PVStructurePtr pvFieldStructure = - std::tr1::dynamic_pointer_cast(pvField); + // if pvRequest is empty, just use pvStructure + if (pvRequestFields->getPVFields().size() > 0) + { + StringArray const & fieldNames = pvRequestFields->getStructure()->getFieldNames(); + PVFieldPtrArray pvFields; + StringArray actualFieldNames; + for (StringArray::const_iterator iter = fieldNames.begin(); + iter != fieldNames.end(); + iter++) + { + PVFieldPtr pvField = pvStructure->getSubField(*iter); + if (pvField) + { + PVStructurePtr pvFieldStructure = + std::tr1::dynamic_pointer_cast(pvField); - PVStructurePtr pvRequestFieldStructure = - std::tr1::dynamic_pointer_cast(pvRequestFields->getSubField(*iter)); - if (pvRequestFieldStructure->getPVFields().size() > 0 && pvFieldStructure.get()) - { - // add subfields only - actualFieldNames.push_back(*iter); - pvFields.push_back(getRequestedStructure(pvFieldStructure, pvRequestFieldStructure)); - } - else - { - // add entire field - actualFieldNames.push_back(*iter); - pvFields.push_back(pvField); - } - } - } + PVStructurePtr pvRequestFieldStructure = + std::tr1::dynamic_pointer_cast(pvRequestFields->getSubField(*iter)); + if (pvRequestFieldStructure->getPVFields().size() > 0 && pvFieldStructure.get()) + { + // add subfields only + actualFieldNames.push_back(*iter); + pvFields.push_back(getRequestedStructure(pvFieldStructure, pvRequestFieldStructure)); + } + else + { + // add entire field + actualFieldNames.push_back(*iter); + pvFields.push_back(pvField); + } + } + } - return getPVDataCreate()->createPVStructure(actualFieldNames, pvFields); - } - } + return getPVDataCreate()->createPVStructure(actualFieldNames, pvFields); + } + } - return pvStructure; + return pvStructure; } class ProcessAction : public Runnable { public: - typedef vector ChannelProcessVector; - ChannelProcessVector toProcess; - AtomicBoolean stopped; - double period; + typedef vector ChannelProcessVector; + ChannelProcessVector toProcess; + AtomicBoolean stopped; + double period; - ProcessAction(double periodHz) : period(periodHz) {} + ProcessAction(double periodHz) : period(periodHz) {} virtual void run() { - while (!stopped.get()) - { + while (!stopped.get()) + { - for (ChannelProcessVector::iterator iter = toProcess.begin(); - iter != toProcess.end(); - iter++) - { - try { - (*iter)->process(false); - } catch (std::exception &ex) { - std::cerr << "Unhandled exception caught in ProcessAction::run(): " << ex.what() << std::endl; - } catch (...) { - std::cerr << "Unhandled exception caught in ProcessAction::run()" << std::endl; - } + for (ChannelProcessVector::iterator iter = toProcess.begin(); + iter != toProcess.end(); + iter++) + { + try { + (*iter)->process(false); + } catch (std::exception &ex) { + std::cerr << "Unhandled exception caught in ProcessAction::run(): " << ex.what() << std::endl; + } catch (...) { + std::cerr << "Unhandled exception caught in ProcessAction::run()" << std::endl; + } - epicsThreadSleep(period); - } - } + epicsThreadSleep(period); + } + } } }; // ADC class ADCAction : public Runnable { public: - String name; + String name; epics::pvData::PVStructure::shared_pointer adcMatrix; SimADC::smart_pointer_type adcSim; - AtomicBoolean stopped; + AtomicBoolean stopped; - ADCAction() {} + ADCAction() {} virtual void run() { - while (!stopped.get()) - { - if (adcSim->updated.wait(1.0)) - { + while (!stopped.get()) + { + if (adcSim->updated.wait(1.0)) + { - try { + try { - epicsGuard guard(adcSim->mutex); + epicsGuard guard(adcSim->mutex); - epicsUInt32 len = adcSim->prev_nSamples; - double *val = adcSim->data.value.get(); - static_pointer_cast(adcMatrix->getScalarArrayField("value", pvDouble))->put(0, len, val, 0); + epicsUInt32 len = adcSim->prev_nSamples; + double *val = adcSim->data.value.get(); + static_pointer_cast(adcMatrix->getScalarArrayField("value", pvDouble))->put(0, len, val, 0); - baseValue::shape_t* shape = &adcSim->data.shape; - size_t shapeLen = shape->size(); - vector intVal(shapeLen); - for (size_t i = 0; i < shapeLen; i++) - intVal[i] = (*shape)[i]; - static_pointer_cast(adcMatrix->getScalarArrayField("dim", pvInt))->put(0, shapeLen, &intVal[0], 0); + baseValue::shape_t* shape = &adcSim->data.shape; + size_t shapeLen = shape->size(); + vector intVal(shapeLen); + for (size_t i = 0; i < shapeLen; i++) + intVal[i] = (*shape)[i]; + static_pointer_cast(adcMatrix->getScalarArrayField("dim", pvInt))->put(0, shapeLen, &intVal[0], 0); - PVStructure::shared_pointer ts = adcMatrix->getStructureField("timeStamp"); + PVStructure::shared_pointer ts = adcMatrix->getStructureField("timeStamp"); - PVTimeStamp timeStamp; - timeStamp.attach(ts); - TimeStamp current; - current.put(adcSim->X.timeStamp.tv_sec, adcSim->X.timeStamp.tv_nsec); - timeStamp.set(current); + PVTimeStamp timeStamp; + timeStamp.attach(ts); + TimeStamp current; + current.put(adcSim->X.timeStamp.tv_sec, adcSim->X.timeStamp.tv_nsec); + timeStamp.set(current); - notifyStructureChanged(name); + notifyStructureChanged(name); - } catch (std::exception &ex) { - std::cerr << "Unhandled exception caught in ADCThread::run(): " << ex.what() << std::endl; - } catch (...) { - std::cerr << "Unhandled exception caught in ADCThread::run()" << std::endl; - } + } catch (std::exception &ex) { + std::cerr << "Unhandled exception caught in ADCThread::run(): " << ex.what() << std::endl; + } catch (...) { + std::cerr << "Unhandled exception caught in ADCThread::run()" << std::endl; + } - } - } + } + } } }; @@ -253,7 +256,7 @@ static epics::pvData::PVStructure::shared_pointer createNTTable(int columnsCount Structure::const_shared_pointer valueStructure( getFieldCreate()->createStructure(fieldNames, fields) - ); + ); StringArray tableFieldNames(2); FieldConstPtrArray tableFields(2); @@ -263,11 +266,11 @@ static epics::pvData::PVStructure::shared_pointer createNTTable(int columnsCount tableFields[1] = valueStructure; PVStructure::shared_pointer result( - getPVDataCreate()->createPVStructure( + getPVDataCreate()->createPVStructure( getFieldCreate()->createStructure( - "uri:ev4:nt/2012/pwd:NTTable", tableFieldNames, tableFields) - ) - ); + "uri:ev4:nt/2012/pwd:NTTable", tableFieldNames, tableFields) + ) + ); static_pointer_cast(result->getScalarArrayField("labels", pvString))->put(0, labels.size(), &labels[0], 0); return result; @@ -282,16 +285,16 @@ static void generateNTTableDoubleValues(epics::pvData::PVStructure::shared_point PVStructure::shared_pointer resultValue = result->getStructureField("value"); - #define ROWS 10 +#define ROWS 10 double values[ROWS]; - #define FILL_VALUES(OFFSET) \ +#define FILL_VALUES(OFFSET) \ for (int r = 0; r < ROWS; r++) \ - values[r] = rand()/((double)RAND_MAX+1) + OFFSET; + values[r] = rand()/((double)RAND_MAX+1) + OFFSET; int offset = 0; for (vector::iterator iter = ld.data.begin(); - iter != ld.data.end(); - iter++, offset++) + iter != ld.data.end(); + iter++, offset++) { FILL_VALUES(offset); static_pointer_cast(resultValue->getScalarArrayField(*iter, pvDouble))->put(0, ROWS, values, 0); @@ -302,7 +305,7 @@ static void generateNTTableDoubleValues(epics::pvData::PVStructure::shared_point class ChannelFindRequesterImpl : public ChannelFindRequester { virtual void channelFindResult(epics::pvData::Status const & status, - ChannelFind::shared_pointer const & /*channelFind*/, bool wasFound) + ChannelFind::shared_pointer const & /*channelFind*/, bool wasFound) { std::cout << "[ChannelFindRequesterImpl] channelFindResult(" << status.toString() << ", ..., " << wasFound << ")" << std::endl; @@ -377,9 +380,9 @@ class ChannelGetRequesterImpl : public ChannelGetRequester } virtual void channelGetConnect(const epics::pvData::Status& status, - ChannelGet::shared_pointer const & /*channelGet*/, - epics::pvData::PVStructure::shared_pointer const & pvStructure, - epics::pvData::BitSet::shared_pointer const & bitSet) + ChannelGet::shared_pointer const & /*channelGet*/, + epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::BitSet::shared_pointer const & bitSet) { std::cout << "channelGetConnect(" << status.toString() << ")" << std::endl; @@ -415,9 +418,9 @@ class ChannelPutRequesterImpl : public ChannelPutRequester } virtual void channelPutConnect(const epics::pvData::Status& status, - ChannelPut::shared_pointer const & /*channelPut*/, - epics::pvData::PVStructure::shared_pointer const & pvStructure, - epics::pvData::BitSet::shared_pointer const & bitSet) + ChannelPut::shared_pointer const & /*channelPut*/, + epics::pvData::PVStructure::shared_pointer const & pvStructure, + epics::pvData::BitSet::shared_pointer const & bitSet) { std::cout << "channelPutConnect(" << status.toString() << ")" << std::endl; @@ -460,7 +463,7 @@ class MonitorRequesterImpl : public MonitorRequester } virtual void monitorConnect(const Status& status, Monitor::shared_pointer const & /*monitor*/, - StructureConstPtr& structure) + StructureConstPtr& structure) { std::cout << "monitorConnect(" << status.toString() << ")" << std::endl; if (structure) @@ -510,7 +513,7 @@ class ChannelProcessRequesterImpl : public ChannelProcessRequester } virtual void channelProcessConnect(const epics::pvData::Status& /*status*/, - ChannelProcess::shared_pointer const & /*channelProcess*/) + ChannelProcess::shared_pointer const & /*channelProcess*/) { //std::cout << "channelProcessConnect(" << status.toString() << ")" << std::endl; @@ -527,19 +530,19 @@ class ChannelProcessRequesterImpl : public ChannelProcessRequester PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelProcess); class MockChannelProcess : - public ChannelProcess, - public std::tr1::enable_shared_from_this + public ChannelProcess, + public std::tr1::enable_shared_from_this { - private: - String m_channelName; - ChannelProcessRequester::shared_pointer m_channelProcessRequester; - PVStructure::shared_pointer m_pvStructure; - PVScalarPtr m_valueField; - PVTimeStamp m_timeStamp; +private: + String m_channelName; + ChannelProcessRequester::shared_pointer m_channelProcessRequester; + PVStructure::shared_pointer m_pvStructure; + PVScalarPtr m_valueField; + PVTimeStamp m_timeStamp; - protected: +protected: MockChannelProcess(String const & channelName, ChannelProcessRequester::shared_pointer const & channelProcessRequester, - PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & /*pvRequest*/) : + PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & /*pvRequest*/) : m_channelName(channelName), m_channelProcessRequester(channelProcessRequester), m_pvStructure(pvStructure) { PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelProcess); @@ -549,19 +552,19 @@ class MockChannelProcess : if (field.get() == 0) { Status noValueFieldStatus(Status::STATUSTYPE_ERROR, "no 'value' field"); - m_channelProcessRequester->channelProcessConnect(noValueFieldStatus, thisPtr); - // NOTE client must destroy this instance... - // do not access any fields and return ASAP - return; + m_channelProcessRequester->channelProcessConnect(noValueFieldStatus, thisPtr); + // NOTE client must destroy this instance... + // do not access any fields and return ASAP + return; } if (field->getField()->getType() != scalar) { Status notAScalarStatus(Status::STATUSTYPE_ERROR, "'value' field not scalar type"); - m_channelProcessRequester->channelProcessConnect(notAScalarStatus, thisPtr); - // NOTE client must destroy this instance... - // do not access any fields and return ASAP - return; + m_channelProcessRequester->channelProcessConnect(notAScalarStatus, thisPtr); + // NOTE client must destroy this instance... + // do not access any fields and return ASAP + return; } m_valueField = dynamic_pointer_cast(field); @@ -570,18 +573,18 @@ class MockChannelProcess : if (ts) m_timeStamp.attach(ts); } - public: +public: static ChannelProcess::shared_pointer create( - String const & channelName, - ChannelProcessRequester::shared_pointer const & channelProcessRequester, - PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) + String const & channelName, + ChannelProcessRequester::shared_pointer const & channelProcessRequester, + PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) { ChannelProcess::shared_pointer thisPtr(new MockChannelProcess(channelName, channelProcessRequester, pvStructure, pvRequest)); // TODO pvRequest - channelProcessRequester->channelProcessConnect(Status::Ok, thisPtr); - - return thisPtr; + channelProcessRequester->channelProcessConnect(Status::Ok, thisPtr); + + return thisPtr; } virtual ~MockChannelProcess() @@ -600,90 +603,90 @@ class MockChannelProcess : { switch (m_valueField->getScalar()->getScalarType()) { - case pvBoolean: + case pvBoolean: + { + // negate + PVBooleanPtr pvBoolean = static_pointer_cast(m_valueField); + pvBoolean->put(!pvBoolean->get()); + break; + } + case pvByte: + { + // increment by one + PVBytePtr pvByte = static_pointer_cast(m_valueField); + pvByte->put(pvByte->get() + 1); + break; + } + case pvShort: + { + // increment by one + PVShortPtr pvShort = static_pointer_cast(m_valueField); + pvShort->put(pvShort->get() + 1); + break; + } + case pvInt: + { + // increment by one + PVIntPtr pvInt = static_pointer_cast(m_valueField); + pvInt->put(pvInt->get() + 1); + break; + } + case pvLong: + { + // increment by one + PVLongPtr pvLong = static_pointer_cast(m_valueField); + pvLong->put(pvLong->get() + 1); + break; + } + case pvFloat: + { + // increment by one + PVFloatPtr pvFloat = static_pointer_cast(m_valueField); + pvFloat->put(pvFloat->get() + 1.0f); + break; + } + case pvDouble: + { + double noise = ((rand()/(double)RAND_MAX)-0.5)*2; + // increment by one + PVDoublePtr pvDouble = static_pointer_cast(m_valueField); + pvDouble->put(pvDouble->get() + noise /*1.0*/); + break; + } + case pvString: + { + // increment by one + PVStringPtr pvString = static_pointer_cast(m_valueField); + String val = pvString->get(); + if (val.empty()) + pvString->put("gen0"); + else { - // negate - PVBooleanPtr pvBoolean = static_pointer_cast(m_valueField); - pvBoolean->put(!pvBoolean->get()); - break; + char c = val[3]; + c++; + pvString->put("gen" + c); } - case pvByte: - { - // increment by one - PVBytePtr pvByte = static_pointer_cast(m_valueField); - pvByte->put(pvByte->get() + 1); - break; - } - case pvShort: - { - // increment by one - PVShortPtr pvShort = static_pointer_cast(m_valueField); - pvShort->put(pvShort->get() + 1); - break; - } - case pvInt: - { - // increment by one - PVIntPtr pvInt = static_pointer_cast(m_valueField); - pvInt->put(pvInt->get() + 1); - break; - } - case pvLong: - { - // increment by one - PVLongPtr pvLong = static_pointer_cast(m_valueField); - pvLong->put(pvLong->get() + 1); - break; - } - case pvFloat: - { - // increment by one - PVFloatPtr pvFloat = static_pointer_cast(m_valueField); - pvFloat->put(pvFloat->get() + 1.0f); - break; - } - case pvDouble: - { - double noise = ((rand()/(double)RAND_MAX)-0.5)*2; - // increment by one - PVDoublePtr pvDouble = static_pointer_cast(m_valueField); - pvDouble->put(pvDouble->get() + noise /*1.0*/); - break; - } - case pvString: - { - // increment by one - PVStringPtr pvString = static_pointer_cast(m_valueField); - String val = pvString->get(); - if (val.empty()) - pvString->put("gen0"); - else - { - char c = val[3]; - c++; - pvString->put("gen" + c); - } - break; - } - default: - // noop - break; + break; + } + default: + // noop + break; } } if (m_timeStamp.isAttached()) { - TimeStamp current; - current.getCurrent(); - m_timeStamp.set(current); + TimeStamp current; + current.getCurrent(); + m_timeStamp.set(current); } - m_channelProcessRequester->processDone(Status::Ok); + m_channelProcessRequester->processDone(Status::Ok); - notifyStructureChanged(m_channelName); + notifyStructureChanged(m_channelName); - if (lastRequest) - destroy(); + if (lastRequest) + destroy(); } virtual void destroy() @@ -710,29 +713,29 @@ PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelGet); class MockChannelGet : public ChannelGet { - private: - ChannelGetRequester::shared_pointer m_channelGetRequester; - PVStructure::shared_pointer m_pvStructure; - BitSet::shared_pointer m_bitSet; - bool m_first; +private: + ChannelGetRequester::shared_pointer m_channelGetRequester; + PVStructure::shared_pointer m_pvStructure; + BitSet::shared_pointer m_bitSet; + bool m_first; - protected: +protected: MockChannelGet(ChannelGetRequester::shared_pointer const & channelGetRequester, - PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : + PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : m_channelGetRequester(channelGetRequester), m_pvStructure(getRequestedStructure(pvStructure, pvRequest)), m_bitSet(new BitSet(m_pvStructure->getNumberFields())), m_first(true) { PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelGet); } - public: +public: static ChannelGet::shared_pointer create(ChannelGetRequester::shared_pointer const & channelGetRequester, PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) { - ChannelGet::shared_pointer thisPtr(new MockChannelGet(channelGetRequester, pvStructure, pvRequest)); - channelGetRequester->channelGetConnect(Status::Ok, thisPtr, - static_cast(thisPtr.get())->m_pvStructure, - static_cast(thisPtr.get())->m_bitSet); - return thisPtr; + ChannelGet::shared_pointer thisPtr(new MockChannelGet(channelGetRequester, pvStructure, pvRequest)); + channelGetRequester->channelGetConnect(Status::Ok, thisPtr, + static_cast(thisPtr.get())->m_pvStructure, + static_cast(thisPtr.get())->m_bitSet); + return thisPtr; } virtual ~MockChannelGet() @@ -742,15 +745,15 @@ class MockChannelGet : public ChannelGet virtual void get(bool lastRequest) { - m_channelGetRequester->getDone(Status::Ok); - if (m_first) - { - m_first = false; - m_bitSet->set(0); // TODO - } + m_channelGetRequester->getDone(Status::Ok); + if (m_first) + { + m_first = false; + m_bitSet->set(0); // TODO + } - if (lastRequest) - destroy(); + if (lastRequest) + destroy(); } virtual void destroy() @@ -775,15 +778,15 @@ PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelPut); class MockChannelPut : public ChannelPut { - private: - String m_channelName; - ChannelPutRequester::shared_pointer m_channelPutRequester; - PVStructure::shared_pointer m_pvStructure; - BitSet::shared_pointer m_bitSet; +private: + String m_channelName; + ChannelPutRequester::shared_pointer m_channelPutRequester; + PVStructure::shared_pointer m_pvStructure; + BitSet::shared_pointer m_bitSet; - protected: +protected: MockChannelPut(String const & channelName, ChannelPutRequester::shared_pointer const & channelPutRequester, - PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : + PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : m_channelName(channelName), m_channelPutRequester(channelPutRequester), m_pvStructure(getRequestedStructure(pvStructure, pvRequest)), m_bitSet(new BitSet(m_pvStructure->getNumberFields())) @@ -791,19 +794,19 @@ class MockChannelPut : public ChannelPut PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelPut); } - public: +public: static ChannelPut::shared_pointer create( - String const & channelName, - ChannelPutRequester::shared_pointer const & channelPutRequester, - PVStructure::shared_pointer const & pvStructure, - PVStructure::shared_pointer const & pvRequest) + String const & channelName, + ChannelPutRequester::shared_pointer const & channelPutRequester, + PVStructure::shared_pointer const & pvStructure, + PVStructure::shared_pointer const & pvRequest) { ChannelPut::shared_pointer thisPtr(new MockChannelPut(channelName, channelPutRequester, pvStructure, pvRequest)); - channelPutRequester->channelPutConnect(Status::Ok, thisPtr, - static_cast(thisPtr.get())->m_pvStructure, - static_cast(thisPtr.get())->m_bitSet); - - return thisPtr; + channelPutRequester->channelPutConnect(Status::Ok, thisPtr, + static_cast(thisPtr.get())->m_pvStructure, + static_cast(thisPtr.get())->m_bitSet); + + return thisPtr; } virtual ~MockChannelPut() @@ -814,17 +817,17 @@ class MockChannelPut : public ChannelPut virtual void put(bool lastRequest) { - m_channelPutRequester->putDone(Status::Ok); + m_channelPutRequester->putDone(Status::Ok); - notifyStructureChanged(m_channelName); + notifyStructureChanged(m_channelName); - if (lastRequest) - destroy(); + if (lastRequest) + destroy(); } virtual void get() { - m_channelPutRequester->getDone(Status::Ok); + m_channelPutRequester->getDone(Status::Ok); } virtual void destroy() @@ -849,16 +852,16 @@ PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelPutGet); class MockChannelPutGet : public ChannelPutGet { - private: - String m_channelName; - ChannelPutGetRequester::shared_pointer m_channelPutGetRequester; - PVStructure::shared_pointer m_getStructure; - PVStructure::shared_pointer m_putStructure; +private: + String m_channelName; + ChannelPutGetRequester::shared_pointer m_channelPutGetRequester; + PVStructure::shared_pointer m_getStructure; + PVStructure::shared_pointer m_putStructure; - protected: +protected: MockChannelPutGet(String const & channelName, ChannelPutGetRequester::shared_pointer const & channelPutGetRequester, - PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : - m_channelName(channelName), + PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : + m_channelName(channelName), m_channelPutGetRequester(channelPutGetRequester), m_getStructure(getRequestedStructure(pvStructure, pvRequest, "getField")), m_putStructure(getRequestedStructure(pvStructure, pvRequest, "putField")) @@ -866,20 +869,20 @@ class MockChannelPutGet : public ChannelPutGet PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelPutGet); } - public: +public: static ChannelPutGet::shared_pointer create( - String const & channelName, - ChannelPutGetRequester::shared_pointer const & channelPutGetRequester, - PVStructure::shared_pointer const & pvStructure, - PVStructure::shared_pointer const & pvRequest) + String const & channelName, + ChannelPutGetRequester::shared_pointer const & channelPutGetRequester, + PVStructure::shared_pointer const & pvStructure, + PVStructure::shared_pointer const & pvRequest) { ChannelPutGet::shared_pointer thisPtr(new MockChannelPutGet(channelName, channelPutGetRequester, pvStructure, pvRequest)); - channelPutGetRequester->channelPutGetConnect(Status::Ok, thisPtr, - static_cast(thisPtr.get())->m_putStructure, - static_cast(thisPtr.get())->m_getStructure); - - return thisPtr; + channelPutGetRequester->channelPutGetConnect(Status::Ok, thisPtr, + static_cast(thisPtr.get())->m_putStructure, + static_cast(thisPtr.get())->m_getStructure); + + return thisPtr; } virtual ~MockChannelPutGet() @@ -889,22 +892,22 @@ class MockChannelPutGet : public ChannelPutGet virtual void putGet(bool lastRequest) { - m_channelPutGetRequester->putGetDone(Status::Ok); + m_channelPutGetRequester->putGetDone(Status::Ok); - notifyStructureChanged(m_channelName); + notifyStructureChanged(m_channelName); - if (lastRequest) - destroy(); + if (lastRequest) + destroy(); } virtual void getGet() { - m_channelPutGetRequester->getGetDone(Status::Ok); + m_channelPutGetRequester->getGetDone(Status::Ok); } virtual void getPut() { - m_channelPutGetRequester->getPutDone(Status::Ok); + m_channelPutGetRequester->getPutDone(Status::Ok); } virtual void destroy() @@ -939,11 +942,11 @@ static bool handleHelp( fields[0] = getFieldCreate()->createScalar(pvString); PVStructure::shared_pointer result( - getPVDataCreate()->createPVStructure( + getPVDataCreate()->createPVStructure( getFieldCreate()->createStructure( "uri:ev4:nt/2012/pwd:NTScalar", fieldNames, fields) - ) - ); + ) + ); static_pointer_cast(result->getStringField("value"))->put(helpText); channelRPCRequester->requestDone(Status::Ok, result); @@ -960,27 +963,27 @@ PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelRPC); class MockChannelRPC : public ChannelRPC { - private: - ChannelRPCRequester::shared_pointer m_channelRPCRequester; - String m_channelName; - PVStructure::shared_pointer m_pvStructure; +private: + ChannelRPCRequester::shared_pointer m_channelRPCRequester; + String m_channelName; + PVStructure::shared_pointer m_pvStructure; - protected: +protected: MockChannelRPC(ChannelRPCRequester::shared_pointer const & channelRPCRequester, - String const & channelName, PVStructure::shared_pointer const & pvStructure, - PVStructure::shared_pointer const & /*pvRequest*/) : + String const & channelName, PVStructure::shared_pointer const & pvStructure, + PVStructure::shared_pointer const & /*pvRequest*/) : m_channelRPCRequester(channelRPCRequester), m_channelName(channelName), m_pvStructure(pvStructure) { PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelRPC); } - public: +public: static ChannelRPC::shared_pointer create(ChannelRPCRequester::shared_pointer const & channelRPCRequester, String const & channelName, PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) { ChannelRPC::shared_pointer thisPtr(new MockChannelRPC(channelRPCRequester, channelName, pvStructure, pvRequest)); // TODO pvRequest - channelRPCRequester->channelRPCConnect(Status::Ok, thisPtr); - return thisPtr; + channelRPCRequester->channelRPCConnect(Status::Ok, thisPtr); + return thisPtr; } virtual ~MockChannelRPC() @@ -990,13 +993,13 @@ class MockChannelRPC : public ChannelRPC virtual void request(epics::pvData::PVStructure::shared_pointer const & pvArgument, bool lastRequest) { - if (m_channelName == "testNTTable") - { - PVStructure::shared_pointer args( - (pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ? - pvArgument->getStructureField("query") : - pvArgument - ); + if (m_channelName == "testNTTable") + { + PVStructure::shared_pointer args( + (pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ? + pvArgument->getStructureField("query") : + pvArgument + ); const String helpText = "Generates a NTTable structure response with 10 rows and a specified number of columns.\n" @@ -1006,27 +1009,27 @@ class MockChannelRPC : public ChannelRPC return; PVStringPtr columns = dynamic_pointer_cast(args->getSubField("columns")); - if (columns.get() == 0) - { - PVStructure::shared_pointer nullPtr; + if (columns.get() == 0) + { + PVStructure::shared_pointer nullPtr; Status errorStatus(Status::STATUSTYPE_ERROR, "no string 'columns' argument specified"); - m_channelRPCRequester->requestDone(errorStatus, nullPtr); - } - else - { - int columnsCount = atoi(columns->get().c_str()); + m_channelRPCRequester->requestDone(errorStatus, nullPtr); + } + else + { + int columnsCount = atoi(columns->get().c_str()); PVStructure::shared_pointer result = createNTTable(columnsCount); generateNTTableDoubleValues(result); - m_channelRPCRequester->requestDone(Status::Ok, result); - } - } - else if (m_channelName == "testNTNameValue") - { - PVStructure::shared_pointer args( - (pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ? - pvArgument->getStructureField("query") : - pvArgument - ); + m_channelRPCRequester->requestDone(Status::Ok, result); + } + } + else if (m_channelName == "testNTNameValue") + { + PVStructure::shared_pointer args( + (pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ? + pvArgument->getStructureField("query") : + pvArgument + ); const String helpText = "Generates a NTNameValue structure response with a specified number of columns.\n" @@ -1036,56 +1039,56 @@ class MockChannelRPC : public ChannelRPC return; PVStringPtr columns = dynamic_pointer_cast(args->getSubField("columns")); - if (columns.get() == 0) - { - PVStructure::shared_pointer nullPtr; + if (columns.get() == 0) + { + PVStructure::shared_pointer nullPtr; Status errorStatus(Status::STATUSTYPE_ERROR, "no string 'columns' argument specified"); - m_channelRPCRequester->requestDone(errorStatus, nullPtr); - } - else - { + m_channelRPCRequester->requestDone(errorStatus, nullPtr); + } + else + { - int columnsCount = atoi(columns->get().c_str()); + int columnsCount = atoi(columns->get().c_str()); - char sbuf[16]; - vector labels; - for (int i = 0; i < columnsCount; i++) - { - sprintf(sbuf, "name%d", i); - labels.push_back(sbuf); - } + char sbuf[16]; + vector labels; + for (int i = 0; i < columnsCount; i++) + { + sprintf(sbuf, "name%d", i); + labels.push_back(sbuf); + } - StringArray tableFieldNames(2); - FieldConstPtrArray tableFields(2); - tableFieldNames[0] = "name"; - tableFields[0] = getFieldCreate()->createScalarArray(pvString); - tableFieldNames[1] = "value"; - tableFields[1] = getFieldCreate()->createScalarArray(pvDouble); + StringArray tableFieldNames(2); + FieldConstPtrArray tableFields(2); + tableFieldNames[0] = "name"; + tableFields[0] = getFieldCreate()->createScalarArray(pvString); + tableFieldNames[1] = "value"; + tableFields[1] = getFieldCreate()->createScalarArray(pvDouble); - PVStructure::shared_pointer result( - getPVDataCreate()->createPVStructure( - getFieldCreate()->createStructure( - "uri:ev4:nt/2012/pwd:NTNameValue", tableFieldNames, tableFields) - ) - ); - static_pointer_cast(result->getScalarArrayField("name", pvString))->put(0, labels.size(), &labels[0], 0); + PVStructure::shared_pointer result( + getPVDataCreate()->createPVStructure( + getFieldCreate()->createStructure( + "uri:ev4:nt/2012/pwd:NTNameValue", tableFieldNames, tableFields) + ) + ); + static_pointer_cast(result->getScalarArrayField("name", pvString))->put(0, labels.size(), &labels[0], 0); - int32 len = columnsCount; - vector mv(len); - for (int r = 0; r < len; r++) - mv[r] = rand()/((double)RAND_MAX+1) + (int)(r); - static_pointer_cast(result->getScalarArrayField("value", pvDouble))->put(0, len, &mv[0], 0); + int32 len = columnsCount; + vector mv(len); + for (int r = 0; r < len; r++) + mv[r] = rand()/((double)RAND_MAX+1) + (int)(r); + static_pointer_cast(result->getScalarArrayField("value", pvDouble))->put(0, len, &mv[0], 0); - m_channelRPCRequester->requestDone(Status::Ok, result); - } - } - else if (m_channelName == "testNTMatrix") - { - PVStructure::shared_pointer args( - (pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ? - pvArgument->getStructureField("query") : - pvArgument - ); + m_channelRPCRequester->requestDone(Status::Ok, result); + } + } + else if (m_channelName == "testNTMatrix") + { + PVStructure::shared_pointer args( + (pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ? + pvArgument->getStructureField("query") : + pvArgument + ); const String helpText = "Generates a NTMatrix structure response with a specified number of rows and columns.\n" @@ -1099,56 +1102,56 @@ class MockChannelRPC : public ChannelRPC PVStringPtr rows = dynamic_pointer_cast(args->getSubField("rows")); PVStringPtr columns = dynamic_pointer_cast(args->getSubField("columns")); - if (rows.get() == 0 || columns.get() == 0) - { - PVStructure::shared_pointer nullPtr; + if (rows.get() == 0 || columns.get() == 0) + { + PVStructure::shared_pointer nullPtr; Status errorStatus(Status::STATUSTYPE_ERROR, "no string 'rows' and 'columns' arguments specified"); - m_channelRPCRequester->requestDone(errorStatus, nullPtr); - } - else - { - int i = 0; - int totalFields = 2; // value[], dim - StringArray fieldNames(totalFields); - FieldConstPtrArray fields(totalFields); - fieldNames[i] = "value"; - fields[i++] = getFieldCreate()->createScalarArray(pvDouble); - fieldNames[i] = "dim"; - fields[i++] = getFieldCreate()->createScalarArray(pvInt); + m_channelRPCRequester->requestDone(errorStatus, nullPtr); + } + else + { + int i = 0; + int totalFields = 2; // value[], dim + StringArray fieldNames(totalFields); + FieldConstPtrArray fields(totalFields); + fieldNames[i] = "value"; + fields[i++] = getFieldCreate()->createScalarArray(pvDouble); + fieldNames[i] = "dim"; + fields[i++] = getFieldCreate()->createScalarArray(pvInt); - PVStructure::shared_pointer result( - getPVDataCreate()->createPVStructure( - getFieldCreate()->createStructure("uri:ev4:nt/2012/pwd:NTMatrix", fieldNames, fields) - ) - ); + PVStructure::shared_pointer result( + getPVDataCreate()->createPVStructure( + getFieldCreate()->createStructure("uri:ev4:nt/2012/pwd:NTMatrix", fieldNames, fields) + ) + ); - int32 rowsVal = atoi(rows->get().c_str()); - int32 colsVal = atoi(columns->get().c_str()); - int32 dimValues[] = { rowsVal, colsVal }; - static_pointer_cast(result->getScalarArrayField("dim", pvInt))->put(0, 2, &dimValues[0], 0); + int32 rowsVal = atoi(rows->get().c_str()); + int32 colsVal = atoi(columns->get().c_str()); + int32 dimValues[] = { rowsVal, colsVal }; + static_pointer_cast(result->getScalarArrayField("dim", pvInt))->put(0, 2, &dimValues[0], 0); - PVStringPtr byColumns = static_pointer_cast(args->getSubField("bycolumns")); - bool bycolumns = (byColumns.get() && byColumns->get() == "1"); + PVStringPtr byColumns = static_pointer_cast(args->getSubField("bycolumns")); + bool bycolumns = (byColumns.get() && byColumns->get() == "1"); - int32 len = rowsVal * colsVal; - vector mv(len); - for (int r = 0; r < len; r++) - if (bycolumns) - mv[r] = rand()/((double)RAND_MAX+1) + (int)(r%rowsVal); - else - mv[r] = rand()/((double)RAND_MAX+1) + (int)(r/colsVal); - static_pointer_cast(result->getScalarArrayField("value", pvDouble))->put(0, len, &mv[0], 0); + int32 len = rowsVal * colsVal; + vector mv(len); + for (int r = 0; r < len; r++) + if (bycolumns) + mv[r] = rand()/((double)RAND_MAX+1) + (int)(r%rowsVal); + else + mv[r] = rand()/((double)RAND_MAX+1) + (int)(r/colsVal); + static_pointer_cast(result->getScalarArrayField("value", pvDouble))->put(0, len, &mv[0], 0); - m_channelRPCRequester->requestDone(Status::Ok, result); - } - } + m_channelRPCRequester->requestDone(Status::Ok, result); + } + } else if (m_channelName.find("testImage") == 0) { PVStructure::shared_pointer args( - (pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ? + (pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ? pvArgument->getStructureField("query") : pvArgument - ); + ); const String helpText = "Generates a NTImage structure response that has encoded a specified image.\n" @@ -1236,7 +1239,7 @@ class MockChannelRPC : public ChannelRPC } } else if (m_channelName == "testNTURI") - { + { const String helpText = "Returns the NTURI structure response identical the NTURI request.\n" "Arguments: (none)\n"; @@ -1244,29 +1247,35 @@ class MockChannelRPC : public ChannelRPC return; if (pvArgument->getStructure()->getID() != "uri:ev4:nt/2012/pwd:NTURI") - { - PVStructure::shared_pointer nullPtr; - Status errorStatus(Status::STATUSTYPE_ERROR, "argument is not a NTURI structure"); - m_channelRPCRequester->requestDone(errorStatus, nullPtr); - } - else - { - // return argument as result - m_channelRPCRequester->requestDone(Status::Ok, pvArgument); - } - } - else - { - /* - std::string s; - pvArgument->toString(&s); - std::cout << "RPC" << std::endl << s << std::endl; - */ - m_channelRPCRequester->requestDone(Status::Ok, m_pvStructure); - } + { + PVStructure::shared_pointer nullPtr; + Status errorStatus(Status::STATUSTYPE_ERROR, "argument is not a NTURI structure"); + m_channelRPCRequester->requestDone(errorStatus, nullPtr); + } + else + { + // return argument as result + m_channelRPCRequester->requestDone(Status::Ok, pvArgument); + } + } + else if (m_channelName.find("testServerShutdown") == 0) + { + PVStructure::shared_pointer nullPtr; + m_channelRPCRequester->requestDone(Status::Ok, nullPtr); + testServerShutdown(); + } + else + { + /* + std::string s; + pvArgument->toString(&s); + std::cout << "RPC" << std::endl << s << std::endl; + */ + m_channelRPCRequester->requestDone(Status::Ok, m_pvStructure); + } - if (lastRequest) - destroy(); + if (lastRequest) + destroy(); } virtual void destroy() @@ -1297,28 +1306,28 @@ PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelArray); class MockChannelArray : public ChannelArray { - private: - ChannelArrayRequester::shared_pointer m_channelArrayRequester; - PVArray::shared_pointer m_pvArray; +private: + ChannelArrayRequester::shared_pointer m_channelArrayRequester; + PVArray::shared_pointer m_pvArray; - protected: +protected: MockChannelArray(ChannelArrayRequester::shared_pointer const & channelArrayRequester, - PVStructure::shared_pointer const & /*pvStructure*/, PVStructure::shared_pointer const & /*pvRequest*/) : + PVStructure::shared_pointer const & /*pvStructure*/, PVStructure::shared_pointer const & /*pvRequest*/) : m_channelArrayRequester(channelArrayRequester), m_pvArray(getPVDataCreate()->createPVScalarArray(pvDouble)) { PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelArray); } - public: +public: static ChannelArray::shared_pointer create(ChannelArrayRequester::shared_pointer const & channelArrayRequester, PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) { ChannelArray::shared_pointer thisPtr(new MockChannelArray(channelArrayRequester, pvStructure, pvRequest)); // TODO pvRequest - channelArrayRequester->channelArrayConnect(Status::Ok, thisPtr, static_cast(thisPtr.get())->m_pvArray); - - return thisPtr; + channelArrayRequester->channelArrayConnect(Status::Ok, thisPtr, static_cast(thisPtr.get())->m_pvArray); + + return thisPtr; } virtual ~MockChannelArray() @@ -1329,25 +1338,25 @@ class MockChannelArray : public ChannelArray virtual void putArray(bool lastRequest, int /*offset*/, int /*count*/) { // TODO offset, count - m_channelArrayRequester->putArrayDone(Status::Ok); - if (lastRequest) - destroy(); + m_channelArrayRequester->putArrayDone(Status::Ok); + if (lastRequest) + destroy(); } virtual void getArray(bool lastRequest, int /*offset*/, int /*count*/) { // TODO offset, count - m_channelArrayRequester->getArrayDone(Status::Ok); - if (lastRequest) - destroy(); + m_channelArrayRequester->getArrayDone(Status::Ok); + if (lastRequest) + destroy(); } virtual void setLength(bool lastRequest, int /*length*/, int /*capacity*/) { // TODO offset, capacity - m_channelArrayRequester->setLengthDone(Status::Ok); - if (lastRequest) - destroy(); + m_channelArrayRequester->setLengthDone(Status::Ok); + if (lastRequest) + destroy(); } virtual void destroy() @@ -1374,23 +1383,23 @@ PVACCESS_REFCOUNT_MONITOR_DEFINE(mockMonitor); class MockMonitor : public Monitor, public StructureChangedCallback, public std::tr1::enable_shared_from_this { - private: - String m_channelName; - MonitorRequester::shared_pointer m_monitorRequester; - PVStructure::shared_pointer m_pvStructure; - BitSet::shared_pointer m_changedBitSet; - BitSet::shared_pointer m_overrunBitSet; - bool m_first; - Mutex m_lock; - int m_count; - - MonitorElement::shared_pointer m_thisPtr; - MonitorElement::shared_pointer m_nullMonitor; +private: + String m_channelName; + MonitorRequester::shared_pointer m_monitorRequester; + PVStructure::shared_pointer m_pvStructure; + BitSet::shared_pointer m_changedBitSet; + BitSet::shared_pointer m_overrunBitSet; + bool m_first; + Mutex m_lock; + int m_count; - protected: + MonitorElement::shared_pointer m_thisPtr; + MonitorElement::shared_pointer m_nullMonitor; + +protected: MockMonitor(String const & channelName, MonitorRequester::shared_pointer const & monitorRequester, - PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : - m_channelName(channelName), + PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : + m_channelName(channelName), m_monitorRequester(monitorRequester), m_pvStructure(getRequestedStructure(pvStructure, pvRequest)), m_changedBitSet(new BitSet(m_pvStructure->getNumberFields())), m_overrunBitSet(new BitSet(m_pvStructure->getNumberFields())), @@ -1406,12 +1415,12 @@ class MockMonitor : public Monitor, public StructureChangedCallback, public std: m_thisPtr->pvStructurePtr = m_pvStructure; m_thisPtr->changedBitSet = m_changedBitSet; m_thisPtr->overrunBitSet = m_overrunBitSet; - } + } - public: +public: static Monitor::shared_pointer create(String const & channelName, - MonitorRequester::shared_pointer const & monitorRequester, - PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) + MonitorRequester::shared_pointer const & monitorRequester, + PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) { Monitor::shared_pointer thisPtr(new MockMonitor(channelName, monitorRequester, pvStructure, pvRequest)); StructureConstPtr structurePtr = static_cast(thisPtr.get())->m_pvStructure->getStructure(); @@ -1429,7 +1438,7 @@ class MockMonitor : public Monitor, public StructureChangedCallback, public std: virtual Status start() { // first monitor - Monitor::shared_pointer thisPtr = shared_from_this(); + Monitor::shared_pointer thisPtr = shared_from_this(); m_monitorRequester->monitorEvent(thisPtr); return Status::Ok; @@ -1440,12 +1449,12 @@ class MockMonitor : public Monitor, public StructureChangedCallback, public std: return Status::Ok; } - virtual void structureChanged() - { - m_count = 0; - Monitor::shared_pointer thisPtr = shared_from_this(); + virtual void structureChanged() + { + m_count = 0; + Monitor::shared_pointer thisPtr = shared_from_this(); m_monitorRequester->monitorEvent(thisPtr); - } + } virtual MonitorElement::shared_pointer poll() { @@ -1495,21 +1504,21 @@ class MockMonitor : public Monitor, public StructureChangedCallback, public std: PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannel); class MockChannel : public Channel { - private: - ChannelProvider::weak_pointer m_provider; - ChannelRequester::shared_pointer m_requester; - String m_name; - String m_remoteAddress; - public: // TODO - PVStructure::shared_pointer m_pvStructure; +private: + ChannelProvider::weak_pointer m_provider; + ChannelRequester::shared_pointer m_requester; + String m_name; + String m_remoteAddress; +public: // TODO + PVStructure::shared_pointer m_pvStructure; - protected: +protected: MockChannel( - ChannelProvider::shared_pointer provider, - ChannelRequester::shared_pointer requester, - String name, - String remoteAddress) : + ChannelProvider::shared_pointer provider, + ChannelRequester::shared_pointer requester, + String name, + String remoteAddress) : m_provider(provider), m_requester(requester), m_name(name), @@ -1519,155 +1528,154 @@ class MockChannel : public Channel { PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannel); if (structureStore.find(m_name) != structureStore.end()) - m_pvStructure = structureStore[m_name]; + m_pvStructure = structureStore[m_name]; else { - // create structure + // create structure - if (m_name.find("testArray") == 0) - { - String allProperties(""); - // String allProperties("alarm,timeStamp,display,control"); - m_pvStructure = getStandardPVField()->scalarArray(pvDouble,allProperties); - PVDoubleArrayPtr pvField = static_pointer_cast(m_pvStructure->getScalarArrayField(String("value"), pvDouble)); + if (m_name.find("testArray") == 0) + { + String allProperties(""); + // String allProperties("alarm,timeStamp,display,control"); + m_pvStructure = getStandardPVField()->scalarArray(pvDouble,allProperties); + PVDoubleArrayPtr pvField = static_pointer_cast(m_pvStructure->getScalarArrayField(String("value"), pvDouble)); - int specCount = 0; char postfix[64]; - int done = sscanf(m_name.c_str(), "testArray%d%s", &specCount, postfix); + int specCount = 0; char postfix[64]; + int done = sscanf(m_name.c_str(), "testArray%d%s", &specCount, postfix); - if (done && specCount > 0) - { - pvField->setCapacity(specCount); - pvField->setLength(specCount); + if (done && specCount > 0) + { + pvField->setCapacity(specCount); + pvField->setLength(specCount); - double v = 0; - int ix = 0; - const int COUNT = 1024; + double v = 0; + int ix = 0; + const int COUNT = 1024; - int n = 0; - while (n < specCount) - { + int n = 0; + while (n < specCount) + { - double array[COUNT]; - int i = 0; - for (; i < COUNT && n < specCount; i++) - { - array[i] = v; v+=1; n++; - } - pvField->put(ix, i, array, 0); - ix += i; - } - } - else - { - double v = 0; - int ix = 0; - const int COUNT = 1024; + double array[COUNT]; + int i = 0; + for (; i < COUNT && n < specCount; i++) + { + array[i] = v; v+=1; n++; + } + pvField->put(ix, i, array, 0); + ix += i; + } + } + else + { + double v = 0; + int ix = 0; + const int COUNT = 1024; - pvField->setCapacity(1024*COUNT); - for (int n = 0; n < 1024; n++) - { + pvField->setCapacity(1024*COUNT); + for (int n = 0; n < 1024; n++) + { - double array[COUNT]; - for (int i = 0; i < COUNT; i++) - { - array[i] = v; v+=1.1; - } - pvField->put(ix, COUNT, array, 0); - ix += COUNT; - } - } - /* - printf("array prepared------------------------------------!!!\n"); - String str; - pvField->toString(&str); - printf("%s\n", str.c_str()); - printf("=============------------------------------------!!!\n"); - */ - } + double array[COUNT]; + for (int i = 0; i < COUNT; i++) + { + array[i] = v; v+=1.1; + } + pvField->put(ix, COUNT, array, 0); + ix += COUNT; + } + } + /* + printf("array prepared------------------------------------!!!\n"); + String str; + pvField->toString(&str); + printf("%s\n", str.c_str()); + printf("=============------------------------------------!!!\n"); + */ + } else if (m_name.find("testMP") == 0 || m_name.find("testImage") == 0) - { - m_pvStructure = getPVDataCreate()->createPVStructure(makeImageStruc()); + { + m_pvStructure = getPVDataCreate()->createPVStructure(makeImageStruc()); initImageEPICSv4GrayscaleLogo(m_pvStructure); } else if (m_name.find("testTable") == 0) { - cout << "test Taaa ble " << endl; m_pvStructure = createNTTable(5); // 5 columns generateNTTableDoubleValues(m_pvStructure); } else if (m_name.find("testADC") == 0) - { - int i = 0; - int totalFields = 6; - StringArray fieldNames(totalFields); - FieldConstPtrArray fields(totalFields); - fieldNames[i] = "value"; - fields[i++] = getFieldCreate()->createScalarArray(pvDouble); - fieldNames[i] = "dim"; - fields[i++] = getFieldCreate()->createScalarArray(pvInt); - fieldNames[i] = "descriptor"; - fields[i++] = getFieldCreate()->createScalar(pvString); - fieldNames[i] = "timeStamp"; - fields[i++] = getStandardField()->timeStamp(); - fieldNames[i] = "alarm"; - fields[i++] = getStandardField()->alarm(); - fieldNames[i] = "display"; - fields[i++] = getStandardField()->display(); + { + int i = 0; + int totalFields = 6; + StringArray fieldNames(totalFields); + FieldConstPtrArray fields(totalFields); + fieldNames[i] = "value"; + fields[i++] = getFieldCreate()->createScalarArray(pvDouble); + fieldNames[i] = "dim"; + fields[i++] = getFieldCreate()->createScalarArray(pvInt); + fieldNames[i] = "descriptor"; + fields[i++] = getFieldCreate()->createScalar(pvString); + fieldNames[i] = "timeStamp"; + fields[i++] = getStandardField()->timeStamp(); + fieldNames[i] = "alarm"; + fields[i++] = getStandardField()->alarm(); + fieldNames[i] = "display"; + fields[i++] = getStandardField()->display(); - m_pvStructure = - getPVDataCreate()->createPVStructure( - getFieldCreate()->createStructure("uri:ev4:nt/2012/pwd:NTMatrix", fieldNames, fields) - ); + m_pvStructure = + getPVDataCreate()->createPVStructure( + getFieldCreate()->createStructure("uri:ev4:nt/2012/pwd:NTMatrix", fieldNames, fields) + ); - // fill with default values - int dimValue = 0; - static_pointer_cast(m_pvStructure->getScalarArrayField("dim", pvInt))->put(0, 1, &dimValue, 0); + // fill with default values + int dimValue = 0; + static_pointer_cast(m_pvStructure->getScalarArrayField("dim", pvInt))->put(0, 1, &dimValue, 0); - m_pvStructure->getStringField("descriptor")->put("Simulated ADC that provides NTMatrix value"); - PVStructurePtr displayStructure = m_pvStructure->getStructureField("display"); - displayStructure->getDoubleField("limitLow")->put(-1.0); - displayStructure->getDoubleField("limitHigh")->put(1.0); - displayStructure->getStringField("description")->put("Simulated ADC"); - displayStructure->getStringField("format")->put("%f"); - displayStructure->getStringField("units")->put("V"); - } - else if (m_name.find("testRPC") == 0 || m_name == "testNTTable" || m_name == "testNTMatrix") - { - StringArray fieldNames; - PVFieldPtrArray fields; - m_pvStructure = getPVDataCreate()->createPVStructure(fieldNames, fields); - } - else if (m_name.find("testValueOnly") == 0) - { - String allProperties(""); - m_pvStructure = getStandardPVField()->scalar(pvDouble,allProperties); - } + m_pvStructure->getStringField("descriptor")->put("Simulated ADC that provides NTMatrix value"); + PVStructurePtr displayStructure = m_pvStructure->getStructureField("display"); + displayStructure->getDoubleField("limitLow")->put(-1.0); + displayStructure->getDoubleField("limitHigh")->put(1.0); + displayStructure->getStringField("description")->put("Simulated ADC"); + displayStructure->getStringField("format")->put("%f"); + displayStructure->getStringField("units")->put("V"); + } + else if (m_name.find("testRPC") == 0 || m_name == "testNTTable" || m_name == "testNTMatrix") + { + StringArray fieldNames; + PVFieldPtrArray fields; + m_pvStructure = getPVDataCreate()->createPVStructure(fieldNames, fields); + } + else if (m_name.find("testValueOnly") == 0) + { + String allProperties(""); + m_pvStructure = getStandardPVField()->scalar(pvDouble,allProperties); + } else if (m_name == "testCounter") - { - String allProperties("timeStamp"); - m_pvStructure = getStandardPVField()->scalar(pvInt,allProperties); - } - else - { - String allProperties("alarm,timeStamp,display,control,valueAlarm"); - m_pvStructure = getStandardPVField()->scalar(pvDouble,allProperties); - //PVDoublePtr pvField = m_pvStructure->getDoubleField(String("value")); - //pvField->put(1.123); - } + { + String allProperties("timeStamp"); + m_pvStructure = getStandardPVField()->scalar(pvInt,allProperties); + } + else + { + String allProperties("alarm,timeStamp,display,control,valueAlarm"); + m_pvStructure = getStandardPVField()->scalar(pvDouble,allProperties); + //PVDoublePtr pvField = m_pvStructure->getDoubleField(String("value")); + //pvField->put(1.123); + } - structureStore[m_name] = m_pvStructure; + structureStore[m_name] = m_pvStructure; } } - public: +public: static Channel::shared_pointer create( - ChannelProvider::shared_pointer provider, - ChannelRequester::shared_pointer requester, - String name, - String remoteAddress) + ChannelProvider::shared_pointer provider, + ChannelRequester::shared_pointer requester, + String name, + String remoteAddress) { Channel::shared_pointer channelPtr(new MockChannel(provider, requester, name, remoteAddress)); @@ -1675,7 +1683,7 @@ class MockChannel : public Channel { requester->channelStateChange(channelPtr, CONNECTED); return channelPtr; - } + } virtual ~MockChannel() { @@ -1733,74 +1741,74 @@ class MockChannel : public Channel { virtual void getField(GetFieldRequester::shared_pointer const & requester,epics::pvData::String const & subField) { - PVFieldPtr pvField; - if(subField == "") - { - pvField = m_pvStructure; - } - else - { - pvField = m_pvStructure->getSubField(subField); - } + PVFieldPtr pvField; + if(subField == "") + { + pvField = m_pvStructure; + } + else + { + pvField = m_pvStructure->getSubField(subField); + } - if(pvField == NULL) - { - string errMsg = "field '" + subField + "' not found"; - FieldConstPtr nullPtr; - Status errorStatus(Status::STATUSTYPE_ERROR, errMsg); - requester->getDone(errorStatus,nullPtr); - return; - } - FieldConstPtr fieldPtr = pvField->getField(); - requester->getDone(Status::Ok, fieldPtr); + if(pvField == NULL) + { + string errMsg = "field '" + subField + "' not found"; + FieldConstPtr nullPtr; + Status errorStatus(Status::STATUSTYPE_ERROR, errMsg); + requester->getDone(errorStatus,nullPtr); + return; + } + FieldConstPtr fieldPtr = pvField->getField(); + requester->getDone(Status::Ok, fieldPtr); } virtual ChannelProcess::shared_pointer createChannelProcess( - ChannelProcessRequester::shared_pointer const & channelProcessRequester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) + ChannelProcessRequester::shared_pointer const & channelProcessRequester, + epics::pvData::PVStructure::shared_pointer const & pvRequest) { - return MockChannelProcess::create(m_name, channelProcessRequester, m_pvStructure, pvRequest); + return MockChannelProcess::create(m_name, channelProcessRequester, m_pvStructure, pvRequest); } virtual ChannelGet::shared_pointer createChannelGet( - ChannelGetRequester::shared_pointer const & channelGetRequester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) + ChannelGetRequester::shared_pointer const & channelGetRequester, + epics::pvData::PVStructure::shared_pointer const & pvRequest) { - return MockChannelGet::create(channelGetRequester, m_pvStructure, pvRequest); + return MockChannelGet::create(channelGetRequester, m_pvStructure, pvRequest); } virtual ChannelPut::shared_pointer createChannelPut( - ChannelPutRequester::shared_pointer const & channelPutRequester, + ChannelPutRequester::shared_pointer const & channelPutRequester, epics::pvData::PVStructure::shared_pointer const & pvRequest) { - return MockChannelPut::create(m_name, channelPutRequester, m_pvStructure, pvRequest); + return MockChannelPut::create(m_name, channelPutRequester, m_pvStructure, pvRequest); } virtual ChannelPutGet::shared_pointer createChannelPutGet( - ChannelPutGetRequester::shared_pointer const & channelPutGetRequester, + ChannelPutGetRequester::shared_pointer const & channelPutGetRequester, epics::pvData::PVStructure::shared_pointer const & pvRequest) { - return MockChannelPutGet::create(m_name, channelPutGetRequester, m_pvStructure, pvRequest); + return MockChannelPutGet::create(m_name, channelPutGetRequester, m_pvStructure, pvRequest); } virtual ChannelRPC::shared_pointer createChannelRPC(ChannelRPCRequester::shared_pointer const & channelRPCRequester, - epics::pvData::PVStructure::shared_pointer const & pvRequest) + epics::pvData::PVStructure::shared_pointer const & pvRequest) { - return MockChannelRPC::create(channelRPCRequester, m_name, m_pvStructure, pvRequest); + return MockChannelRPC::create(channelRPCRequester, m_name, m_pvStructure, pvRequest); } virtual epics::pvData::Monitor::shared_pointer createMonitor( epics::pvData::MonitorRequester::shared_pointer const & monitorRequester, epics::pvData::PVStructure::shared_pointer const & pvRequest) { - return MockMonitor::create(m_name, monitorRequester, m_pvStructure, pvRequest); + return MockMonitor::create(m_name, monitorRequester, m_pvStructure, pvRequest); } virtual ChannelArray::shared_pointer createChannelArray( ChannelArrayRequester::shared_pointer const & channelArrayRequester, epics::pvData::PVStructure::shared_pointer const & pvRequest) { - return MockChannelArray::create(channelArrayRequester, m_pvStructure, pvRequest); + return MockChannelArray::create(channelArrayRequester, m_pvStructure, pvRequest); } virtual void printInfo() { @@ -1813,14 +1821,14 @@ class MockChannel : public Channel { //std::ostringstream ostr; //static String emptyString; - out->append( "CHANNEL : "); out->append(m_name); - out->append("\nSTATE : "); out->append(ConnectionStateNames[getConnectionState()]); - if (isConnected()) - { - out->append("\nADDRESS : "); out->append(getRemoteAddress()); - //out->append("\nRIGHTS : "); out->append(getAccessRights()); - } - out->append("\n"); + out->append( "CHANNEL : "); out->append(m_name); + out->append("\nSTATE : "); out->append(ConnectionStateNames[getConnectionState()]); + if (isConnected()) + { + out->append("\nADDRESS : "); out->append(getRemoteAddress()); + //out->append("\nRIGHTS : "); out->append(getAccessRights()); + } + out->append("\n"); } }; @@ -1829,7 +1837,7 @@ class MockServerChannelProvider; class MockChannelFind : public ChannelFind { - public: +public: typedef std::tr1::shared_ptr shared_pointer; typedef std::tr1::shared_ptr const_shared_pointer; @@ -1854,26 +1862,26 @@ class MockChannelFind : public ChannelFind throw std::runtime_error("not supported"); } - private: - ChannelProvider::weak_pointer m_provider; +private: + ChannelProvider::weak_pointer m_provider; }; class MockServerChannelProvider : public ChannelProvider, - public std::tr1::enable_shared_from_this + public std::tr1::enable_shared_from_this { - public: +public: typedef std::tr1::shared_ptr shared_pointer; typedef std::tr1::shared_ptr const_shared_pointer; - MockServerChannelProvider() : - m_mockChannelFind(), - m_counterChannel(), - m_adcChannel(), + MockServerChannelProvider() : + m_mockChannelFind(), + m_counterChannel(), + m_adcChannel(), m_mpChannel(), m_scan1Hz(1.0), - m_scan1HzThread(), + m_scan1HzThread(), m_scan10Hz(0.1), m_scan10HzThread(), m_adcAction(), @@ -1883,24 +1891,24 @@ class MockServerChannelProvider : public ChannelProvider, { } - virtual ~MockServerChannelProvider() - { - m_scan1Hz.stopped.set(); + virtual ~MockServerChannelProvider() + { + m_scan1Hz.stopped.set(); m_scan10Hz.stopped.set(); m_adcAction.stopped.set(); m_imgAction.stopped.set(); } - void initialize() - { - ChannelProvider::shared_pointer chProviderPtr = shared_from_this(); - m_mockChannelFind.reset(new MockChannelFind(chProviderPtr)); + void initialize() + { + ChannelProvider::shared_pointer chProviderPtr = shared_from_this(); + m_mockChannelFind.reset(new MockChannelFind(chProviderPtr)); - std::tr1::shared_ptr cr(new ChannelRequesterImpl()); - m_counterChannel = MockChannel::create(chProviderPtr, cr, "testCounter", "local"); - std::tr1::shared_ptr cpr(new ChannelProcessRequesterImpl()); - ChannelProcess::shared_pointer process = m_counterChannel->createChannelProcess(cpr, PVStructure::shared_pointer()); + std::tr1::shared_ptr cr(new ChannelRequesterImpl()); + m_counterChannel = MockChannel::create(chProviderPtr, cr, "testCounter", "local"); + std::tr1::shared_ptr cpr(new ChannelProcessRequesterImpl()); + ChannelProcess::shared_pointer process = m_counterChannel->createChannelProcess(cpr, PVStructure::shared_pointer()); m_scan1Hz.toProcess.push_back(process); Channel::shared_pointer c = MockChannel::create(chProviderPtr, cr, "testRandom", "local"); @@ -1914,17 +1922,17 @@ class MockServerChannelProvider : public ChannelProvider, m_scan1HzThread.reset(new Thread("process1hz", highPriority, &m_scan1Hz)); m_scan10HzThread.reset(new Thread("process10hz", highPriority, &m_scan10Hz)); - m_adcChannel = MockChannel::create(chProviderPtr, cr, "testADC", "local"); - m_adcAction.name = "testADC"; - m_adcAction.adcMatrix = static_pointer_cast(m_adcChannel)->m_pvStructure; - m_adcAction.adcSim = createSimADC("testADC"); - m_adcThread.reset(new Thread("adcThread", highPriority, &m_adcAction)); + m_adcChannel = MockChannel::create(chProviderPtr, cr, "testADC", "local"); + m_adcAction.name = "testADC"; + m_adcAction.adcMatrix = static_pointer_cast(m_adcChannel)->m_pvStructure; + m_adcAction.adcSim = createSimADC("testADC"); + m_adcThread.reset(new Thread("adcThread", highPriority, &m_adcAction)); m_mpChannel = MockChannel::create(chProviderPtr, cr, "testMP", "local"); m_imgAction.name = "testMP"; m_imgAction.pvImage = static_pointer_cast(m_mpChannel)->m_pvStructure; m_imgThread.reset(new Thread("imgThread", highPriority, &m_imgAction)); - } + } virtual epics::pvData::String getProviderName() { @@ -1936,108 +1944,117 @@ class MockServerChannelProvider : public ChannelProvider, } virtual ChannelFind::shared_pointer channelFind( - epics::pvData::String const & channelName, - ChannelFindRequester::shared_pointer const & channelFindRequester) + epics::pvData::String const & channelName, + ChannelFindRequester::shared_pointer const & channelFindRequester) { // channel that starts with "test" always exists - bool exists = (channelName.find("test") == 0); + bool exists = (channelName.find("test") == 0); channelFindRequester->channelFindResult(Status::Ok, m_mockChannelFind, exists); return m_mockChannelFind; } virtual Channel::shared_pointer createChannel( - epics::pvData::String const & channelName, - ChannelRequester::shared_pointer const & channelRequester, - short priority) + epics::pvData::String const & channelName, + ChannelRequester::shared_pointer const & channelRequester, + short priority) { return createChannel(channelName, channelRequester, priority, "local"); } virtual Channel::shared_pointer createChannel( - epics::pvData::String const & channelName, - ChannelRequester::shared_pointer const & channelRequester, - short /*priority*/, - epics::pvData::String const & address) + epics::pvData::String const & channelName, + ChannelRequester::shared_pointer const & channelRequester, + short /*priority*/, + epics::pvData::String const & address) { if (address == "local") { - if (channelName == "testCounter") - { - channelRequester->channelCreated(Status::Ok, m_counterChannel); - return m_counterChannel; - } - else if (channelName == "testADC") - { - channelRequester->channelCreated(Status::Ok, m_adcChannel); - return m_adcChannel; - } + if (channelName == "testCounter") + { + channelRequester->channelCreated(Status::Ok, m_counterChannel); + return m_counterChannel; + } + else if (channelName == "testADC") + { + channelRequester->channelCreated(Status::Ok, m_adcChannel); + return m_adcChannel; + } else if (channelName == "testMP") { channelRequester->channelCreated(Status::Ok, m_mpChannel); return m_mpChannel; } else - { - ChannelProvider::shared_pointer chProviderPtr = shared_from_this(); - Channel::shared_pointer channel = MockChannel::create(chProviderPtr, channelRequester, channelName, address); - channelRequester->channelCreated(Status::Ok, channel); - return channel; - } + { + ChannelProvider::shared_pointer chProviderPtr = shared_from_this(); + Channel::shared_pointer channel = MockChannel::create(chProviderPtr, channelRequester, channelName, address); + channelRequester->channelCreated(Status::Ok, channel); + return channel; + } } else { - Channel::shared_pointer nullPtr; + Channel::shared_pointer nullPtr; Status errorStatus(Status::STATUSTYPE_ERROR, "only local supported"); channelRequester->channelCreated(errorStatus, nullPtr); return nullPtr; } } - private: +private: ChannelFind::shared_pointer m_mockChannelFind; Channel::shared_pointer m_counterChannel; Channel::shared_pointer m_adcChannel; Channel::shared_pointer m_mpChannel; - ProcessAction m_scan1Hz; - auto_ptr m_scan1HzThread; + ProcessAction m_scan1Hz; + auto_ptr m_scan1HzThread; ProcessAction m_scan10Hz; auto_ptr m_scan10HzThread; ADCAction m_adcAction; - auto_ptr m_adcThread; + auto_ptr m_adcThread; NTImageAction m_imgAction; auto_ptr m_imgThread; }; - +static ServerContextImpl::shared_pointer ctx; void testServer(int timeToRun) { - - MockServerChannelProvider::shared_pointer channelProvider(new MockServerChannelProvider()); - channelProvider->initialize(); - - ChannelProvider::shared_pointer ptr = channelProvider; - registerChannelProvider(ptr); - ServerContextImpl::shared_pointer ctx = ServerContextImpl::create(); - ChannelAccess::shared_pointer channelAccess = getChannelAccess(); - ctx->initialize(channelAccess); + MockServerChannelProvider::shared_pointer channelProvider(new MockServerChannelProvider()); + channelProvider->initialize(); - ctx->printInfo(); + ChannelProvider::shared_pointer ptr = channelProvider; + registerChannelProvider(ptr); - ctx->run(timeToRun); + //ServerContextImpl::shared_pointer ctx = ServerContextImpl::create(); + ctx = ServerContextImpl::create(); + ChannelAccess::shared_pointer channelAccess = getChannelAccess(); + ctx->initialize(channelAccess); - ctx->destroy(); + ctx->printInfo(); - unregisterChannelProvider(ptr); + ctx->run(timeToRun); - structureChangedListeners.clear(); - structureStore.clear(); + ctx->destroy(); + + unregisterChannelProvider(ptr); + + structureChangedListeners.clear(); + structureStore.clear(); + + ctx.reset(); +} + +void testServerShutdown() +{ + // NOTE: this is not thread-safe TODO + ctx->shutdown(); } #include @@ -2045,13 +2062,13 @@ void testServer(int timeToRun) void usage (char *argv[]) { fprintf (stderr, "\nUsage: %s [options]\n\n" - " -h: Help: Print this message\n" - "\noptions:\n" - " -t : Time to run in seconds, 0 for forever\n" - " -d: Enable debug output\n" - " -c: Wait for clean shutdown and report used instance count (for expert users)" - "\n\n", - argv[0]); + " -h: Help: Print this message\n" + "\noptions:\n" + " -t : Time to run in seconds, 0 for forever\n" + " -d: Enable debug output\n" + " -c: Wait for clean shutdown and report used instance count (for expert users)" + "\n\n", + argv[0]); } @@ -2103,14 +2120,14 @@ int main(int argc, char *argv[]) shutdownSimADCs(); - cout << "Done" << endl; + cout << "Done" << endl; if (cleanupAndReport) { // TODO implement wait on context - epicsThreadSleep ( 3.0 ); - //std::cout << "-----------------------------------------------------------------------" << std::endl; - //epicsExitCallAtExits(); + epicsThreadSleep ( 3.0 ); + //std::cout << "-----------------------------------------------------------------------" << std::endl; + //epicsExitCallAtExits(); } return (0);