static int _gcdpoll_watch_add(AvahiWatch *w, AvahiWatchEvent a_events) { dispatch_source_t sr = NULL; dispatch_source_t sw = NULL; if ((a_events & AVAHI_WATCH_IN) && !w->w_read) { sr = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, w->fd, 0, mdns_sq); if (!sr) return -1; dispatch_set_context(sr, w); dispatch_source_set_event_handler_f(sr, gcdpollcb_watch_read); } if ((a_events & AVAHI_WATCH_OUT) && !w->w_write) { sw = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, w->fd, 0, mdns_sq); if (!sw) { if (sr) { dispatch_source_cancel(sr); dispatch_release(sr); } return -1; } dispatch_set_context(sw, w); dispatch_source_set_event_handler_f(sw, gcdpollcb_watch_write); } if (sr) { w->w_read = sr; dispatch_resume(sr); } if (sw) { w->w_write = sw; dispatch_resume(sw); } return 0; }
void WorkQueue::registerMachPortEventHandler(mach_port_t machPort, MachPortEventType eventType, const Function<void()>& function) { ASSERT(machPort != MACH_PORT_NULL); dispatch_source_type_t sourceType = 0; switch (eventType) { case MachPortDataAvailable: sourceType = DISPATCH_SOURCE_TYPE_MACH_RECV; break; case MachPortDeadNameNotification: sourceType = DISPATCH_SOURCE_TYPE_MACH_SEND; break; } dispatch_source_t dispatchSource = dispatch_source_create(sourceType, machPort, 0, m_dispatchQueue); EventSource* eventSource = new EventSource(eventType, dispatchSource, function); dispatch_set_context(dispatchSource, eventSource); dispatch_source_set_event_handler_f(dispatchSource, &EventSource::eventHandler); dispatch_source_set_cancel_handler_f(dispatchSource, &EventSource::cancelHandler); dispatch_set_finalizer_f(dispatchSource, &EventSource::finalizeHandler); // Add the source to our set of sources. { MutexLocker locker(m_eventSourcesMutex); ASSERT(!m_eventSources.contains(machPort)); m_eventSources.set(machPort, eventSource); // And start it! dispatch_resume(dispatchSource); } }
static VALUE rb_source_init(VALUE self, SEL sel, VALUE type, VALUE handle, VALUE mask, VALUE queue) { Check_Queue(queue); rb_source_t *src = RSource(self); src->source_enum = (source_enum_t) NUM2LONG(type); dispatch_source_type_t c_type = rb_source_enum2type(src->source_enum); assert(c_type != NULL); uintptr_t c_handle = NUM2UINT(rb_Integer(handle)); unsigned long c_mask = NUM2LONG(mask); dispatch_queue_t c_queue = RQueue(queue)->queue; src->source = dispatch_source_create(c_type, c_handle, c_mask, c_queue); assert(src->source != NULL); rb_vm_block_t *block = get_prepared_block(); GC_WB(&src->event_handler, block); GC_RETAIN(self); // apparently needed to ensure consistent counting dispatch_set_context(src->source, (void *)self); dispatch_source_set_event_handler_f(src->source, rb_source_event_handler); GC_WB(&src->handle, handle); if (rb_source_is_file(src) && rb_obj_is_kind_of(handle, rb_cIO)) { dispatch_source_set_cancel_handler_f(src->source, rb_source_close_handler); } rb_dispatch_resume(self, 0); return self; }
void queue::finalizer( operation *op, const queue &q ) { dispatch_set_finalizer_f( d->native, _xdispatch_run_operation ); dispatch_set_context( d->native, op ); dispatch_set_target_queue( d->native, (dispatch_queue_t)q.native() ); }
DispatchSource createSourceTimer(void * ctx, dispatch_function_t handler) { dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, DISPATCH_TARGET_QUEUE_DEFAULT); dispatch_set_context(source, ctx); dispatch_source_set_event_handler_f(source, handler); dispatch_resume(source); return DispatchSource(source); }
DispatchSource createSourceSignal(int sig, void * ctx, dispatch_function_t handler) { signal(sig, SIG_IGN); dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, sig, 0, DISPATCH_TARGET_QUEUE_DEFAULT); dispatch_set_context(source, ctx); dispatch_source_set_event_handler_f(source, handler); dispatch_resume(source); return DispatchSource(source); }
static void pong(void *context) { dispatch_queue_t this_q = (dispatch_queue_t)context; size_t replies = (size_t)dispatch_get_context(this_q); dispatch_set_context(this_q, (void *)--replies); if (!replies) { //MU_MESSAGE("collect from: %s\n", dispatch_queue_get_label(dispatch_get_current_queue())); dispatch_async_f(dispatch_get_main_queue(), NULL, collect); } }
static void start_node(void *context) { dispatch_queue_t this_q = (dispatch_queue_t)context; size_t i; dispatch_set_context(this_q, (void *)COUNT); for (i = 0; i < COUNT; i++) { dispatch_async_f(queues[i], this_q, ping); } }
static dispatch_source_t mach_create_client_source(xpc_port_t port, void *context, dispatch_queue_t tq) { mach_port_t mp = (mach_port_t)port; dispatch_source_t ret; ret = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, (uintptr_t)mp, 0, tq); dispatch_set_context(ret, context); dispatch_source_set_event_handler_f(ret, xpc_connection_recv_message); dispatch_source_set_cancel_handler(ret, ^{ xpc_connection_destroy_peer(dispatch_get_context(ret)); });
int main(void) { dispatch_test_start("Dispatch Queue Finalizer"); #ifdef __LP64__ ctxt_magic = (void*)((uintptr_t)arc4random() << 32 | arc4random()); #else ctxt_magic = (void*)arc4random(); #endif // we need a non-NULL value for the tests to work properly if (ctxt_magic == NULL) { ctxt_magic = &ctxt_magic; } dispatch_queue_t q = dispatch_queue_create("com.apple.testing.finalizer", NULL); test_ptr_notnull("dispatch_queue_new", q); dispatch_set_finalizer_f(q, finalize); dispatch_queue_t q_null_context = dispatch_queue_create("com.apple.testing.finalizer.context_null", NULL); dispatch_set_context(q_null_context, NULL); dispatch_set_finalizer_f(q_null_context, never_call); dispatch_release(q_null_context); // Don't test k dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC), dispatch_get_main_queue(), ^{ // Usign async to set the context helps test that blocks are // run before the release as opposed to just thrown away. dispatch_async(q, ^{ dispatch_set_context(q, ctxt_magic); }); dispatch_release(q); });
void IOHIDEventSystemStatistics::scheduleWithDispatchQueue(dispatch_queue_t queue) { _dispatch_queue = queue; if ( _dispatch_queue ) { _pending_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)); dispatch_set_context(_pending_source, this); dispatch_source_set_event_handler_f(_pending_source, IOHIDEventSystemStatistics::handlePendingStats); dispatch_resume(_pending_source); notify_register_dispatch( "com.apple.iokit.hid.displayStatus", &_displayToken,_dispatch_queue, ^(__unused int token){ notify_get_state(_displayToken, &_displayState); }); }
static int _gcdpoll_timeout_add(AvahiTimeout *t, const struct timeval *tv) { struct timeval e_tv; struct timeval now; int64_t nsecs; int ret; ret = gettimeofday(&now, NULL); if (ret != 0) return -1; if (!t->timer) { t->timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, mdns_sq); if (!t->timer) return -1; dispatch_set_context(t->timer, t); dispatch_source_set_event_handler_f(t->timer, gcdpollcb_timer); } else dispatch_suspend(t->timer); if ((tv->tv_sec == 0) && (tv->tv_usec == 0)) { dispatch_source_set_timer(t->timer, DISPATCH_TIME_NOW, DISPATCH_TIME_FOREVER /* one-shot */, 0); } else { timersub(tv, &now, &e_tv); nsecs = e_tv.tv_sec * NSEC_PER_SEC + e_tv.tv_usec * 1000; dispatch_source_set_timer(t->timer, dispatch_time(DISPATCH_TIME_NOW, nsecs), DISPATCH_TIME_FOREVER /* one-shot */, 0); } dispatch_resume(t->timer); return 0; }
int main(void) { test_start("Dispatch Queue Finalizer"); #ifdef __LP64__ ctxt_magic = (void*)((uintptr_t)arc4random() << 32 | arc4random()); #else ctxt_magic = (void*)arc4random(); #endif dispatch_queue_t q = dispatch_queue_create(NULL, NULL); test_ptr_notnull("dispatch_queue_new", q); dispatch_set_context(q, ctxt_magic); dispatch_set_finalizer_f(q, finalizer); dispatch_release(q); dispatch_main(); return 0; }
void WorkQueue::platformInitialize(const char* name) { m_dispatchQueue = dispatch_queue_create(name, 0); dispatch_set_context(m_dispatchQueue, this); }
Boolean SCDynamicStoreSetDispatchQueue(SCDynamicStoreRef store, dispatch_queue_t queue) { dispatch_group_t drainGroup = NULL; dispatch_queue_t drainQueue = NULL; dispatch_group_t group = NULL; mach_port_t mp; Boolean ok = FALSE; dispatch_source_t source; SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; if (store == NULL) { // sorry, you must provide a session _SCErrorSet(kSCStatusNoStoreSession); return FALSE; } if (queue == NULL) { if (storePrivate->dispatchQueue == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } ok = TRUE; goto cleanup; } if (storePrivate->server == MACH_PORT_NULL) { // sorry, you must have an open session to play _SCErrorSet(kSCStatusNoStoreServer); return FALSE; } if ((storePrivate->dispatchQueue != NULL) || (storePrivate->rls != NULL)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (storePrivate->notifyStatus != NotifierNotRegistered) { // sorry, you can only have one notification registered at once... _SCErrorSet(kSCStatusNotifierActive); return FALSE; } /* * mark our using of the SCDynamicStore notifications, create and schedule * the notification port (storePrivate->rlsNotifyPort), and a bunch of other * "setup" */ storePrivate->notifyStatus = Using_NotifierInformViaDispatch; rlsSchedule((void*)store, NULL, NULL); if (storePrivate->rlsNotifyPort == NULL) { /* if we could not schedule the notification */ _SCErrorSet(kSCStatusFailed); goto cleanup; } // retain the dispatch queue storePrivate->dispatchQueue = queue; dispatch_retain(storePrivate->dispatchQueue); // // We've taken a reference to the callers dispatch_queue and we // want to hold on to that reference until we've processed any/all // notifications. To facilitate this we create a group, dispatch // any notification blocks to via that group, and when the caller // has told us to stop the notifications (unschedule) we wait for // the group to empty and use the group's finalizer to release // our reference to the SCDynamicStore. // group = dispatch_group_create(); storePrivate->dispatchGroup = group; CFRetain(store); dispatch_set_context(storePrivate->dispatchGroup, (void *)store); dispatch_set_finalizer_f(storePrivate->dispatchGroup, (dispatch_function_t)CFRelease); // create a dispatch source for the mach notifications mp = CFMachPortGetPort(storePrivate->rlsNotifyPort); source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, mp, 0, queue); if (source == NULL) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStore dispatch_source_create() failed")); _SCErrorSet(kSCStatusFailed); goto cleanup; } dispatch_source_set_event_handler(source, ^{ kern_return_t kr; mach_msg_id_t msgid; union { u_int8_t buf[sizeof(mach_msg_empty_t) + MAX_TRAILER_SIZE]; mach_msg_empty_rcv_t msg; mach_no_senders_notification_t no_senders; } notify_msg; kr = mach_msg(¬ify_msg.msg.header, // msg MACH_RCV_MSG, // options 0, // send_size sizeof(notify_msg), // rcv_size mp, // rcv_name MACH_MSG_TIMEOUT_NONE, // timeout MACH_PORT_NULL); // notify if (kr != KERN_SUCCESS) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStore notification handler, kr=0x%x"), kr); return; } msgid = notify_msg.msg.header.msgh_id; CFRetain(store); dispatch_group_async(group, queue, ^{ if (msgid == MACH_NOTIFY_NO_SENDERS) { // re-establish notification and inform the client (void)__SCDynamicStoreReconnectNotifications(store); } rlsPerform(storePrivate); CFRelease(store); }); });