duplicate search responses from the same server bound to multiple NIFs filtered out
This commit is contained in:
@@ -41,11 +41,12 @@ class SearchInstance {
|
||||
|
||||
/**
|
||||
* Search response from server (channel found).
|
||||
* @param guid server GUID.
|
||||
* @param minorRevision server minor PVA revision.
|
||||
* @param serverAddress server address.
|
||||
*/
|
||||
// TODO make serverAddress an URI or similar
|
||||
virtual void searchResponse(int8_t minorRevision, osiSockAddr* serverAddress) = 0;
|
||||
virtual void searchResponse(const GUID & guid, int8_t minorRevision, osiSockAddr* serverAddress) = 0;
|
||||
};
|
||||
|
||||
class ChannelSearchManager {
|
||||
@@ -78,12 +79,13 @@ class ChannelSearchManager {
|
||||
|
||||
/**
|
||||
* Search response from server (channel found).
|
||||
* @param guid server GUID.
|
||||
* @param cid client channel ID.
|
||||
* @param seqNo search sequence number.
|
||||
* @param minorRevision server minor PVA revision.
|
||||
* @param serverAddress server address.
|
||||
*/
|
||||
virtual void searchResponse(pvAccessID cid, int32_t seqNo, int8_t minorRevision, osiSockAddr* serverAddress) = 0;
|
||||
virtual void searchResponse(const GUID & guid, pvAccessID cid, int32_t seqNo, int8_t minorRevision, osiSockAddr* serverAddress) = 0;
|
||||
|
||||
/**
|
||||
* New server detected.
|
||||
|
||||
@@ -137,7 +137,7 @@ void SimpleChannelSearchManagerImpl::unregisterSearchInstance(SearchInstance::sh
|
||||
m_channels.erase(id);
|
||||
}
|
||||
|
||||
void SimpleChannelSearchManagerImpl::searchResponse(pvAccessID cid, int32_t /*seqNo*/, int8_t minorRevision, osiSockAddr* serverAddress)
|
||||
void SimpleChannelSearchManagerImpl::searchResponse(const GUID & guid, pvAccessID cid, int32_t /*seqNo*/, int8_t minorRevision, osiSockAddr* serverAddress)
|
||||
{
|
||||
Lock guard(m_channelMutex);
|
||||
std::map<pvAccessID,SearchInstance::shared_pointer>::iterator channelsIter = m_channels.find(cid);
|
||||
@@ -145,10 +145,10 @@ void SimpleChannelSearchManagerImpl::searchResponse(pvAccessID cid, int32_t /*se
|
||||
{
|
||||
guard.unlock();
|
||||
|
||||
// minor hack to enable duplicate reports
|
||||
// enable duplicate reports
|
||||
SearchInstance::shared_pointer si = std::tr1::dynamic_pointer_cast<SearchInstance>(m_context.lock()->getChannel(cid));
|
||||
if (si)
|
||||
si->searchResponse(minorRevision, serverAddress);
|
||||
si->searchResponse(guid, minorRevision, serverAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -160,7 +160,7 @@ void SimpleChannelSearchManagerImpl::searchResponse(pvAccessID cid, int32_t /*se
|
||||
guard.unlock();
|
||||
|
||||
// then notify SearchInstance
|
||||
si->searchResponse(minorRevision, serverAddress);
|
||||
si->searchResponse(guid, minorRevision, serverAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,12 +89,13 @@ class SimpleChannelSearchManagerImpl :
|
||||
void unregisterSearchInstance(SearchInstance::shared_pointer const & channel);
|
||||
/**
|
||||
* Search response from server (channel found).
|
||||
* @param guid server GUID.
|
||||
* @param cid client channel ID.
|
||||
* @param seqNo search sequence number.
|
||||
* @param minorRevision server minor PVA revision.
|
||||
* @param serverAddress server address.
|
||||
*/
|
||||
void searchResponse(pvAccessID cid, int32_t seqNo, int8_t minorRevision, osiSockAddr* serverAddress);
|
||||
void searchResponse(const GUID & guid, pvAccessID cid, int32_t seqNo, int8_t minorRevision, osiSockAddr* serverAddress);
|
||||
/**
|
||||
* New server detected.
|
||||
* Boost searching of all channels.
|
||||
|
||||
@@ -2862,7 +2862,7 @@ namespace epics {
|
||||
{
|
||||
transport->ensureData(4);
|
||||
pvAccessID cid = payloadBuffer->getInt();
|
||||
csm->searchResponse(cid, searchSequenceId, version, &serverAddress);
|
||||
csm->searchResponse(guid, cid, searchSequenceId, version, &serverAddress);
|
||||
}
|
||||
|
||||
|
||||
@@ -3497,6 +3497,11 @@ namespace epics {
|
||||
/// Used by SearchInstance.
|
||||
int32_t m_userValue;
|
||||
|
||||
/**
|
||||
* @brief Server GUID.
|
||||
*/
|
||||
GUID m_guid;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param context
|
||||
@@ -3931,21 +3936,23 @@ namespace epics {
|
||||
m_addressIndex = m_addresses->size()*STATIC_SEARCH_MAX_MULTIPLIER;
|
||||
|
||||
// NOTE: calls channelConnectFailed() on failure
|
||||
searchResponse(PVA_PROTOCOL_REVISION, &((*m_addresses)[ix]));
|
||||
static GUID guid = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
|
||||
searchResponse(guid, PVA_PROTOCOL_REVISION, &((*m_addresses)[ix]));
|
||||
}
|
||||
|
||||
virtual void timerStopped() {
|
||||
// noop
|
||||
}
|
||||
|
||||
virtual void searchResponse(int8 minorRevision, osiSockAddr* serverAddress) {
|
||||
virtual void searchResponse(const GUID & guid, int8 minorRevision, osiSockAddr* serverAddress) {
|
||||
Lock guard(m_channelMutex);
|
||||
Transport::shared_pointer transport = m_transport;
|
||||
if (transport.get())
|
||||
{
|
||||
// TODO use GUID to determine whether there are multiple servers with the same channel
|
||||
// multiple defined PV or reconnect request (same server address)
|
||||
if (!sockAddrAreIdentical(transport->getRemoteAddress(), serverAddress))
|
||||
// GUID check case: same server listening on different NIF
|
||||
|
||||
if (!sockAddrAreIdentical(transport->getRemoteAddress(), serverAddress) &&
|
||||
!std::equal(guid.value, guid.value + 12, m_guid.value))
|
||||
{
|
||||
EXCEPTION_GUARD(m_requester->message("More than one channel with name '" + m_name +
|
||||
"' detected, connected to: " + inetAddressToString(*transport->getRemoteAddress()) + ", ignored: " + inetAddressToString(*serverAddress), warningMessage));
|
||||
@@ -3960,6 +3967,10 @@ namespace epics {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// remember GUID
|
||||
std::copy(guid.value, guid.value + 12, m_guid.value);
|
||||
|
||||
// create channel
|
||||
createChannel(transport);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user