dispatch_queue_t _dispatch_source_invoke(dispatch_source_t ds) { // This function performs all source actions. Each action is responsible // for verifying that it takes place on the appropriate queue. If the // current queue is not the correct queue for this action, the correct queue // will be returned and the invoke will be re-driven on that queue. // The order of tests here in invoke and in probe should be consistent. dispatch_queue_t dq = _dispatch_queue_get_current(); if (!ds->ds_is_installed) { // The source needs to be installed on the manager queue. if (dq != &_dispatch_mgr_q) { return &_dispatch_mgr_q; } _dispatch_kevent_merge(ds); } else if ((ds->ds_atomic_flags & DSF_CANCELED) || (ds->do_xref_cnt == 0)) { // The source has been cancelled and needs to be uninstalled from the // manager queue. After uninstallation, the cancellation handler needs // to be delivered to the target queue. if (ds->ds_dkev) { if (dq != &_dispatch_mgr_q) { return &_dispatch_mgr_q; } _dispatch_kevent_release(ds); return ds->do_targetq; } else if (ds->ds_cancel_handler) { if (dq != ds->do_targetq) { return ds->do_targetq; } } _dispatch_source_cancel_callout(ds); } else if (ds->ds_pending_data) { // The source has pending data to deliver via the event handler callback // on the target queue. Some sources need to be rearmed on the manager // queue after event delivery. if (dq != ds->do_targetq) { return ds->do_targetq; } _dispatch_source_latch_and_call(ds); if (ds->ds_needs_rearm) { return &_dispatch_mgr_q; } } else if (ds->ds_needs_rearm && !ds->ds_is_armed) { // The source needs to be rearmed on the manager queue. if (dq != &_dispatch_mgr_q) { return &_dispatch_mgr_q; } _dispatch_source_kevent_resume(ds, 0, 0); ds->ds_is_armed = true; } return NULL; }
// 6618342 Contact the team that owns the Instrument DTrace probe before renaming this symbol static void _dispatch_source_set_cancel_handler2(void *context) { dispatch_source_t ds = (dispatch_source_t)_dispatch_queue_get_current(); dispatch_assert(ds->do_vtable == &_dispatch_source_kevent_vtable); if (ds->ds_cancel_is_block && ds->ds_cancel_handler) { Block_release(ds->ds_cancel_handler); } ds->ds_cancel_handler = context; ds->ds_cancel_is_block = true; }
static void _dispatch_source_set_cancel_handler_f(void *context) { dispatch_source_t ds = (dispatch_source_t)_dispatch_queue_get_current(); dispatch_assert(ds->do_vtable == &_dispatch_source_kevent_vtable); #ifdef __BLOCKS__ if (ds->ds_cancel_is_block && ds->ds_cancel_handler) { Block_release(ds->ds_cancel_handler); } #endif ds->ds_cancel_handler = context; ds->ds_cancel_is_block = false; }
// 6618342 Contact the team that owns the Instrument DTrace probe before renaming this symbol static void _dispatch_source_set_event_handler2(void *context) { struct Block_layout *bl = context; dispatch_source_t ds = (dispatch_source_t)_dispatch_queue_get_current(); dispatch_assert(ds->do_vtable == &_dispatch_source_kevent_vtable); if (ds->ds_handler_is_block && ds->ds_handler_ctxt) { Block_release(ds->ds_handler_ctxt); } ds->ds_handler_func = bl ? (void *)bl->invoke : NULL; ds->ds_handler_ctxt = bl; ds->ds_handler_is_block = true; }
// REQUIRES: x86-registered-target // RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -g -S %s -o - // rdar://7590323 typedef struct dispatch_queue_s *dispatch_queue_t; __attribute__((visibility("default"))) extern struct dispatch_queue_s _dispatch_main_q; typedef struct dispatch_item_s *dispatch_item_t; typedef void (^dispatch_legacy_block_t)(dispatch_item_t); dispatch_item_t LEGACY_dispatch_call(dispatch_queue_t dq, dispatch_legacy_block_t dispatch_block, dispatch_legacy_block_t callback_block) { dispatch_queue_t lq = _dispatch_queue_get_current() ?: (&_dispatch_main_q); dispatch_async(dq, ^ { if (callback_block) { dispatch_async(lq, ^ { } ); } } ); } // radar://9008853 typedef struct P { int x; } PS; # 1 "" void foo() { PS p2; }
void _dispatch_introspection_callout_return(void *ctxt, dispatch_function_t f) { dispatch_queue_t dq = _dispatch_queue_get_current(); DISPATCH_INTROSPECTION_INTERPOSABLE_HOOK_CALLOUT( queue_callout_end, dq, ctxt, f); }
dispatch_queue_t LEGACY_dispatch_queue_get_current(void) { return _dispatch_queue_get_current(); }
///////////////////////////////////////////////////////////////////////////// dispatch_queue_t LEGACY_dispatch_queue_get_current(void) { return _dispatch_queue_get_current(); } #ifdef __BLOCKS__ dispatch_item_t LEGACY_dispatch_call(dispatch_queue_t dq, dispatch_legacy_block_t dispatch_block, dispatch_legacy_block_t callback_block) { dispatch_queue_t lq = _dispatch_queue_get_current() ?: dispatch_get_main_queue(); dispatch_item_t di; di = dispatch_block ? calloc(1, ROUND_UP_TO_CACHELINE_SIZE(sizeof(*di))) : NULL; if (!di) { return di; } if (callback_block) { dispatch_retain(lq); } dispatch_async(dq, ^{ dispatch_block(di);