void Thread::ExitCurrent() { // no point creating a ScopedCritical; it would never be destroyed anarch::SetCritical(true); // since this thread is already running, it must be retained Thread * th = GetCurrent(); th->Kill(); // the scheduler will never be able to retain this thread again, so this will // be the last line of code ever run on this thread th->GetTask().GetScheduler().Yield(); __builtin_unreachable(); }
void PrePostProcessor::WaitJobs() { debug("PrePostProcessor: waiting for jobs to complete"); // wait 5 seconds until all post-processing jobs gracefully finish time_t waitStart = Util::CurrentTime(); while (Util::CurrentTime() < waitStart + 5) { { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); if (m_activeJobs.empty()) { break; } } CheckPostQueue(); usleep(200 * 1000); } // kill remaining post-processing jobs; not safe but we can't wait any longer { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* postJob : m_activeJobs) { if (postJob->GetPostInfo() && postJob->GetPostInfo()->GetPostThread()) { Thread* thread = postJob->GetPostInfo()->GetPostThread(); postJob->GetPostInfo()->SetPostThread(nullptr); warn("Terminating active post-process job for %s", postJob->GetName()); thread->Kill(); delete thread; } } } // wait 5 seconds until direct unpack threads gracefully finish waitStart = Util::CurrentTime(); while (Util::CurrentTime() < waitStart + 5) { { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); if (std::find_if(downloadQueue->GetQueue()->begin(), downloadQueue->GetQueue()->end(), [](const std::unique_ptr<NzbInfo>& nzbInfo) { return nzbInfo->GetUnpackThread() != nullptr; }) == downloadQueue->GetQueue()->end()) { break; } } usleep(200 * 1000); } // disconnect remaining direct unpack jobs { GuardedDownloadQueue downloadQueue = DownloadQueue::Guard(); for (NzbInfo* nzbInfo : downloadQueue->GetQueue()) { nzbInfo->SetUnpackThread(nullptr); } } debug("PrePostProcessor: Jobs are completed"); }
/*! Kill timer thread. \param sig signal to kill with */ void kill(const int sig=SIGKILL) { _thread.Kill(sig); }