fix IntrospectionRegistry error handling

Calling code can't deal with "cache" miss,
which indicates either a protocol error (use of invalid ID),
or a logic error on our part (didn't save ID).
In either case, better to throw an exception than to crash.
This commit is contained in:
Michael Davidsaver
2018-06-20 18:28:50 -07:00
parent e08de8c2df
commit 3abd77a42c
2 changed files with 14 additions and 35 deletions

View File

@@ -36,21 +36,6 @@ void IntrospectionRegistry::reset()
_registry.clear();
}
FieldConstPtr IntrospectionRegistry::getIntrospectionInterface(const int16 id)
{
registryMap_t::iterator registryIter = _registry.find(id);
if(registryIter == _registry.end())
{
return FieldConstPtr();
}
return registryIter->second;
}
void IntrospectionRegistry::registerIntrospectionInterface(const int16 id, FieldConstPtr const & field)
{
_registry[id] = field;
}
int16 IntrospectionRegistry::registerIntrospectionInterface(FieldConstPtr const & field, bool& existing)
{
int16 key;
@@ -127,8 +112,17 @@ FieldConstPtr IntrospectionRegistry::deserialize(ByteBuffer* buffer, Deserializa
}
else if (typeCode == ONLY_ID_TYPE_CODE)
{
control->ensureData(sizeof(int16)/sizeof(int8));
return getIntrospectionInterface(buffer->getShort());
control->ensureData(sizeof(int16));
int16 id = buffer->getShort();
registryMap_t::iterator registryIter = _registry.find(id);
if(registryIter == _registry.end())
{
// peer gave us an id which we don't remember.
// This isn't recoverable.
throw std::runtime_error("IntrospectionRegistry miss.");
}
return registryIter->second;
}
// could also be a mask
if(typeCode == IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE)
@@ -136,7 +130,7 @@ FieldConstPtr IntrospectionRegistry::deserialize(ByteBuffer* buffer, Deserializa
control->ensureData(sizeof(int16)/sizeof(int8));
const short key = buffer->getShort();
FieldConstPtr field = _fieldCreate->deserialize(buffer, control);
registerIntrospectionInterface(key, field);
_registry[key] = field;
return field;
}

View File

@@ -51,23 +51,8 @@ public:
* Resets registry, i.e. must be done when transport is changed (server restarted).
*/
void reset();
/**
* Get introspection interface for given ID.
*
* @param id id of the introspection interface to get
*
* @return <code>Field</code> instance for given ID.
*/
epics::pvData::FieldConstPtr getIntrospectionInterface(const epics::pvData::int16 id);
/**
* Registers introspection interface with given ID. Always INCOMING.
*
* @param id id of the introspection interface to register
* @param field introspection interface to register
*/
void registerIntrospectionInterface(const epics::pvData::int16 id, epics::pvData::FieldConstPtr const & field);
private:
/**
* Registers introspection interface and get it's ID. Always OUTGOING.
* If it is already registered only preassigned ID is returned.
@@ -79,7 +64,7 @@ public:
* @return id of given introspection interface
*/
epics::pvData::int16 registerIntrospectionInterface(epics::pvData::FieldConstPtr const & field, bool& existing);
public:
/**
* Serializes introspection interface
*