+ bool res = false;
+ bool traceWL = (gIOKitTrace & kIOTraceWorkLoops) ? true : false;
+ bool traceES = (gIOKitTrace & kIOTraceEventSources) ? true : false;
+
+ closeGate();
+ if (ISSETP(&fFlags, kLoopTerminate))
+ goto abort;
+
+ if (traceWL)
+ IOTimeStampStartConstant(IODBG_WORKLOOP(IOWL_WORK), (uintptr_t) this);
+
+ bool more;
+ do {
+ CLRP(&fFlags, kLoopRestart);
+ more = false;
+ IOInterruptState is = IOSimpleLockLockDisableInterrupt(workToDoLock);
+ workToDo = false;
+ IOSimpleLockUnlockEnableInterrupt(workToDoLock, is);
+ /* NOTE: only loop over event sources in eventChain. Bypass "passive" event sources for performance */
+ for (IOEventSource *evnt = eventChain; evnt; evnt = evnt->getNext()) {
+
+ if (traceES)
+ IOTimeStampStartConstant(IODBG_WORKLOOP(IOWL_CLIENT), (uintptr_t) this, (uintptr_t) evnt);
+
+ more |= evnt->checkForWork();
+
+ if (traceES)
+ IOTimeStampEndConstant(IODBG_WORKLOOP(IOWL_CLIENT), (uintptr_t) this, (uintptr_t) evnt);
+
+ if (ISSETP(&fFlags, kLoopTerminate))
+ goto abort;
+ else if (fFlags & kLoopRestart) {
+ more = true;
+ break;
+ }
+ }
+ } while (more);
+
+ res = true;
+
+ if (traceWL)
+ IOTimeStampEndConstant(IODBG_WORKLOOP(IOWL_WORK), (uintptr_t) this);
+
+abort:
+ openGate();
+ return res;