void _Block_release()

in src/BlocksRuntime/runtime.c [510:531]


void _Block_release(const void *arg) {
    struct Block_layout *aBlock = (struct Block_layout *)arg;
    if (!aBlock 
        || (aBlock->flags & BLOCK_IS_GLOBAL)
        || ((aBlock->flags & (BLOCK_IS_GC|BLOCK_NEEDS_FREE)) == 0)
        ) return;
    if (aBlock->flags & BLOCK_IS_GC) {
        if (latching_decr_int_now_zero(&aBlock->flags)) {
            // Tell GC we no longer have our own refcounts.  GC will decr its refcount
            // and unless someone has done a CFRetain or marked it uncollectable it will
            // now be subject to GC reclamation.
            _Block_setHasRefcount(aBlock, false);
        }
    }
    else if (aBlock->flags & BLOCK_NEEDS_FREE) {
        if (latching_decr_int_should_deallocate(&aBlock->flags)) {
            _Block_call_dispose_helper(aBlock);
            _Block_destructInstance(aBlock);
            _Block_deallocator(aBlock);
        }
    }
}