void WorkItemQueue::Process() { while (!m_dying) { WorkItem* item = NULL; boost::unique_lock<boost::mutex> lock(m_mutex); while ((!m_dying) && (item = Pop())) { try { // LslDebug( "running WorkItem %p, prio = %d", item, item->m_priority ); item->Run(); } catch (std::exception& e) { // better eat all exceptions thrown by WorkItem::Run(), // don't want to let the thread die on a single faulty WorkItem. LslDebug("WorkerThread caught exception thrown by WorkItem::Run -- %s", e.what()); } catch (...) { LslDebug("WorkerThread caught exception thrown by WorkItem::Run"); } CleanupWorkItem(item); } // cleanup leftover WorkItems while ((item = Pop()) != NULL) { CleanupWorkItem(item); } if (!m_dying) //wait for the next Push m_cond.wait(lock); } }
void* WorkerThread::Entry() { WorkItem* item; wxLogMessage( _T( "WorkerThread started" ) ); while ( !TestDestroy() ) { // sleep an hour or until a new WorkItem arrives (DoWork() will wake us up). Sleep( 3600 * 1000 ); while ( !TestDestroy() && ( item = m_workItems.Pop() ) != NULL ) { try { wxLogMessage( _T( "running WorkItem %p, prio = %d" ), item, item->m_priority ); item->Run(); } catch ( ... ) { // better eat all exceptions thrown by WorkItem::Run(), // don't want to let the thread die on a single faulty WorkItem. wxLogMessage( _T( "WorkerThread caught exception thrown by WorkItem::Run" ) ); } CleanupWorkItem( item ); // give other threads some air Yield(); } } // cleanup leftover WorkItems while ( ( item = m_workItems.Pop() ) != NULL ) { CleanupWorkItem( item ); } wxLogMessage( _T( "WorkerThread stopped" ) ); return 0; }
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 ReplicationExecutor::doOperationWithGlobalExclusiveLock( OperationContext* txn, const CallbackHandle& cbHandle) { boost::unique_lock<boost::mutex> lk(_mutex); if (_inShutdown) return; const WorkQueue::iterator iter = cbHandle._iter; const uint64_t generation = iter->generation; invariant(generation == cbHandle._generation); WorkItem work = *iter; iter->callback = CallbackFn(); _freeQueue.splice(_freeQueue.begin(), _exclusiveLockInProgressQueue, iter); lk.unlock(); { boost::lock_guard<boost::mutex> terribleLock(_terribleExLockSyncMutex); work.callback(CallbackData(this, cbHandle, (work.isCanceled ? Status(ErrorCodes::CallbackCanceled, "Callback canceled") : Status::OK()), txn)); } lk.lock(); signalEvent_inlock(work.finishedEvent); }
void WorkQueue_Impl::worker_main() { while (true) { int wakeup_reason = Event::wait(stop_event, work_available_event); if (wakeup_reason != 1) break; MutexSection mutex_lock(&mutex); if (!queued_items.empty()) { WorkItem *item = queued_items.front(); queued_items.erase(queued_items.begin()); mutex_lock.unlock(); item->process_work(); mutex_lock.lock(); finished_items.push_back(item); mutex_lock.unlock(); set_wakeup_event(); } else { work_available_event.reset(); } } }
QTime Job::avgRenderTime(int& days) { QTime sum,diff,midnight; QDateTime left,right; int tempDays,counter = 0,hour; //24*60*60*1000 = 86400000 const long MS_PER_DAY = 86400000; long daySeconds, timeSeconds; WorkItem* currentItem = finished.first(); days = 0; //traverse finished list while(currentItem) { left = currentItem->getFinish(); right = currentItem->getStart(); diff = left.time() - right.time(); //if the hours combine to more than 24 add a day hour = diff.hour() + sum.hour(); if(hour >= 24) days++; //add to sum sum = diff + sum; //find the days between start time and finish time tempDays = right.daysTo(left); //if the difference is greater than one day add the difference if(tempDays > 0) { days = days + tempDays - 1; if(diff >= midnight) days++; } currentItem = finished.next(); counter++; } //now calculate the average. //days must be converted into ms //sum must be converted into ms //the two must be added and devided by counter daySeconds = ((double)days/counter)*24*60*60*1000; timeSeconds = sum.hour()*60*60*1000 + sum.minute()*60*1000 + sum.second()*1000 + sum.msec(); if(counter > 0) timeSeconds = timeSeconds/counter + daySeconds; else timeSeconds = 0; midnight = midnight.addMSecs(timeSeconds%MS_PER_DAY); days = timeSeconds/MS_PER_DAY; return midnight; }
SOM_Scope short SOMLINK removeItem(Day *somSelf, Environment *ev, string start, string end, string desc) { DayData *somThis = DayGetData(somSelf); short i; WorkItem *item; DayMethodDebug("Day","removeItem"); for (i=0; i < sequenceLength(somThis->workList); i++ ) { item = sequenceElement(somThis->workList,i); if ( (strcmp(start, item->_get_startTime(ev)) == 0) && (strcmp(end, item->_get_endTime(ev)) == 0) && (strcmp(desc, item->_get_task(ev)) == 0) ) { sequenceLength(somThis->workList)--; for (i; i < sequenceLength(somThis->workList); i++) { sequenceElement(somThis->workList,i) = sequenceElement(somThis->workList, i+1); } somSelf->sompSetDirty(ev); return 0; } } return -1L; // item not found }
void ServerObject::jobFailed(const QString& str, QThread* thread) { Thread* thr = (Thread*)thread; WorkItem *nextItem; if (unpaused) { //jobs->renderFailed(((Thread*)thread)->getInfo()); uint jobid; nextItem = jobs->getItem(&jobid); // here is where we queue in the next job in the list if (nextItem) { emit finished(thr->getHost().append(" ").append(str)); thr->setJobId(jobid); thr->setJobName(nextItem->getJob()->getJobName()); thr->setInfo(nextItem); thr->start(); } else{ emit finished(thr->getHost().append(" ").append(str)); emit finished(tr("All jobs finished on ").append(thr->getHost())); } } else { emit finished(thr->getHost().append(" ").append("paused")); } }
inline F32 ThreadPool::WorkItemWrapper::getPriority() { WorkItem* item = ptr(); AssertFatal( item != 0, "ThreadPool::WorkItemWrapper::getPriority - called on dead item" ); // Compute a scaled priority value based on the item's context. return ( item->getContext()->getAccumulatedPriorityBias() * item->getPriority() ); }
static void Callback(PTP_CALLBACK_INSTANCE, PVOID state, PTP_WORK) { WorkItem* workItem = static_cast<WorkItem*>(state); workItem->callback_(); ::CloseThreadpoolWork(workItem->work_); workItem->selfReferenceSPtr_.reset(); }
inline bool ThreadPool::WorkItemWrapper::isAlive() { WorkItem* item = ptr(); if( !item ) return false; else if( item->isCancellationRequested() ) { ( *this ) = 0; return false; } else return true; }
WorkList::~WorkList() { // Delete any WorkItems in the queue: WorkItem* item; cci_debug_printf("%s", __FUNCTION__); char buf[2048]; char* pbuf = (char*)buf; while (remove(&item)) { cci_debug_printf("WorkList::~WorkList() deleting %s", item->print(pbuf)); delete item; } DeleteCriticalSection(&cs); }
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; }
EXTERN_C int worklist_remove(long* rpcmsg, ccs_pipe_t* pipe, k5_ipc_stream* stream, time_t* sst) { WorkItem* item = NULL; cc_int32 err = worklist.remove(&item); *rpcmsg = item->type(); *pipe = item->take_pipe(); *stream = item->take_payload(); *sst = item->sst(); delete item; return err; }
void* run() { // Remove 1 item at a time and process it. Blocks if no items are // available to process. for (int i = 0;; i++) { printf("thread %lu, loop %d - waiting for item...\n", (long unsigned int)self(), i); WorkItem* item = m_queue.remove(); printf("thread %lu, loop %d - got one item\n", (long unsigned int)self(), i); printf("thread %lu, loop %d - item: message - %s, number - %d\n", (long unsigned int)self(), i, item->getMessage(), item->getNumber()); delete item; } return NULL; }
Job::~Job() { WorkItem* tempItem; working.first(); while(!working.isEmpty()) { tempItem = working.take(); //set workitems job pointer to null tempItem->setParentJob(0); //put work items in a special list of WorkQueue class to be deleted //when they are finished. emit disown(tempItem); } }
void ThreadPool::IOThreadMain() { while (m_Running) { if (m_IOHasWork.Acquire(500)) { WorkItem itm; if (!m_IOWorkQueue.try_pop(itm)) { continue; } itm.pFunct(itm.pArg); } } }
std::shared_ptr<Artworks::ArtworkMetadata> SpellCheckWorker::processWorkItem(WorkItem &workItem) { std::shared_ptr<Artworks::ArtworkMetadata> result; if (workItem.isSeparator()) { emit queueIsEmpty(); } else { this->processSpellingQuery(workItem.m_Item); if (workItem.isMilestone()) { QThread::msleep(SPELLCHECK_WORKER_SLEEP_DELAY); } result = std::dynamic_pointer_cast<Artworks::ArtworkMetadata>(workItem.m_Item->getBasicModelSource()); } return result; }
bool Job::inList(Que* list, QString itemInfo) { if(list) { //traverse list from front WorkItem* listWalker = list->first(); while(listWalker) { //return true if ID matches if(listWalker->getFrameInfo() == itemInfo) return true; listWalker = list->next(); } } //did not find matching ID in list return false; }
DWORD WINAPI Pool::threadFunction(void* context) { DWORD currentThreadId = GetCurrentThreadId(); //работаем пока хотим, что поток жил или не убиваем его printf("Thread: %d\n", currentThreadId); fflush(stdin); Pool *pool = (Pool*)context; while(true) { //выходим из потока, если ему повелел killer EnterCriticalSection(&pool->killCriticalSection); if (pool->killThreads->at(currentThreadId) == true) { LeaveCriticalSection(&pool->killCriticalSection); break; } LeaveCriticalSection(&pool->killCriticalSection); printf("Work thread: %d wait on semaphore\n", currentThreadId); //ждЄм пока нет новой задачи WaitForSingleObject(pool->semaphoreFreeThread, INFINITE); printf("Work thread: %d now was work\n", currentThreadId); //отмечаем, что поток начнЄт работать EnterCriticalSection(&pool->timeLifeCriticalSection); pool->handlersAndTime->at(currentThreadId) = SIGN_THREAD_NOW_WORK; LeaveCriticalSection(&pool->timeLifeCriticalSection); //атомарно получаем работу и удал¤ем еЄ из очереди //чтобы несколько потоко не выполн¤ли одно и тоже EnterCriticalSection(&pool->worksCriticalSection); WorkItem work = pool->queueWorks->back(); pool->queueWorks->pop_back(); LeaveCriticalSection(&pool->worksCriticalSection); //работаем work.function(work.context); //врем¤ когда поток перестал работать EnterCriticalSection(&pool->timeLifeCriticalSection); DWORD currentTime = GetTickCount(); pool->handlersAndTime->at(currentThreadId) = currentTime; LeaveCriticalSection(&pool->timeLifeCriticalSection); } return 0; }
WorkItem::WorkItem(const WorkItem& item) : _buf(NULL), _rpcmsg(0), _pipe(NULL), _sst(0) { k5_ipc_stream _buf = NULL; krb5int_ipc_stream_new(&_buf); krb5int_ipc_stream_write(_buf, krb5int_ipc_stream_data(item.payload()), krb5int_ipc_stream_size(item.payload()) ); WorkItem(_buf, item._pipe, item._rpcmsg, item._sst); }
std::shared_ptr<void> TelemetryWorker::processWorkItem(WorkItem &workItem) { processOneItem(workItem.m_Item); if (workItem.isMilestone()) { // force context switch for more imporant tasks QThread::msleep(TELEMETRY_SLEEP_MILLIS); } return std::shared_ptr<void>(); }
void ServerObject::connected(const QString& str, const QThread* thr) { emit connectChange(str); Thread* thread = (Thread*)thr; WorkItem *nextItem; if (started) { thread->setReady(true); uint jobid; nextItem = jobs->getItem(&jobid); if (nextItem) { thread->setJobId(jobid); thread->setJobName(nextItem->getJob()->getJobName()); thread->setInfo(nextItem); thread->start(); } } else thread->setReady(true); }
WorkItem* Job::getWorkItem() { uint size = unassigned.count(); WorkItem* temp = 0; if(size > 0) { //set start time if first frame being dispatched if((working.count()==0) && (finished.count()==0)) setStart(); //move item to working queue temp = unassigned.take(0); temp->setStart(); working.append(temp); //let interface/scheduler know that status changed emit changed(this); } return temp; }
void WorkQueue_Impl::worker_main() { while (true) { std::unique_lock<std::mutex> mutex_lock(mutex); worker_event.wait(mutex_lock, [&]() { return stop_flag || !queued_items.empty(); }); if (stop_flag) break; WorkItem *item = queued_items.front(); queued_items.erase(queued_items.begin()); mutex_lock.unlock(); item->process_work(); mutex_lock.lock(); finished_items.push_back(item); mutex_lock.unlock(); } }
// Activates work items sitting in the queue void CEcmtSdkPlugin::FlushQueue(TBool aFinal) { // Lock the queue Emulator::Escape(); WaitForSingleObject(iMutex, INFINITE); Emulator::Reenter(); // Move queued callbacks to a temp queue TDblQue<WorkItem> q; while (!iQueue.IsEmpty()) { WorkItem* workItem = iQueue.Last(); workItem->Deque(); q.AddFirst(*workItem); } if (aFinal) { iRunner->Cancel(); } else { iRunner->iStatus = KRequestPending; iRunner->SetActive(); } ReleaseMutex(iMutex); // Invoke the callbacks while (!q.IsEmpty()) { WorkItem* w = q.First(); w->Deque(); TRACE2("[%08X] running work item %08X",this,w); if ((*w->iCallback != NULL) && (w->iArg1 != NULL)) { TRAPD(err,(*w->iCallback)(w->iArg1,w->iArg2,w->iArg3)); } if (w->iEvent) { TRACE2("[%08X] setting event for work item %08X",this,w); SetEvent(w->iEvent); } MemFree(w); } }
Job::Job(Job& clone) { priority = clone.priority; jobName = clone.jobName; fileName = clone.fileName; jobID = clone.jobID; start=clone.start; finish=clone.finish; WorkItem* tempOld; //deep copy unassigned QPtrList tempOld = clone.unassigned.first(); while(tempOld) { unassigned.append(new WorkItem(this,tempOld->getFrameInfo())); tempOld = clone.unassigned.next(); } //deep copy working QPtrList tempOld = clone.working.first(); while(tempOld) { working.append(new WorkItem(this,tempOld->getFrameInfo())); tempOld = clone.working.next(); } //deep copy finished QPtrList tempOld = clone.finished.first(); while(tempOld) { finished.append(new WorkItem(this,tempOld->getFrameInfo())); tempOld = clone.finished.next(); } finished.setAutoDelete(true); working.setAutoDelete(true); unassigned.setAutoDelete(true); }
void ThreadPool::wait() { while( true ) { numberLock_.lock(); if( numberOfFinishedWorkItems_ == numberOfAddedWorkItems_ ) { numberLock_.unlock(); return; } numberLock_.unlock(); WorkItem* workItem = pop(); if( workItem != nullptr ) { workItem->dig(); workerFinsihedJob(); delete workItem; } } }
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(); }
void* run() { // Remove 1 item at a time and process it. Blocks if no items are // available to process. for (int i = 0;; i++) { //qDebug("thread %lu, loop %d - waiting for item...", (long unsigned int)self(), i); WorkItem* item = m_queue.remove(); //qDebug("thread %lu, loop %d - got one item", (long unsigned int)self(), i); TCPStream* stream = item->getStream(); // Echo messages back the client until the connection is // closed char input[256]; for (int i = 0; i < 255; i++) { input[i] = '\0'; } string output; int len; while ((len = stream->receive(input, sizeof(input)-1)) > 0 ) { output = "OK"; stream->send(output.c_str(), (sizeof(output.c_str())-1)); //qDebug("thread %lu, echoed '%s' back to the client", (long unsigned int)self(), input); std::string cmd(input); executeCommand(cmd); } delete item; } // Should never get here return NULL; }