Spun from bug #219232. Any task queued via RunLoop::dispatchAfter() is leaked if the RunLoop thread terminates before the underlying DispatchTimer is fired because the DispatchTimer is only freed when it's fired, which doesn't happen after the RunLoop thread terminates. Right now, the RunLoop reference taken via TimerBase (from which DispatchTimer derives) also blocks the RunLoop object to be destroyed once the thread is terminated. Bug #219232 doesn't help here because DispatchTimer instances are not stored in any containers that could be cleared at the point of termination.
Created attachment 415538 [details] Unit test
<rdar://problem/72288000>