// === CODE === void Timer_CallbackThread(void *Unused) { Threads_SetName("Timer Callback Thread"); Workqueue_Init(&gTimers_CallbackQueue, "Timer Callbacks", offsetof(tTimer, Next)); for(;;) { tTimer *timer = Workqueue_GetWork(&gTimers_CallbackQueue); if( !timer->Callback ) { LOG("Timer %p doesn't have a callback", timer); ASSERT( timer->Callback ); } // Save callback and argument (because once the mutex is released // the timer may no longer be valid) tTimerCallback *cb = timer->Callback; void *arg = timer->Argument; LOG("Callback fire %p", timer); // Allow Time_RemoveTimer to be called safely timer->bActive = 0; // Fire callback cb(arg); // Mark timer as no longer needed } }
// === CODE === void USB_PortCtl_Init(void) { Workqueue_Init(&gUSB_PortCtl_WorkQueue, "USB Port Reset Work Queue", offsetof(tUSBHubPort, ListNext)); Proc_SpawnWorker(USB_PortCtl_Worker, NULL); }