Пример #1
0
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;
}
Пример #2
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);
    }
}
Пример #3
0
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;
}
Пример #4
0
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() );
}
Пример #5
0
	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);
	}
Пример #6
0
	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);
	}
Пример #7
0
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);
	}
}
Пример #8
0
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);
	}
}
Пример #9
0
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);
        });
    }
Пример #12
0
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;
}
Пример #13
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;
}
Пример #14
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(&notify_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);
		});
	});