diff --git a/src/ca/caChannel.cpp b/src/ca/caChannel.cpp index 8a89de4..c1f2dbe 100644 --- a/src/ca/caChannel.cpp +++ b/src/ca/caChannel.cpp @@ -62,20 +62,24 @@ void CAChannel::connected() if(DEBUG_LEVEL>0) { cout<< "CAChannel::connected " << channelName << endl; } - bool callChannelConnected = false; + bool callChannelCreated = false; { Lock lock(requestsMutex); if(!channelCreated) { channelCreated = true; - callChannelConnected = true; + callChannelCreated = true; } } - if(callChannelConnected) { + if(callChannelCreated) { CAChannelProviderPtr provider(channelProvider.lock()); if(provider) provider->addChannel(shared_from_this()); ChannelRequester::shared_pointer req(channelRequester.lock()); if(req) EXCEPTION_GUARD(req->channelCreated(Status::Ok, shared_from_this())); } + while(!getFieldQueue.empty()) { + getFieldQueue.front()->activate(); + getFieldQueue.pop(); + } while(!putQueue.empty()) { putQueue.front()->activate(); putQueue.pop(); @@ -239,7 +243,8 @@ void CAChannel::getField(GetFieldRequester::shared_pointer const & requester, if(DEBUG_LEVEL>0) { cout << "CAChannel::getField " << channelName << endl; } - CAChannelGetFieldPtr getField(new CAChannelGetField(requester,subField)); + CAChannelGetFieldPtr getField( + new CAChannelGetField(shared_from_this(),requester,subField)); { Lock lock(requestsMutex); if(getConnectionState()!=Channel::CONNECTED) { @@ -353,8 +358,10 @@ void CAChannel::printInfo(std::ostream& out) CAChannelGetField::CAChannelGetField( + CAChannelPtr const &channel, GetFieldRequester::shared_pointer const & requester,std::string const & subField) - : getFieldRequester(requester), + : channel(channel), + getFieldRequester(requester), subField(subField) { if(DEBUG_LEVEL>0) { @@ -362,6 +369,12 @@ CAChannelGetField::CAChannelGetField( } } +void CAChannelGetField::activate() +{ + CAChannelPtr chan(channel.lock()); + if(chan) callRequester(chan); +} + CAChannelGetField::~CAChannelGetField() { if(DEBUG_LEVEL>0) { diff --git a/src/ca/caChannel.h b/src/ca/caChannel.h index 8228627..d5835cd 100644 --- a/src/ca/caChannel.h +++ b/src/ca/caChannel.h @@ -63,10 +63,15 @@ class CAChannelGetField : { public: POINTER_DEFINITIONS(CAChannelGetField); - CAChannelGetField(GetFieldRequester::shared_pointer const & requester,std::string const & subField); + CAChannelGetField( + CAChannelPtr const &channel, + GetFieldRequester::shared_pointer const & requester, + std::string const & subField); ~CAChannelGetField(); void callRequester(CAChannelPtr const & caChannel); + void activate(); private: + CAChannelWPtr channel; GetFieldRequester::weak_pointer getFieldRequester; std::string subField; }; diff --git a/src/client/clientRPC.cpp b/src/client/clientRPC.cpp index 04cfab2..ff52a3e 100644 --- a/src/client/clientRPC.cpp +++ b/src/client/clientRPC.cpp @@ -141,6 +141,9 @@ struct RPCer : public pva::ChannelRPCRequester, event.message.clear(); } event.value = pvResponse; + pvd::BitSetPtr valid(new pvd::BitSet(1)); + valid->set(0); + event.valid = valid; callEvent(G, status.isSuccess()? pvac::GetEvent::Success : pvac::GetEvent::Fail); } diff --git a/src/client/pvAccess.cpp b/src/client/pvAccess.cpp index 9089683..7975f74 100644 --- a/src/client/pvAccess.cpp +++ b/src/client/pvAccess.cpp @@ -216,6 +216,14 @@ struct Get2PutProxy : public ChannelGet return req ? req->getRequesterName() : ""; } + virtual void message(const std::string &message, MessageType messageType) OVERRIDE FINAL { + ChannelGetRequester::shared_pointer req(requester.lock()); + if(req) + req->message(message, messageType); + else + ChannelPutRequester::message(message, messageType); + } + virtual void channelDisconnect(bool destroy) OVERRIDE FINAL { ChannelGetRequester::shared_pointer req(requester.lock()); if(req) diff --git a/src/server/pva/server.h b/src/server/pva/server.h index 89c54cc..3bd2196 100644 --- a/src/server/pva/server.h +++ b/src/server/pva/server.h @@ -121,6 +121,7 @@ public: private: typedef std::map > builders_t; public: + typedef builders_t::const_iterator const_iterator; //! Build a new, empty, provider. //! @param name Provider Name. Only relevant if registerAsServer() is called, then must be unique in this process. @@ -144,8 +145,8 @@ public: std::tr1::shared_ptr provider() const; // iterate through currently add()'d PVs. Iteraters are invalidated by concurrent add() or remove() - builders_t::const_iterator begin() const; - builders_t::const_iterator end() const; + const_iterator begin() const; + const_iterator end() const; }; /** @brief A Provider which has no pre-configured list of names. diff --git a/src/server/sharedstate_pv.cpp b/src/server/sharedstate_pv.cpp index dc6ab66..082168a 100644 --- a/src/server/sharedstate_pv.cpp +++ b/src/server/sharedstate_pv.cpp @@ -26,9 +26,9 @@ namespace { struct MailboxHandler : public pvas::SharedPV::Handler { virtual ~MailboxHandler() {} - virtual void onPut(pvas::SharedPV& self, pvas::Operation& op) + virtual void onPut(const pvas::SharedPV::shared_pointer& self, pvas::Operation& op) OVERRIDE FINAL { - self.post(op.value(), op.changed()); + self->post(op.value(), op.changed()); op.info("Set!"); op.complete(); } diff --git a/testCa/testCaProvider.cpp b/testCa/testCaProvider.cpp index ff275d3..b92c462 100644 --- a/testCa/testCaProvider.cpp +++ b/testCa/testCaProvider.cpp @@ -573,6 +573,7 @@ private: TestClient(string const &channelName,PVStructurePtr const & pvRequest); string channelName; PVStructurePtr pvRequest; + string putValue; TestChannelPtr testChannel; TestChannelGetPtr testChannelGet; TestChannelPutPtr testChannelPut; @@ -611,8 +612,14 @@ void TestClient::getDone( testOk(pvStructure->getSubField("timeStamp").get() != 0,"timeStamp not null"); testOk(pvStructure->getSubField("alarm").get() != 0,"alarm not null"); if (DEBUG) std::cout << testChannel->getChannelName() + " TestClient::getDone" + << " putValue " << putValue << " bitSet " << *bitSet << " pvStructure\n" << pvStructure << "\n"; + PVScalarPtr pvScalar = pvStructure->getSubField("value"); + if(pvScalar) { + string getValue = getConvert()->toString(pvScalar); + testOk(getValue.compare(putValue)==0,"getValue==putValue"); + } waitForGet.signal(); } @@ -649,6 +656,7 @@ void TestClient::put(string const & value) { testDiag("TestClient::put %s := %s", testChannel->getChannelName().c_str(), value.c_str()); + putValue = value; testChannelPut->put(value); waitPut(OPERATION_TIMEOUT); } @@ -756,7 +764,7 @@ void checkClient(const string &channelName, const string &putValue) MAIN(testCaProvider) { - testPlan(84 + EXIT_TESTS); + testPlan(143 + EXIT_TESTS); TestIocPtr testIoc(new TestIoc()); testIoc->start(); @@ -766,10 +774,16 @@ MAIN(testCaProvider) ChannelProviderRegistry::shared_pointer reg(ChannelProviderRegistry::clients()); try { ChannelProvider::shared_pointer channelProvider(reg->getProvider("ca")); - if (!channelProvider) - testAbort("Channel provider 'ca' not registered"); - - checkClient("DBRlongout", "5"); + if (!channelProvider) testAbort("Channel provider 'ca' not registered"); + checkClient("DBRlongout", "0"); + checkClient("DBRlongout", "1"); + checkClient("DBRlongout", "-1"); + checkClient("DBRlongout", "32767"); + checkClient("DBRlongout", "32768"); + checkClient("DBRlongout", "-32768"); + checkClient("DBRlongout", "-32769"); + checkClient("DBRlongout", "2147483647"); + checkClient("DBRlongout", "-2147483648"); checkClient("DBRdoubleout", "1.5"); checkClient("DBRstringout", "test"); checkClient("DBRbyteArray", "1 2 3");