[mdns-avahi] handle freed AvahiWatch/Timeout
entries as processing run loop
#2019
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Avahi provides a mechanism to integrate it to a
select()
style run loop where an implementation can provide anAvahiWatch
and anAvahiTimeout
structure along with a set of related APIs (as function pointers given to Avahi client) for it to allocate new watch/timeout entries or update or free them. A watch entry provides a set of events to watch for and expects its given callback to be invoked when the events occur. A timeout provides an abstraction for a timer.This commit updates
AvahiPoller
(which integrates Avahi to run loop as aMainloopProcessor
) to protect against situations where entries get freed or updated as Avahi callbacks are invoked fromAvahiPoller::Process()
.When we invoke the callback for an
AvahiWatch
orAvahiTimeout
the Avahi module can call any of APIs we provided to it. For example, it can update or free any existingAvahiWatch/Timeout
entry, which in turn, modifies themWatches
ormTimers
list being tracked by theAvahiPoller
.This commit updates the
AvahiPoller
class to correctly handle such situations. Before invoking the callback, we update the entry's state and after returning from callback we restart the iteration over the watch/timer list to find the next entry to report, as the list may have changed during execution of the callback.