server: keep most recent GetFieldRequester alive

This commit is contained in:
Michael Davidsaver
2017-11-06 16:27:43 -06:00
parent 0ec4e16373
commit c469d49ecb
3 changed files with 38 additions and 8 deletions

View File

@@ -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<pvAccessID, Destroyable::shared_pointer> _requests_t;
_requests_t _requests;

View File

@@ -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<ServerGetFieldRequesterImpl> tp(new ServerGetFieldRequesterImpl(_context, channel, ioid, transport));
GetFieldRequester::shared_pointer gfr = tp;
GetFieldRequester::shared_pointer req;
{
std::tr1::shared_ptr<ServerGetFieldRequesterImpl> 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()

View File

@@ -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<epicsMutex> 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<epicsMutex> G(_mutex);
prev.swap(_active_requester);
}
}
}
}