DISPATCH_NOINLINE void _dispatch_source_xref_release(dispatch_source_t ds) { #ifndef DISPATCH_NO_LEGACY if (ds->ds_is_legacy) { if (!(ds->ds_timer.flags & DISPATCH_TIMER_TYPE_MASK == DISPATCH_TIMER_ONESHOT)) { dispatch_source_cancel(ds); } // Clients often leave sources suspended at the last release dispatch_atomic_and(&ds->do_suspend_cnt, DISPATCH_OBJECT_SUSPEND_LOCK); } else #endif if (slowpath(DISPATCH_OBJECT_SUSPENDED(ds))) { // Arguments for and against this assert are within 6705399 DISPATCH_CLIENT_CRASH("Release of a suspended object"); } _dispatch_wakeup(as_do(ds)); _dispatch_release(as_do(ds)); }
// Return true if this bit was the last in the bitmap, and it is now all zeroes DISPATCH_ALWAYS_INLINE_NDEBUG static bool bitmap_clear_bit(volatile bitmap_t *bitmap, unsigned int index, bool exclusively) { #if DISPATCH_DEBUG dispatch_assert(index < CONTINUATIONS_PER_BITMAP); #endif const bitmap_t mask = BITMAP_C(1) << index; bitmap_t b; if (exclusively == CLEAR_EXCLUSIVELY) { if (slowpath((*bitmap & mask) == 0)) { DISPATCH_CRASH("Corruption: failed to clear bit exclusively"); } } // and-and-fetch b = dispatch_atomic_and(bitmap, ~mask, release); return b == 0; }