diff --git a/testApp/remote/eget.cpp b/testApp/remote/eget.cpp index 82676b7..e2f3793 100644 --- a/testApp/remote/eget.cpp +++ b/testApp/remote/eget.cpp @@ -595,11 +595,14 @@ class ChannelGetRequesterImpl : public ChannelGetRequester Mutex m_pointerMutex; Event m_event; + bool m_done; + public: ChannelGetRequesterImpl(String channelName, bool printValue) : m_channelName(channelName), - m_printValue(printValue) + m_printValue(printValue), + m_done(false) { } @@ -638,6 +641,7 @@ class ChannelGetRequesterImpl : public ChannelGetRequester else { std::cerr << "[" << m_channelName << "] failed to create channel get: " << status.toString() << std::endl; + m_event.signal(); } } @@ -655,6 +659,8 @@ class ChannelGetRequesterImpl : public ChannelGetRequester { Lock lock(m_pointerMutex); { + m_done = true; + if (m_printValue) { // needed since we access the data @@ -664,12 +670,9 @@ class ChannelGetRequesterImpl : public ChannelGetRequester } } - // this is OK since calle holds also owns it + // this is OK since callee holds also owns it m_channelGet.reset(); } - - m_event.signal(); - } else { @@ -681,6 +684,7 @@ class ChannelGetRequesterImpl : public ChannelGetRequester } } + m_event.signal(); } PVStructure::shared_pointer getPVStructure() @@ -691,7 +695,15 @@ class ChannelGetRequesterImpl : public ChannelGetRequester bool waitUntilGet(double timeOut) { - return m_event.wait(timeOut); + 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; } }; @@ -705,9 +717,12 @@ class ChannelRPCRequesterImpl : public ChannelRPCRequester Event m_connectionEvent; String m_channelName; + PVStructure::shared_pointer m_lastResponse; + bool m_done; + public: - ChannelRPCRequesterImpl(String channelName) : m_channelName(channelName) {} + ChannelRPCRequesterImpl(String channelName) : m_channelName(channelName), m_done(false) {} virtual String getRequesterName() { @@ -740,6 +755,7 @@ class ChannelRPCRequesterImpl : public ChannelRPCRequester else { std::cerr << "[" << m_channelName << "] failed to create channel get: " << status.toString() << std::endl; + m_connectionEvent.signal(); } } @@ -757,15 +773,17 @@ class ChannelRPCRequesterImpl : public ChannelRPCRequester { Lock lock(m_pointerMutex); + m_done = true; + m_lastResponse = pvResponse; + + /* formatNT(std::cout, pvResponse); std::cout << std::endl; + */ // this is OK since calle holds also owns it m_channelRPC.reset(); } - - m_event.signal(); - } else { @@ -777,6 +795,7 @@ class ChannelRPCRequesterImpl : public ChannelRPCRequester } } + m_event.signal(); } /* @@ -787,14 +806,40 @@ class ChannelRPCRequesterImpl : public ChannelRPCRequester } */ + PVStructure::shared_pointer getLastResponse() + { + Lock lock(m_pointerMutex); + return m_lastResponse; + } + bool waitUntilRPC(double timeOut) { - return m_event.wait(timeOut); + 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; } bool waitUntilConnected(double timeOut) { - return m_connectionEvent.wait(timeOut); + 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); + connected = (m_channelRPC.get() != 0); + } + return connected ? true : false; } }; @@ -998,7 +1043,7 @@ int main (int argc, char *argv[]) } shared_ptr getRequesterImpl( - new ChannelGetRequesterImpl(channel->getChannelName(), !collectValues) + new ChannelGetRequesterImpl(channel->getChannelName(), false) ); ChannelGet::shared_pointer channelGet = channel->createChannelGet(getRequesterImpl, pvRequest); bool ok = getRequesterImpl->waitUntilGet(timeOut); @@ -1006,7 +1051,12 @@ int main (int argc, char *argv[]) if (ok && collectValues) { collectedValues.push_back(getRequesterImpl->getPVStructure()); - //collectedNames.push_back(channel->getChannelName()); + // no labels collectedNames.push_back(channel->getChannelName()); + } + else + { + // print immediately + printValue(channel->getChannelName(), getRequesterImpl->getPVStructure()); } } else @@ -1171,21 +1221,25 @@ int main (int argc, char *argv[]) { channelRPC->request(arg, true); allOK &= rpcRequesterImpl->waitUntilRPC(timeOut); + if (allOK) + { + formatNT(std::cout, rpcRequesterImpl->getLastResponse()); + std::cout << std::endl; + } } else { allOK = false; - channel->destroy(); - std::cerr << "[" << channel->getChannelName() << "] RPC create timeout" << std::endl; } } else { allOK = false; - channel->destroy(); std::cerr << "[" << channel->getChannelName() << "] connection timeout" << std::endl; } - + + channel->destroy(); + ClientFactory::stop(); } diff --git a/testApp/remote/pvget.cpp b/testApp/remote/pvget.cpp index 6a51d4d..9f05029 100644 --- a/testApp/remote/pvget.cpp +++ b/testApp/remote/pvget.cpp @@ -55,6 +55,43 @@ void usage (void) , DEFAULT_REQUEST, DEFAULT_TIMEOUT); } +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 && valueType != scalarArray) + { + // switch to structure mode + std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; + } + else + { + if (fieldSeparator == ' ' && value->getField()->getType() == scalar) + std::cout << std::setw(30) << std::left << channelName; + else + std::cout << channelName; + + std::cout << fieldSeparator; + + terse(std::cout, value) << std::endl; + } + } + } + else if (mode == TerseMode) + terseStructure(std::cout, pv) << std::endl; + else + std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; +} + class ChannelGetRequesterImpl : public ChannelGetRequester { @@ -66,9 +103,11 @@ class ChannelGetRequesterImpl : public ChannelGetRequester Event m_event; String m_channelName; + bool m_done; + public: - ChannelGetRequesterImpl(String channelName) : m_channelName(channelName) {} + ChannelGetRequesterImpl(String channelName) : m_channelName(channelName), m_done(false) {} virtual String getRequesterName() { @@ -105,6 +144,7 @@ class ChannelGetRequesterImpl : public ChannelGetRequester else { std::cerr << "[" << m_channelName << "] failed to create channel get: " << status.toString() << std::endl; + m_event.signal(); } } @@ -121,50 +161,21 @@ class ChannelGetRequesterImpl : public ChannelGetRequester // access smart pointers { Lock lock(m_pointerMutex); + + m_done = true; + + /* { // needed since we access the data ScopedLock dataLock(m_channelGet); + + printValue(m_channelName, m_pvStructure); - if (mode == ValueOnlyMode) - { - PVField::shared_pointer value = m_pvStructure->getSubField("value"); - if (value.get() == 0) - { - std::cerr << "no 'value' field" << std::endl; - std::cout << m_channelName << std::endl << *(m_pvStructure.get()) << std::endl << std::endl; - } - else - { - Type valueType = value->getField()->getType(); - if (valueType != scalar && valueType != scalarArray) - { - // switch to structure mode - std::cout << m_channelName << std::endl << *(m_pvStructure.get()) << std::endl << std::endl; - } - else - { - if (fieldSeparator == ' ' && value->getField()->getType() == scalar) - std::cout << std::setw(30) << std::left << m_channelName; - else - std::cout << m_channelName; - - std::cout << fieldSeparator; - - terse(std::cout, value) << std::endl; - } - } - } - else if (mode == TerseMode) - terseStructure(std::cout, m_pvStructure) << std::endl; - else - std::cout << m_channelName << std::endl << *(m_pvStructure.get()) << std::endl << std::endl; - } - // this is OK since calle holds also owns it + } + */ + // this is OK since callee holds also owns it m_channelGet.reset(); } - - m_event.signal(); - } else { @@ -176,11 +187,26 @@ class ChannelGetRequesterImpl : public ChannelGetRequester } } + m_event.signal(); + } + + PVStructure::shared_pointer getPVStructure() + { + Lock lock(m_pointerMutex); + return m_pvStructure; } bool waitUntilGet(double timeOut) { - return m_event.wait(timeOut); + 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; } }; @@ -453,6 +479,8 @@ int main (int argc, char *argv[]) shared_ptr getRequesterImpl(new ChannelGetRequesterImpl(channel->getChannelName())); ChannelGet::shared_pointer channelGet = channel->createChannelGet(getRequesterImpl, pvRequest); allOK &= getRequesterImpl->waitUntilGet(timeOut); + if (allOK) + printValue(channel->getChannelName(), getRequesterImpl->getPVStructure()); } else { diff --git a/testApp/remote/pvput.cpp b/testApp/remote/pvput.cpp index 2f1e038..85d6446 100644 --- a/testApp/remote/pvput.cpp +++ b/testApp/remote/pvput.cpp @@ -575,6 +575,7 @@ class ChannelPutRequesterImpl : public ChannelPutRequester auto_ptr m_event; String m_channelName; AtomicBoolean m_supressGetValue; + AtomicBoolean m_done; public: @@ -623,6 +624,7 @@ class ChannelPutRequesterImpl : public ChannelPutRequester else { std::cerr << "[" << m_channelName << "] failed to create channel put: " << status.toString() << std::endl; + m_event->signal(); } } @@ -636,12 +638,15 @@ class ChannelPutRequesterImpl : public ChannelPutRequester std::cerr << "[" << m_channelName << "] channel get: " << status.toString() << std::endl; } + m_done.set(); + // access smart pointers // do not print old value in terseMode if (!m_supressGetValue.get()) { Lock lock(m_pointerMutex); { + // needed since we access the data ScopedLock dataLock(m_channelPut); @@ -680,14 +685,13 @@ class ChannelPutRequesterImpl : public ChannelPutRequester std::cout << std::endl << *(m_pvStructure.get()) << std::endl << std::endl; } } - - m_event->signal(); } else { std::cerr << "[" << m_channelName << "] failed to get: " << status.toString() << std::endl; } + m_event->signal(); } virtual void putDone(const epics::pvData::Status& status) @@ -700,13 +704,14 @@ class ChannelPutRequesterImpl : public ChannelPutRequester std::cerr << "[" << m_channelName << "] channel put: " << status.toString() << std::endl; } - m_event->signal(); + m_done.set(); } else { std::cerr << "[" << m_channelName << "] failed to get: " << status.toString() << std::endl; } + m_event->signal(); } PVStructure::shared_pointer getStructure() @@ -719,6 +724,7 @@ class ChannelPutRequesterImpl : public ChannelPutRequester { Lock lock(m_eventMutex); m_event.reset(new Event()); + m_done.clear(); } bool waitUntilDone(double timeOut) @@ -728,7 +734,15 @@ class ChannelPutRequesterImpl : public ChannelPutRequester Lock lock(m_eventMutex); event = m_event.get(); } - return event->wait(timeOut); + + bool signaled = event->wait(timeOut); + if (!signaled) + { + std::cerr << "[" << m_channelName << "] timeout" << std::endl; + return false; + } + + return m_done.get(); } void supressGetValue(bool flag)