sal: catch listener removal corner case

This change makes sure an active but not-yet fired listener does not fire
anymore if it gets removed.  In this case, the listener already has an
invalid index, but still needs to be copied to the delete list.

This issue has not been observed in the wild, and is unlikely to have
caused real problems in the past.

Change-Id: I8be8a5b1d4cdc783a092b93f34f33b969894e5da
This commit is contained in:
Horst Schirmeier
2015-01-13 19:19:30 +01:00
parent c4d44aeb0c
commit d68ea990ca

View File

@ -50,16 +50,22 @@ void ListenerManager::remove(BaseListener* li)
// called onDeletion for these listeners):
m_DeleteList.insert(m_DeleteList.end(), m_FireList.begin(), m_FireList.end());
// - li != 0 -> remove single listener (if added previously)
// * Inform the listeners (call onDeletion)
// * Remove the index in the perf. buffer-list (if existing)
// * Find/remove 'li' in 'm_BufferList'
// - li != 0 -> remove single listener
// * If added / not removed before,
// -> inform the listeners (call onDeletion)
// -> Remove the index in the perf. buffer-list (if existing)
// -> Find/remove 'li' in 'm_BufferList'
// * If 'li' in 'm_FireList', copy to 'm_DeleteList'
} else if (li->getLocation() != INVALID_INDEX) { // Check if li hasn't been added previously (Q&D)
li->onDeletion();
if (li->getPerformanceBuffer() != NULL)
li->getPerformanceBuffer()->remove(li->getLocation());
m_remove(li->getLocation());
} else {
// has li been removed previously?
if (li->getLocation() != INVALID_INDEX) {
li->onDeletion();
if (li->getPerformanceBuffer() != NULL) {
li->getPerformanceBuffer()->remove(li->getLocation());
}
m_remove(li->getLocation());
}
// if li hasn't fired yet, make sure it doesn't
firelist_t::const_iterator it =
std::find(m_FireList.begin(), m_FireList.end(), li);
if (it != m_FireList.end()) {