OSMetaClassDefineReservedUnused(IOTimerEventSource, 6);
OSMetaClassDefineReservedUnused(IOTimerEventSource, 7);
+//
+// reserved != 0 means IOTimerEventSource::timeoutAndRelease is being used,
+// not a subclassed implementation.
+//
+
bool IOTimerEventSource::checkForWork() { return false; }
// Timeout handler function. This function is called by the kernel when
{
IOTimerEventSource *me = (IOTimerEventSource *) self;
- if (me->enabled) {
- Action doit = (Action) me->action;
+ if (me->enabled && me->action)
+ {
+ IOWorkLoop *
+ wl = me->workLoop;
+ if (wl)
+ {
+ Action doit;
+ wl->closeGate();
+ doit = (Action) me->action;
+ if (doit && me->enabled && AbsoluteTime_to_scalar(&me->abstime))
+ {
+ IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
+ (unsigned int) doit, (unsigned int) me->owner);
+ (*doit)(me->owner, me);
+ }
+ wl->openGate();
+ }
+ }
+}
- if (doit) {
- IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
- (unsigned int) doit, (unsigned int) me->owner);
- me->closeGate();
- (*doit)(me->owner, me);
- me->openGate();
+void IOTimerEventSource::timeoutAndRelease(void * self, void * count)
+{
+ IOTimerEventSource *me = (IOTimerEventSource *) self;
+
+ if (me->enabled && me->action)
+ {
+ IOWorkLoop *
+ wl = me->reserved->workLoop;
+ if (wl)
+ {
+ Action doit;
+ wl->closeGate();
+ doit = (Action) me->action;
+ if (doit && (me->reserved->calloutGeneration == (SInt32) count))
+ {
+ IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
+ (unsigned int) doit, (unsigned int) me->owner);
+ (*doit)(me->owner, me);
+ }
+ wl->openGate();
}
}
+
+ me->reserved->workLoop->release();
+ me->release();
}
void IOTimerEventSource::setTimeoutFunc()
{
- calloutEntry = (void *) thread_call_allocate((thread_call_func_t) timeout,
+ // reserved != 0 means IOTimerEventSource::timeoutAndRelease is being used,
+ // not a subclassed implementation
+ reserved = IONew(ExpansionData, 1);
+ calloutEntry = (void *) thread_call_allocate((thread_call_func_t) &IOTimerEventSource::timeoutAndRelease,
(thread_call_param_t) this);
}
IOTimerEventSource *me = new IOTimerEventSource;
if (me && !me->init(inOwner, inAction)) {
- me->free();
+ me->release();
return 0;
}
thread_call_free((thread_call_t) calloutEntry);
}
+ if (reserved)
+ IODelete(reserved, ExpansionData, 1);
+
super::free();
}
void IOTimerEventSource::cancelTimeout()
{
- thread_call_cancel((thread_call_t) calloutEntry);
+ if (reserved)
+ reserved->calloutGeneration++;
+ bool active = thread_call_cancel((thread_call_t) calloutEntry);
AbsoluteTime_to_scalar(&abstime) = 0;
+ if (active && reserved)
+ {
+ release();
+ workLoop->release();
+ }
}
void IOTimerEventSource::enable()
void IOTimerEventSource::disable()
{
- thread_call_cancel((thread_call_t) calloutEntry);
+ if (reserved)
+ reserved->calloutGeneration++;
+ bool active = thread_call_cancel((thread_call_t) calloutEntry);
super::disable();
+ if (active && reserved)
+ {
+ release();
+ workLoop->release();
+ }
}
IOReturn IOTimerEventSource::setTimeoutTicks(UInt32 ticks)
{
- return setTimeout(ticks, NSEC_PER_SEC/hz);
+ return setTimeout(ticks, kTickScale);
}
IOReturn IOTimerEventSource::setTimeoutMS(UInt32 ms)
IOReturn IOTimerEventSource::wakeAtTimeTicks(UInt32 ticks)
{
- return wakeAtTime(ticks, NSEC_PER_SEC/hz);
+ return wakeAtTime(ticks, kTickScale);
}
IOReturn IOTimerEventSource::wakeAtTimeMS(UInt32 ms)
return wakeAtTime(us, kMicrosecondScale);
}
-IOReturn IOTimerEventSource::wakeAtTime(UInt32 abstime, UInt32 scale_factor)
+IOReturn IOTimerEventSource::wakeAtTime(UInt32 inAbstime, UInt32 scale_factor)
{
AbsoluteTime end;
- clock_interval_to_absolutetime_interval(abstime, scale_factor, &end);
+ clock_interval_to_absolutetime_interval(inAbstime, scale_factor, &end);
return wakeAtTime(end);
}
-IOReturn IOTimerEventSource::wakeAtTime(mach_timespec_t abstime)
+IOReturn IOTimerEventSource::wakeAtTime(mach_timespec_t inAbstime)
{
AbsoluteTime end, nsecs;
clock_interval_to_absolutetime_interval
- (abstime.tv_nsec, kNanosecondScale, &nsecs);
+ (inAbstime.tv_nsec, kNanosecondScale, &nsecs);
clock_interval_to_absolutetime_interval
- (abstime.tv_sec, kSecondScale, &end);
+ (inAbstime.tv_sec, kSecondScale, &end);
ADD_ABSOLUTETIME(&end, &nsecs);
return wakeAtTime(end);
}
+void IOTimerEventSource::setWorkLoop(IOWorkLoop *inWorkLoop)
+{
+ super::setWorkLoop(inWorkLoop);
+ if ( enabled && AbsoluteTime_to_scalar(&abstime) && workLoop )
+ wakeAtTime(abstime);
+}
+
IOReturn IOTimerEventSource::wakeAtTime(AbsoluteTime inAbstime)
{
if (!action)
return kIOReturnNoResources;
abstime = inAbstime;
- if ( enabled && AbsoluteTime_to_scalar(&abstime) )
- thread_call_enter_delayed((thread_call_t) calloutEntry, abstime);
+ if ( enabled && AbsoluteTime_to_scalar(&abstime) && workLoop )
+ {
+ if (reserved)
+ {
+ retain();
+ workLoop->retain();
+ reserved->workLoop = workLoop;
+ reserved->calloutGeneration++;
+ if (thread_call_enter1_delayed((thread_call_t) calloutEntry,
+ (void *) reserved->calloutGeneration, abstime))
+ {
+ release();
+ workLoop->release();
+ }
+ }
+ else
+ thread_call_enter_delayed((thread_call_t) calloutEntry, abstime);
+ }
return kIOReturnSuccess;
}