diff --git a/src/remoteClient/clientContextImpl.cpp b/src/remoteClient/clientContextImpl.cpp index 4031504..1777b82 100644 --- a/src/remoteClient/clientContextImpl.cpp +++ b/src/remoteClient/clientContextImpl.cpp @@ -73,6 +73,9 @@ typedef std::map IOIDResponseRequestM catch (std::exception &e) { LOG(logLevelError, "Unhandled exception caught from client code at %s:%d: %s", __FILE__, __LINE__, e.what()); } \ catch (...) { LOG(logLevelError, "Unhandled exception caught from client code at %s:%d.", __FILE__, __LINE__); }} +#define SEND_MESSAGE(WEAK, PTR, MSG, MTYPE) \ +do{requester_type::shared_pointer PTR((WEAK).lock()); if(PTR) (PTR)->message(MSG, MTYPE); }while(0) + /** * Base channel request. * @author Matej Sekoranja @@ -2154,18 +2157,25 @@ public: PVStructurePtr pvOptions = m_pvRequest->getSubField("record._options"); if (pvOptions) { - PVStringPtr pvString = pvOptions->getSubField("queueSize"); - if (pvString) { - int32 size; - std::stringstream ss; - ss << pvString->get(); - ss >> size; - if (size > 1) - m_queueSize = size; + PVScalarPtr option(pvOptions->getSubField("queueSize")); + if (option) { + try { + m_queueSize = option->getAs(); + if(m_queueSize<2) + m_queueSize = 2; + }catch(std::runtime_error& e){ + SEND_MESSAGE(m_callback, cb, "Invalid queueSize=", warningMessage); + } + } + + option = pvOptions->getSubField("pipeline"); + if (option) { + try { + m_pipeline = option->getAs(); + }catch(std::runtime_error& e){ + SEND_MESSAGE(m_callback, cb, "Invalid pipeline=", warningMessage); + } } - pvString = pvOptions->getSubField("pipeline"); - if (pvString) - m_pipeline = (pvString->get() == "true"); // pipeline options if (m_pipeline) @@ -2173,23 +2183,40 @@ public: // defaults to queueSize/2 m_ackAny = m_queueSize/2; - pvString = pvOptions->getSubField("ackAny"); - if (pvString) { - int32 size; - string sval = pvString->get(); - string::size_type slen = sval.length(); - bool percentage = (slen > 0) && (sval[slen-1] == '%'); - if (percentage) - sval = sval.substr(0, slen-1); - std::stringstream ss; - ss << sval; - ss >> size; - if (percentage) - size = (m_queueSize * size) / 100; - if (size <= 0) + bool done = false; + int32 size; + + option = pvOptions->getSubField("ackAny"); + if (option) { + if(option->getScalar()->getScalarType()==pvString) { + std::string sval(option->getAs()); + + if(!sval.empty() && sval[sval.size()-1]=='%') { + try { + double percent = castUnsafe(sval.substr(0, sval.size()-1)); + size = (m_queueSize * percent) / 100.0; + done = true; + }catch(std::runtime_error&){ + SEND_MESSAGE(m_callback, cb, "ackAny= invalid precentage", warningMessage); + } + } + } + + if(!done) { + try { + size = option->getAs(); + done = true; + }catch(std::runtime_error&){ + SEND_MESSAGE(m_callback, cb, "ackAny= invalid value", warningMessage); + } + } + + if(!done) { + } else if (size <= 0) { m_ackAny = 1; - else + } else { m_ackAny = (m_ackAny <= m_queueSize) ? size : m_queueSize; + } } } } @@ -2221,9 +2248,7 @@ public: } } - virtual ~ChannelMonitorImpl() - { - } + virtual ~ChannelMonitorImpl() {} ChannelBaseRequester::shared_pointer getRequester() OVERRIDE FINAL { return m_callback.lock(); } diff --git a/testApp/remote/channelAccessIFTest.cpp b/testApp/remote/channelAccessIFTest.cpp index 99a4210..c95c2a2 100644 --- a/testApp/remote/channelAccessIFTest.cpp +++ b/testApp/remote/channelAccessIFTest.cpp @@ -1755,7 +1755,7 @@ void ChannelAccessIFTest::test_channelMonitorWithInvalidRequesterAndRequest() { void ChannelAccessIFTest::test_channelMonitor(int queueSize) { - testDiag("BEGIN TEST %s:", CURRENT_FUNCTION); + testDiag("BEGIN TEST %s: queueSize=%d", CURRENT_FUNCTION, queueSize); ostringstream ostream; ostream << queueSize; string request = "record[queueSize=";