int main(void) { test_start("Dispatch Debug"); dispatch_queue_t main_q = dispatch_get_main_queue(); dispatch_debug(main_q, "dispatch_queue_t"); dispatch_queue_t default_q = dispatch_get_concurrent_queue(0); dispatch_debug(default_q, "dispatch_queue_t"); dispatch_source_attr_t attr = dispatch_source_attr_create(); dispatch_debug(attr, "dispatch_source_attr_t"); dispatch_source_t s = dispatch_source_timer_create(DISPATCH_TIMER_INTERVAL, 1000000000ull, 0, attr, main_q, ^(dispatch_event_t ev __attribute__((unused))) {}); dispatch_debug(s, "dispatch_source_t"); dispatch_group_t g = dispatch_group_create(); dispatch_debug(g, "dispatch_group_t"); return 0; }
void dispatch_source_cancel(dispatch_source_t ds) { #if DISPATCH_DEBUG dispatch_debug(as_do(ds), __FUNCTION__); #endif // Right after we set the cancel flag, someone else // could potentially invoke the source, do the cancelation, // unregister the source, and deallocate it. We would // need to therefore retain/release before setting the bit _dispatch_retain(as_do(ds)); dispatch_atomic_or(&ds->ds_atomic_flags, DSF_CANCELED); _dispatch_wakeup(as_do(ds)); _dispatch_release(as_do(ds)); }
dispatch_source_t dispatch_source_create(dispatch_source_type_t type, uintptr_t handle, uintptr_t mask, dispatch_queue_t q) { dispatch_source_t ds = NULL; static char source_label[sizeof(ds->dq_label)] = "source"; // input validation if (type == NULL || (mask & ~type->mask)) { goto out_bad; } ds = calloc(1ul, sizeof(struct dispatch_source_s)); if (slowpath(!ds)) { goto out_bad; } // Initialize as a queue first, then override some settings below. _dispatch_queue_init((dispatch_queue_t)ds); memcpy(ds->dq_label, source_label, sizeof(source_label)); // Dispatch Object ds->do_vtable = &_dispatch_source_kevent_vtable; ds->do_ref_cnt++; // the reference the manger queue holds ds->do_suspend_cnt = DISPATCH_OBJECT_SUSPEND_INTERVAL; // do_targetq will be retained below, past point of no-return ds->do_targetq = q; if (slowpath(!type->init(ds, type, handle, mask, q))) { goto out_bad; } dispatch_assert(!(ds->ds_is_level && ds->ds_is_adder)); #if DISPATCH_DEBUG dispatch_debug(as_do(ds), __FUNCTION__); #endif _dispatch_retain(as_do(ds->do_targetq)); return ds; out_bad: free(ds); return NULL; }