client: (shallow) copy into Monitor::root
Avoid exposing refs. from monitor queue which might then be used after release(). Also allows users the possibility of caching getSubField() until root.get() actually changes.
This commit is contained in:
@ -196,16 +196,29 @@ bool Monitor::poll()
|
||||
Guard G(impl->mutex);
|
||||
|
||||
if(!impl->done && impl->last.next()) {
|
||||
root = impl->last->pvStructurePtr;
|
||||
const epics::pvData::PVStructurePtr& ptr = impl->last->pvStructurePtr;
|
||||
changed = *impl->last->changedBitSet;
|
||||
overrun = *impl->last->overrunBitSet;
|
||||
|
||||
/* copy the exposed PVStructure for two reasons.
|
||||
* 1. Prevent accidental use of shared container after release()
|
||||
* 2. Allows caller to cache results of getSubField() until root.get() changes.
|
||||
*/
|
||||
if(!root || (void*)root->getField().get()!=(void*)ptr->getField().get()) {
|
||||
// initial connection, or new type
|
||||
root = pvd::getPVDataCreate()->createPVStructure(ptr); // also calls copyUnchecked()
|
||||
} else {
|
||||
// same type
|
||||
const_cast<pvd::PVStructure&>(*root).copyUnchecked(*ptr, changed);
|
||||
}
|
||||
|
||||
impl->seenEmpty = false;
|
||||
} else {
|
||||
root.reset();
|
||||
changed.clear();
|
||||
overrun.clear();
|
||||
impl->seenEmpty = true;
|
||||
}
|
||||
return impl->seenEmpty = !!root;
|
||||
return !impl->seenEmpty;
|
||||
}
|
||||
|
||||
bool Monitor::complete() const
|
||||
|
@ -104,13 +104,31 @@ struct epicsShareClass Monitor
|
||||
void cancel();
|
||||
/** updates root, changed, overrun
|
||||
*
|
||||
* @return true if root!=NULL
|
||||
* @return true if a new update was extracted from the queue.
|
||||
* @note This method does not block.
|
||||
* @note MonitorEvent::Data will not be repeated until poll()==false.
|
||||
* @post root!=NULL (after version 6.0.0)
|
||||
* @post root!=NULL iff poll()==true (In version 6.0.0)
|
||||
*/
|
||||
bool poll();
|
||||
//! true if all events received.
|
||||
//! Check after poll()==false
|
||||
bool complete() const;
|
||||
/** Monitor update data.
|
||||
*
|
||||
* After version 6.0.0
|
||||
*
|
||||
* Initially NULL, becomes !NULL the first time poll()==true.
|
||||
* The PVStructure pointed to be root will presist until
|
||||
* Monitor reconnect w/ type change. This can be detected
|
||||
* by comparing `root.get()`. references to root may be cached
|
||||
* subject to this test.
|
||||
*
|
||||
* In version 6.0.0
|
||||
*
|
||||
* NULL except after poll()==true. poll()==false sets root=NULL.
|
||||
* references to root should not be stored between calls to poll().
|
||||
*/
|
||||
epics::pvData::PVStructure::const_shared_pointer root;
|
||||
epics::pvData::BitSet changed,
|
||||
overrun;
|
||||
|
Reference in New Issue
Block a user