+ thread_call_priority_t pri;
+ uint32_t options;
+
+ if (reserved) {
+ panic("setTimeoutFunc already %p, %p", this, reserved);
+ }
+
+ // reserved != 0 means IOTimerEventSource::timeoutAndRelease is being used,
+ // not a subclassed implementation
+ reserved = IONewZero(ExpansionData, 1);
+
+ reserved->calloutGenerationSignaled = ~reserved->calloutGeneration;
+ // make use of an existing ivar for parameter passing
+ options = (uint32_t) abstime;
+ abstime = 0;
+
+ thread_call_options_t tcoptions = 0;
+ thread_call_func_t func = NULL;
+
+ switch (kIOTimerEventSourceOptionsPriorityMask & options) {
+ case kIOTimerEventSourceOptionsPriorityHigh:
+ pri = THREAD_CALL_PRIORITY_HIGH;
+ func = &IOTimerEventSource::timeoutAndRelease;
+ break;
+
+ case kIOTimerEventSourceOptionsPriorityKernel:
+ pri = THREAD_CALL_PRIORITY_KERNEL;
+ func = &IOTimerEventSource::timeoutAndRelease;
+ break;
+
+ case kIOTimerEventSourceOptionsPriorityKernelHigh:
+ pri = THREAD_CALL_PRIORITY_KERNEL_HIGH;
+ func = &IOTimerEventSource::timeoutAndRelease;
+ break;
+
+ case kIOTimerEventSourceOptionsPriorityUser:
+ pri = THREAD_CALL_PRIORITY_USER;
+ func = &IOTimerEventSource::timeoutAndRelease;
+ break;
+
+ case kIOTimerEventSourceOptionsPriorityLow:
+ pri = THREAD_CALL_PRIORITY_LOW;
+ func = &IOTimerEventSource::timeoutAndRelease;
+ break;
+
+ case kIOTimerEventSourceOptionsPriorityWorkLoop:
+ pri = THREAD_CALL_PRIORITY_KERNEL;
+ tcoptions |= THREAD_CALL_OPTIONS_SIGNAL;
+ if (kIOTimerEventSourceOptionsAllowReenter & options) {
+ break;
+ }
+ func = &IOTimerEventSource::timeoutSignaled;
+ break;
+
+ default:
+ break;
+ }
+
+ assertf(func, "IOTimerEventSource options 0x%x", options);
+ if (!func) {
+ return; // init will fail
+ }
+ if (THREAD_CALL_OPTIONS_SIGNAL & tcoptions) {
+ flags |= kActive;
+ } else {
+ flags |= kPassive;
+ }
+
+ if (!(kIOTimerEventSourceOptionsAllowReenter & options)) {
+ tcoptions |= THREAD_CALL_OPTIONS_ONCE;
+ }
+
+ calloutEntry = (void *) thread_call_allocate_with_options(func,
+ (thread_call_param_t) this, pri, tcoptions);
+ assert(calloutEntry);
+}
+
+bool
+IOTimerEventSource::init(OSObject *inOwner, Action inAction)
+{
+ if (!super::init(inOwner, (IOEventSource::Action) inAction)) {
+ return false;
+ }
+
+ setTimeoutFunc();
+ if (!calloutEntry) {
+ return false;
+ }