void WorkQueue::Complete(unsigned priority) { completing_ = true; if (threads_.Size()) { Resume(); // Take work items also in the main thread until queue empty or no high-priority items anymore while (!queue_.Empty()) { queueMutex_.Acquire(); if (!queue_.Empty() && queue_.Front()->priority_ >= priority) { WorkItem* item = queue_.Front(); queue_.PopFront(); queueMutex_.Release(); item->workFunction_(item, 0); item->completed_ = true; } else { queueMutex_.Release(); break; } } // Wait for threaded work to complete while (!IsCompleted(priority)) { } // If no work at all remaining, pause worker threads by leaving the mutex locked if (queue_.Empty()) Pause(); } else { // No worker threads: ensure all high-priority items are completed in the main thread while (!queue_.Empty() && queue_.Front()->priority_ >= priority) { WorkItem* item = queue_.Front(); queue_.PopFront(); item->workFunction_(item, 0); item->completed_ = true; } } PurgeCompleted(priority); completing_ = false; }
void WorkQueue::ProcessItems(unsigned threadIndex) { bool wasActive = false; for (;;) { if (shutDown_) return; if (pausing_ && !wasActive) Time::Sleep(0); else { queueMutex_.Acquire(); if (!queue_.Empty()) { wasActive = true; WorkItem* item = queue_.Front(); queue_.PopFront(); queueMutex_.Release(); item->workFunction_(item, threadIndex); item->completed_ = true; } else { wasActive = false; queueMutex_.Release(); Time::Sleep(0); } } } }
void WorkQueue::HandleBeginFrame(StringHash eventType, VariantMap& eventData) { // If no worker threads, complete low-priority work here if (threads_.Empty() && !queue_.Empty()) { URHO3D_PROFILE(CompleteWorkNonthreaded); HiresTimer timer; while (!queue_.Empty() && timer.GetUSec(false) < maxNonThreadedWorkMs_ * 1000) { WorkItem* item = queue_.Front(); queue_.PopFront(); item->workFunction_(item, 0); item->completed_ = true; } } // Complete and signal items down to the lowest priority PurgeCompleted(0); PurgePool(); }