Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Fixed race condition in reachability callback delivery #3117

Merged

Conversation

MichaelHackett
Copy link
Contributor

This is an alternative implementation of a previous attempt to fix a race condition in reachability notifications, particularly with domain-name-based associations. However, we encountered cases where the status-change callback could still receive notifications out of order, due to one path executing the callback immediately on the runloop thread and the other queuing the callback onto the GCD main queue (which is serviced by the same run loop, but the order in which queue blocks and other run loop callbacks are executed is not easy to determine).

I broke this into two commits: The first is the fix for the issue, by sending all callback notifications through the GCD main queue, just as the NSNotifications were being sent. This is the code we've been using for a few weeks and it has resolved all our issues. The second removes the special case for domain-based reachability associations, as I don't think there's any need for it with this implementation. However, I have not tested this; I just noticed that there was an attempt to remove it a few months ago, but it was quickly restored due to reintroducing the race condition. If I've really solved the root cause, then it should be safe to remove this now. But I can't think of a way to unit-test this, so it needs to be tried in a few different apps to see if it's safe. If not, I can reverse that commit and resubmit with the first alone.

Because the run-loop reachability callback executed its callback
directly, whereas the initial check (fired off from
`-[AFNetworkReachabilityManager startMonitoring]`) executed the callback
from a GCD queue, it was possible for the callbacks to be executed out
of order from when the status was obtained, leaving the listener in the
incorrect state.

By sending both routes through the same GCD-queuing function, both the
callbacks and NSNotifications will be processed in the order in which
they are sent. It also removes some repetition in the code.
It appears that a check was put in place to work around a race condition
when reachability was associated with a domain name. However, the cause
of the race condition is addressed in the previous commit, so the
special-casing is no longer needed.
@kcharwood kcharwood added this to the 2.6.2 milestone Nov 6, 2015
@kcharwood
Copy link
Contributor

This looks great! Thanks for putting this together. I should be able to get this merged in today, and I plan on shipping it in the 2.6.2 release.

@kcharwood kcharwood changed the title Serialize reachability callbacks Fixed race condition in reachability call back delivery Nov 6, 2015
@kcharwood kcharwood changed the title Fixed race condition in reachability call back delivery Fixed race condition in reachability callback delivery Nov 6, 2015
@MichaelHackett
Copy link
Contributor Author

I appreciate the comment! I'm glad it's of use.

@kcharwood kcharwood added the fixed label Nov 6, 2015
kcharwood added a commit that referenced this pull request Nov 6, 2015
…allbacks

Fixed race condition in reachability callback delivery
@kcharwood kcharwood merged commit 4e59284 into AFNetworking:master Nov 6, 2015
kcharwood added a commit that referenced this pull request Nov 6, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants