From c469d49ecb2ea198312d4c3bd326539a4d965f97 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 6 Nov 2017 16:27:43 -0600 Subject: [PATCH] server: keep most recent GetFieldRequester alive --- src/server/pv/serverChannelImpl.h | 9 ++++++--- src/server/responseHandlers.cpp | 15 ++++++++++----- src/server/serverChannelImpl.cpp | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/server/pv/serverChannelImpl.h b/src/server/pv/serverChannelImpl.h index d7b5c5c..9ca4ee5 100644 --- a/src/server/pv/serverChannelImpl.h +++ b/src/server/pv/serverChannelImpl.h @@ -47,6 +47,9 @@ public: void unregisterRequest(pvAccessID id); + void installGetField(const GetFieldRequester::shared_pointer& gf); + void completeGetField(); + //! may return NULL Destroyable::shared_pointer getRequest(pvAccessID id); @@ -56,15 +59,15 @@ public: void printInfo(FILE *fd) const; private: - /** - * Local channel. - */ const Channel::shared_pointer _channel; const ChannelRequester::shared_pointer _requester; const pvAccessID _cid, _sid; + //! keep alive in-progress GetField() + GetFieldRequester::shared_pointer _active_requester; + typedef std::map _requests_t; _requests_t _requests; diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index 64edadf..37bf21f 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -2754,20 +2754,24 @@ void ServerGetFieldHandler::handleResponse(osiSockAddr* responseFrom, string subField = SerializeHelper::deserializeString(payloadBuffer, transport.get()); // issue request - // TODO use std::make_shared - std::tr1::shared_ptr tp(new ServerGetFieldRequesterImpl(_context, channel, ioid, transport)); - GetFieldRequester::shared_pointer gfr = tp; + GetFieldRequester::shared_pointer req; + { + std::tr1::shared_ptr tp(new ServerGetFieldRequesterImpl(_context, channel, ioid, transport)); + req = tp; + } // asCheck Status asStatus = channel->getChannelSecuritySession()->authorizeGetField(ioid, subField); if (!asStatus.isSuccess()) { - gfr->getDone(asStatus, FieldConstPtr()); + req->getDone(asStatus, FieldConstPtr()); return; } + channel->installGetField(req); + // TODO exception check - channel->getChannel()->getField(gfr, subField); + channel->getChannel()->getField(req, subField); } void ServerGetFieldHandler::getFieldFailureResponse(Transport::shared_pointer const & transport, const pvAccessID ioid, const Status& errorStatus) @@ -2792,6 +2796,7 @@ void ServerGetFieldRequesterImpl::getDone(const Status& status, FieldConstPtr co } TransportSender::shared_pointer thisSender = shared_from_this(); _transport->enqueueSendRequest(thisSender); + _channel->completeGetField(); } void ServerGetFieldRequesterImpl::destroy() diff --git a/src/server/serverChannelImpl.cpp b/src/server/serverChannelImpl.cpp index 5ef7295..2cca566 100644 --- a/src/server/serverChannelImpl.cpp +++ b/src/server/serverChannelImpl.cpp @@ -108,5 +108,27 @@ void ServerChannel::printInfo(FILE *fd) const fprintf(fd,"CHANNEL : %s\n", typeid(*_channel).name()); } +void ServerChannel::installGetField(const GetFieldRequester::shared_pointer& gf) +{ + GetFieldRequester::shared_pointer prev; + { + epicsGuard G(_mutex); + prev.swap(_active_requester); + _active_requester = gf; + } + if(prev) { + prev->getDone(Status::error("Aborted"), FieldConstPtr()); + } +} + +void ServerChannel::completeGetField() +{ + GetFieldRequester::shared_pointer prev; + { + epicsGuard G(_mutex); + prev.swap(_active_requester); + } +} + } }