예제 #1
0
/* extern */ void
_CFTypeInvalidate(CFTypeRef obj) {

	CFTypeID t = CFGetTypeID(obj);

	/* Invalidate according to type of object. */
	if (t == CFRunLoopSourceGetTypeID()) {
		CFRunLoopSourceInvalidate((CFRunLoopSourceRef)obj);
	}

	else if (t == CFMachPortGetTypeID()) {
		CFMachPortInvalidate((CFMachPortRef)obj);
	}

	else if (t == CFSocketGetTypeID()) {
		CFSocketInvalidate((CFSocketRef)obj);
	}

	/* For scheduled types of objects, it is invalidated by setting the client to NULL. */
	else if (t == CFReadStreamGetTypeID()) {
		CFReadStreamSetClient((CFReadStreamRef)obj, kCFStreamEventNone, NULL, NULL);
	}

	else if (t == CFWriteStreamGetTypeID()) {
		CFWriteStreamSetClient((CFWriteStreamRef)obj, kCFStreamEventNone, NULL, NULL);
	}

	else if (t == CFHostGetTypeID()) {
		CFHostSetClient((CFHostRef)obj, NULL, NULL);
	}

	else if (t == SCNetworkReachabilityGetTypeID()) {
		SCNetworkReachabilitySetCallback((SCNetworkReachabilityRef)obj, NULL, NULL);
	}

	else if (t == CFRunLoopTimerGetTypeID()) {
		CFRunLoopTimerInvalidate((CFRunLoopTimerRef)obj);
	}

	else if (t == CFNetServiceGetTypeID()) {
		CFNetServiceSetClient((CFNetServiceRef)obj, NULL, NULL);
	}

	else if (t == CFNetServiceBrowserGetTypeID()) {
		CFNetServiceBrowserInvalidate((CFNetServiceBrowserRef)obj);
	}

	else if (t == CFNetServiceMonitorGetTypeID()) {
		CFNetServiceMonitorInvalidate((CFNetServiceMonitorRef)obj);
	}

	else if (t == SCNetworkReachabilityGetTypeID()) {
		SCNetworkConnectionStop((SCNetworkConnectionRef)obj, FALSE);
	}
}
예제 #2
0
파일: usb_mac.c 프로젝트: akosipc/ckb
void* os_inputmain(void* context){
    usbdevice* kb = context;
    int index = INDEX_OF(kb, keyboard);
    // Schedule async events for the device on this thread
    CFRunLoopRef runloop = CFRunLoopGetCurrent();
    int count = (IS_RGB(kb->vendor, kb->product)) ? 4 : 3;
    for(int i = 0; i < count; i++){
        CFTypeRef eventsource;
        kern_return_t res = (*kb->handles[i])->getAsyncEventSource(kb->handles[i], &eventsource);
        if(res != kIOReturnSuccess){
            ckb_err("Failed to start input thread for %s%d: %x\n", devpath, index, res);
            return 0;
        }
        if(CFGetTypeID(eventsource) == CFRunLoopSourceGetTypeID())
            CFRunLoopAddSource(runloop, (CFRunLoopSourceRef)eventsource, kCFRunLoopDefaultMode);
        else if(CFGetTypeID(eventsource) == CFRunLoopTimerGetTypeID())
            CFRunLoopAddTimer(runloop, (CFRunLoopTimerRef)eventsource, kCFRunLoopDefaultMode);
    }
    ckb_info("Starting input thread for %s%d\n", devpath, index);

    // Start getting reports
    uint8_t* urbinput[] = { malloc(8), malloc(32), malloc(MSG_SIZE) };
    (*kb->handles[0])->setInputReportCallback(kb->handles[0], urbinput[0], 8, intreport, kb, 0);
    if(IS_RGB(kb->vendor, kb->product)){
        (*kb->handles[1])->setInputReportCallback(kb->handles[1], urbinput[1], 21, intreport, kb, 0);
        (*kb->handles[2])->setInputReportCallback(kb->handles[2], urbinput[2], MSG_SIZE, intreport, kb, 0);
    } else {
        (*kb->handles[1])->setInputReportCallback(kb->handles[1], urbinput[1], 4, intreport, kb, 0);
        (*kb->handles[2])->setInputReportCallback(kb->handles[2], urbinput[2], 15, intreport, kb, 0);
    }

    // Run the run loop for up to 2ms at a time, then check for key repeats
    while(1){
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.002, false);
        pthread_mutex_lock(imutex(kb));
        if(!IS_CONNECTED(kb)){
            // Make sure the device hasn't disconnected
            pthread_mutex_unlock(imutex(kb));
            break;
        }
        keyretrigger(kb);
        pthread_mutex_unlock(imutex(kb));
    }

    // Clean up
    ckb_info("Stopping input thread for %s%d\n", devpath, index);
    free(urbinput[0]);
    free(urbinput[1]);
    free(urbinput[2]);
    return 0;
}
예제 #3
0
void UPSDeviceAdded(void *refCon, io_iterator_t iterator)
{
    io_object_t             upsDevice           = MACH_PORT_NULL;
    UPSDataRef              upsDataRef          = NULL;
    CFDictionaryRef         upsProperties       = NULL;
    CFDictionaryRef         upsEvent            = NULL;
    CFSetRef                upsCapabilites 		= NULL;
    CFRunLoopSourceRef      upsEventSource      = NULL;
    CFRunLoopTimerRef       upsEventTimer       = NULL;
    CFTypeRef               typeRef             = NULL;
    IOCFPlugInInterface **	plugInInterface 	= NULL;
    IOUPSPlugInInterface_v140 **	upsPlugInInterface 	= NULL;
    HRESULT                 result              = S_FALSE;
    IOReturn                kr;
    SInt32                  score;
        
    while ( (upsDevice = IOIteratorNext(iterator)) )
    {        
        // Create the CF plugin for this device
        kr = IOCreatePlugInInterfaceForService(upsDevice, kIOUPSPlugInTypeID, 
                    kIOCFPlugInInterfaceID, &plugInInterface, &score);
                    
        if ( kr != kIOReturnSuccess )
            goto UPSDEVICEADDED_NONPLUGIN_CLEANUP;
            
        // Grab the new v140 interface
        result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUPSPlugInInterfaceID_v140), 
                                                (LPVOID)&upsPlugInInterface);
                                                
        if ( ( result == S_OK ) && upsPlugInInterface )
        {
            kr = (*upsPlugInInterface)->createAsyncEventSource(upsPlugInInterface, &typeRef);
            
            if ((kr != kIOReturnSuccess) || !typeRef)
                goto UPSDEVICEADDED_FAIL;
                
            if ( CFGetTypeID(typeRef) == CFRunLoopTimerGetTypeID() )
            {
                upsEventTimer = (CFRunLoopTimerRef)typeRef;
                CFRunLoopAddTimer(CFRunLoopGetCurrent(), upsEventTimer, kCFRunLoopDefaultMode);
            }
            else if ( CFGetTypeID(typeRef) == CFRunLoopSourceGetTypeID() )
            {
                upsEventSource = (CFRunLoopSourceRef)typeRef;
                CFRunLoopAddSource(CFRunLoopGetCurrent(), upsEventSource, kCFRunLoopDefaultMode);
            }
        }
        // Couldn't grab the new interface.  Fallback on the old.
        else
        {
            result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUPSPlugInInterfaceID), 
                                                (LPVOID)&upsPlugInInterface);
        }
                                                        
        // Got the interface
        if ( ( result == S_OK ) && upsPlugInInterface )
        {
            kr = (*upsPlugInInterface)->getProperties(upsPlugInInterface, &upsProperties);
            
            if (kr != kIOReturnSuccess)
                goto UPSDEVICEADDED_FAIL;
                
            upsDataRef = GetPrivateData(upsProperties);

            if ( !upsDataRef )
                goto UPSDEVICEADDED_FAIL;

            upsDataRef->upsPlugInInterface  = (IOUPSPlugInInterface **)upsPlugInInterface;
            upsDataRef->upsEventSource      = upsEventSource;
            upsDataRef->upsEventTimer       = upsEventTimer;
            upsDataRef->isPresent           = true;
            
            kr = (*upsPlugInInterface)->getCapabilities(upsPlugInInterface, &upsCapabilites);

            if (kr != kIOReturnSuccess)
                goto UPSDEVICEADDED_FAIL;

            kr = CreatePowerManagerUPSEntry(upsDataRef, upsProperties, upsCapabilites);

            if (kr != kIOReturnSuccess)
                goto UPSDEVICEADDED_FAIL;

            kr = (*upsPlugInInterface)->getEvent(upsPlugInInterface, &upsEvent);

            if (kr != kIOReturnSuccess)
                goto UPSDEVICEADDED_FAIL;

            ProcessUPSEvent(upsDataRef, upsEvent);

            (*upsPlugInInterface)->setEventCallback(upsPlugInInterface, UPSEventCallback, NULL, upsDataRef);

            IOServiceAddInterestNotification(	
                                    gNotifyPort,		// notifyPort
                                    upsDevice,			// service
                                    kIOGeneralInterest,		// interestType
                                    DeviceNotification,		// callback
                                    upsDataRef,			// refCon
                                    &(upsDataRef->notification)	// notification
                                    );
                                    
            goto UPSDEVICEADDED_CLEANUP;
        }

UPSDEVICEADDED_FAIL:
        // Failed to allocated a UPS interface.  Do some cleanup
        if ( upsPlugInInterface )
        {
            (*upsPlugInInterface)->Release(upsPlugInInterface);
            upsPlugInInterface = NULL;
        }
        
        if ( upsEventSource )
        {
            CFRunLoopRemoveSource(CFRunLoopGetCurrent(), upsEventSource, kCFRunLoopDefaultMode);
            upsEventSource = NULL;
        }

        if ( upsEventTimer )
        {
            CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), upsEventTimer, kCFRunLoopDefaultMode);
            upsEventSource = NULL;
        }

UPSDEVICEADDED_CLEANUP:
        // Clean up
        (*plugInInterface)->Release(plugInInterface);
        
UPSDEVICEADDED_NONPLUGIN_CLEANUP:
        IOObjectRelease(upsDevice);
    }
}
예제 #4
0
/* extern */ void
_CFTypeScheduleOnRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode) {

	CFTypeID t = CFGetTypeID(obj);
	CFTypeRef src = NULL;
	void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
	void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);

	fn = NULL;
	fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddSource;

	/* Get the correct source or function used for adding the object to the run loop. */
	if (t == CFRunLoopSourceGetTypeID()) {
		src = CFRetain(obj);
	}

	else if (t == CFMachPortGetTypeID()) {
		src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
	}

	else if (t == CFSocketGetTypeID()) {
		src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
	}

	else if (t == CFReadStreamGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamScheduleWithRunLoop;
	}

	else if (t == CFWriteStreamGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamScheduleWithRunLoop;
	}

	else if (t == CFHostGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostScheduleWithRunLoop;
	}

	else if (t == SCNetworkReachabilityGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityScheduleWithRunLoop;
	}

	else if (t == CFRunLoopTimerGetTypeID()) {
		src = CFRetain(obj);
		fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddTimer;
	}

	else if (t == CFNetServiceGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceScheduleWithRunLoop;
	}

	else if (t == CFNetServiceBrowserGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserScheduleWithRunLoop;
	}

	else if (t == CFNetServiceMonitorGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorScheduleWithRunLoop;
	}

	else if (t == SCNetworkConnectionGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionScheduleWithRunLoop;
	}


	/* If a source was retrieved, need to add the source */
	if (src) {
		fn2(runLoop, src, runLoopMode);
		CFRelease(src);
	}

	/* If a schedule function was retrieved, call it. */
	else if (fn) {
		fn(obj, runLoop, runLoopMode);
	}
}
예제 #5
0
/* extern */ void
_CFTypeUnscheduleFromMultipleRunLoops(CFTypeRef obj, CFArrayRef schedules) {

	CFTypeID t = CFGetTypeID(obj);
	CFTypeRef src = NULL;
	void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
	void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);

	fn = NULL;
	fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveSource;

	/* Get the proper source or function for removing the object from the run loop. */
	if (t == CFRunLoopSourceGetTypeID()) {
		src = CFRetain(obj);
	}

	else if (t == CFMachPortGetTypeID()) {
		src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
	}

	else if (t == CFSocketGetTypeID()) {
		src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
	}

	else if (t == CFReadStreamGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamUnscheduleFromRunLoop;
	}

	else if (t == CFWriteStreamGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamUnscheduleFromRunLoop;
	}

	else if (t == CFHostGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostUnscheduleFromRunLoop;
	}

	else if (t == SCNetworkReachabilityGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityUnscheduleFromRunLoop;
	}

	else if (t == CFRunLoopTimerGetTypeID()) {
		src = CFRetain(obj);
		fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveTimer;
	}

	else if (t == CFNetServiceGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceUnscheduleFromRunLoop;
	}

	else if (t == CFNetServiceBrowserGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserUnscheduleFromRunLoop;
	}

	else if (t == CFNetServiceMonitorGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorUnscheduleFromRunLoop;
	}

	else if (t == SCNetworkConnectionGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionUnscheduleFromRunLoop;
	}

	/* If a source was retrieved, need to remove it from the list of run loops*/
	if (src) {

		CFIndex i, length = CFArrayGetCount(schedules);

		for (i = 0; i < length; i += 2) {
			fn2((CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
				src,
				(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
		}

		CFRelease(src);
	}

	/* If an unschedule function was retrieved, need to call it for each schedule in the list. */
	else if (fn) {

		CFIndex i, length = CFArrayGetCount(schedules);

		for (i = 0; i < length; i += 2) {
			fn(obj,
			   (CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
			   (CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
		}
	}
}
예제 #6
0
/* extern */ void
_CFTypeUnscheduleFromRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode) {

	CFTypeID t = CFGetTypeID(obj);
	CFTypeRef src = NULL;
	void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
	void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);

	fn = NULL;
	fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveSource;

	/* Get the proper source or function for removing the object from the run loop. */
	if (t == CFRunLoopSourceGetTypeID()) {
		src = CFRetain(obj);
	}

	else if (t == CFMachPortGetTypeID()) {
		src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
	}

	else if (t == CFSocketGetTypeID()) {
		src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
	}

	else if (t == CFReadStreamGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamUnscheduleFromRunLoop;
	}

	else if (t == CFWriteStreamGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamUnscheduleFromRunLoop;
	}

	else if (t == CFHostGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostUnscheduleFromRunLoop;
	}

	else if (t == SCNetworkReachabilityGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityUnscheduleFromRunLoop;
	}

	else if (t == CFRunLoopTimerGetTypeID()) {
		src = CFRetain(obj);
		fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveTimer;
	}

	else if (t == CFNetServiceGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceUnscheduleFromRunLoop;
	}

	else if (t == CFNetServiceBrowserGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserUnscheduleFromRunLoop;
	}

	else if (t == CFNetServiceMonitorGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorUnscheduleFromRunLoop;
	}

	else if (t == SCNetworkConnectionGetTypeID()) {
		fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionUnscheduleFromRunLoop;
	}

	/* If a source was retrieved, need to remove it */
	if (src) {
		fn2(runLoop, src, runLoopMode);
		CFRelease(src);
	}

	/* If an unschedule function was retrieved, need to call it. */
	else if (fn) {
		fn(obj, runLoop, runLoopMode);
	}
}
예제 #7
0
void
rwsched_cftimer_callout_intercept(CFRunLoopTimerRef timer,
                                  void *info)
{
  rwsched_instance_ptr_t instance;
  rwsched_CFRunLoopTimerRef rwsched_object = (rwsched_CFRunLoopTimerRef) info;
  rwsched_tasklet_ptr_t sched_tasklet;

  // Validate input parameters
  __CFGenericValidateType_(timer, CFRunLoopTimerGetTypeID(), __PRETTY_FUNCTION__);
  RW_CF_TYPE_VALIDATE(rwsched_object, rwsched_CFRunLoopTimerRef);
  sched_tasklet = rwsched_object->callback_context.tasklet_info;
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
  instance = rwsched_object->callback_context.instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // #1 - Check if the current tasklet is in blocking mode; if a
  //      timer fired while blocking, then dont call the callback
  // #2 - Otherwise the current tasklet is not blocking and the timer callback
  //      shall be called
  if (sched_tasklet->blocking_mode.blocked) {
    /*
    printf("BLOK timer=%p valid=%d repeat=%d interval=%f next-fire=%f \n",
           timer, CFRunLoopTimerIsValid(timer), CFRunLoopTimerDoesRepeat(timer), CFRunLoopTimerGetInterval(timer),
           (CFRunLoopTimerGetNextFireDate(timer) - CFAbsoluteTimeGetCurrent()));
    */
    CFRunLoopRemoveTimer(rwsched_tasklet_CFRunLoopGetCurrent(sched_tasklet), rwsched_object->cf_object, instance->main_cfrunloop_mode);
    //CFRunLoopAddTimer(rwsched_tasklet_CFRunLoopGetCurrent(sched_tasklet), rwsched_object->cf_object, instance->deferred_cfrunloop_mode);
    if (rwsched_object->onetime_timer)
      rwsched_object->onetime_timer_fired_while_blocked = 1;
  }
  else {
    /*
    printf("MAIN timer=%p valid=%d repeat=%d interval=%f next-fire=%f \n",
           timer, CFRunLoopTimerIsValid(timer), CFRunLoopTimerDoesRepeat(timer), CFRunLoopTimerGetInterval(timer),
           (CFRunLoopTimerGetNextFireDate(timer) - CFAbsoluteTimeGetCurrent()));
    */
    g_rwresource_track_handle = sched_tasklet->rwresource_track_handle;
    g_tasklet_info = sched_tasklet;

    // The current task is not blocking so we can invoke the callback now

    struct timeval tv_begin, tv_end, tv_delta;
    if (sched_tasklet->instance->latency.check_threshold_ms) {
      gettimeofday(&tv_begin, NULL);
    } else {
      tv_begin.tv_sec = 0;
    }

    (rwsched_object->cf_callout)(rwsched_object, rwsched_object->cf_context.info);

    if (tv_begin.tv_sec
	&& sched_tasklet->instance->latency.check_threshold_ms) {
      gettimeofday(&tv_end, NULL);
      timersub(&tv_end, &tv_begin, &tv_delta);
      unsigned int cbms = (tv_delta.tv_sec * 1000 + tv_delta.tv_usec / 1000);
      if (cbms >= sched_tasklet->instance->latency.check_threshold_ms) {
	char *name = rw_btrace_get_proc_name(rwsched_object->cf_callout);
  RWSCHED_LOG_EVENT(instance, SchedDebug, RWLOG_ATTR_SPRINTF("rwsched[%d] CF timer took %ums ctx %p callback %s",
                                                             getpid(), cbms, rwsched_object->cf_context.info, name));
	free(name);
      }
    }

    g_tasklet_info = 0;
    g_rwresource_track_handle = 0;
  }
}