diff --git a/src/server/pv/responseHandlers.h b/src/server/pv/responseHandlers.h index cae4681..78f96a2 100644 --- a/src/server/pv/responseHandlers.h +++ b/src/server/pv/responseHandlers.h @@ -687,6 +687,7 @@ public: void destroy(); void send(epics::pvData::ByteBuffer* buffer, TransportSendControl* control); private: + bool done; epics::pvData::Status _status; epics::pvData::FieldConstPtr _field; }; diff --git a/src/server/pv/serverChannelImpl.h b/src/server/pv/serverChannelImpl.h index 9ca4ee5..be04967 100644 --- a/src/server/pv/serverChannelImpl.h +++ b/src/server/pv/serverChannelImpl.h @@ -48,7 +48,7 @@ public: void unregisterRequest(pvAccessID id); void installGetField(const GetFieldRequester::shared_pointer& gf); - void completeGetField(); + void completeGetField(GetFieldRequester *req); //! may return NULL Destroyable::shared_pointer getRequest(pvAccessID id); diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index 37bf21f..e47fe4f 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -2783,20 +2783,25 @@ void ServerGetFieldHandler::getFieldFailureResponse(Transport::shared_pointer co ServerGetFieldRequesterImpl::ServerGetFieldRequesterImpl( ServerContextImpl::shared_pointer const & context, ServerChannel::shared_pointer const & channel, const pvAccessID ioid, Transport::shared_pointer const & transport) : - BaseChannelRequester(context, channel, ioid, transport), _field() + BaseChannelRequester(context, channel, ioid, transport), done(false) { } void ServerGetFieldRequesterImpl::getDone(const Status& status, FieldConstPtr const & field) { + bool twice; { Lock guard(_mutex); _status = status; _field = field; + twice = done; + done = true; } - TransportSender::shared_pointer thisSender = shared_from_this(); - _transport->enqueueSendRequest(thisSender); - _channel->completeGetField(); + if(!twice) { + TransportSender::shared_pointer thisSender = shared_from_this(); + _transport->enqueueSendRequest(thisSender); + } + _channel->completeGetField(this); } void ServerGetFieldRequesterImpl::destroy() diff --git a/src/server/serverChannelImpl.cpp b/src/server/serverChannelImpl.cpp index 2cca566..d4a03c3 100644 --- a/src/server/serverChannelImpl.cpp +++ b/src/server/serverChannelImpl.cpp @@ -121,12 +121,13 @@ void ServerChannel::installGetField(const GetFieldRequester::shared_pointer& gf) } } -void ServerChannel::completeGetField() +void ServerChannel::completeGetField(GetFieldRequester *req) { GetFieldRequester::shared_pointer prev; { epicsGuard G(_mutex); - prev.swap(_active_requester); + if(_active_requester.get()==req) + prev.swap(_active_requester); } }