//------------------------------------------------- void ofThread::waitForThread(bool callStopThread, long milliseconds){ if(thread.isRunning()){ threadBeingWaitedFor = true; // tell thread to stop if(callStopThread){ stopThread(); ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - Signaled to stop."; } // wait for the thread to finish ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - waiting to stop"; if(isCurrentThread()){ ofLogWarning("ofThread") << "- name: " << getThreadName() << " - waitForThread should only be called from outside the this ofThread."; return; } if (INFINITE_JOIN_TIMEOUT == milliseconds){ thread.join(); }else{ // Wait for "joinWaitMillis" milliseconds for thread to finish if(!thread.tryJoin(milliseconds)){ ofLogError("ofThread") << "- name: " << getThreadName() << " - Unable to completely waitForThread."; } } } }
bool ServerThread::execute() { bool bRv(true); SHAREDPTR::shared_ptr<IFileDescriptorPattern> fp; m_pError= m_pConnect->accept(); if(!m_pError->hasError()) { fp= m_pConnect->getDescriptor(); m_pStarterPool->setNewClient(fp); } if(m_pError->fail()) { string msg; ostringstream decl; decl << getThreadName(); decl << "@" << m_pConnect->getHostAddress(); decl << "@" << m_pConnect->getPortAddress(); m_pError->addMessage("ServerThread", "accept", decl.str()); msg= m_pError->getDescription(); if(m_pError->hasError()) { cerr << glob::addPrefix("### ALERT: ", msg) << endl; LOG(LOG_ALERT, msg); bRv= false; }else { cout << glob::addPrefix("### WARNING: ", msg) << endl; TIMELOG(LOG_WARNING, getThreadName() + "@" + m_pConnect->getHostAddress(), msg); } } return bRv; }
//------------------------------------------------- void ofThread::unlock(){ mutex.unlock(); if(isCurrentThread()){ ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - ofThread unlocked its own mutex."; } else { ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - External thread unlocked the ofThread mutex."; } }
bool GenericSchedulerThread::abortThreadedTask(bool keepOldestRender) { if ( !isRunning() ) { return false; } ThreadStateEnum state = getThreadState(); bool shouldRequestAbort = state != eThreadStateAborted && state != eThreadStateIdle; if ( keepOldestRender && !shouldRequestAbort ) { return false; } { QMutexLocker l(&_imp->abortRequestedMutex); // We are already aborting if (_imp->abortRequested > 0 && keepOldestRender) { return false; } #ifdef TRACE_GENERIC_SCHEDULER_THREAD qDebug() << QThread::currentThread() << ": Aborting task on" << getThreadName().c_str(); #endif if (shouldRequestAbort) { ++_imp->abortRequested; } } onAbortRequested(keepOldestRender); return true; }
void ServiceContextMongoDTest::setUp() { Client::initThread(getThreadName()); auto const serviceContext = getServiceContext(); auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext); LogicalClock::set(serviceContext, std::move(logicalClock)); if (!serviceContext->getGlobalStorageEngine()) { // When using the "ephemeralForTest" storage engine, it is fine for the temporary directory // to go away after the global storage engine is initialized. unittest::TempDir tempDir("service_context_d_test_fixture"); storageGlobalParams.dbpath = tempDir.path(); storageGlobalParams.engine = "ephemeralForTest"; storageGlobalParams.engineSetByUser = true; checked_cast<ServiceContextMongoD*>(serviceContext)->createLockFile(); serviceContext->initializeGlobalStorageEngine(); serviceContext->setOpObserver(stdx::make_unique<OpObserverNoop>()); } // Set up UUID Catalog observer. This is necessary because the Collection destructor contains an // invariant to ensure the UUID corresponding to that Collection object is no longer associated // with that Collection object in the UUIDCatalog. UUIDs may be registered in the UUIDCatalog // directly in certain code paths, but they can only be removed from the UUIDCatalog via a // UUIDCatalogObserver. It is therefore necessary to install the observer to ensure the // invariant in the Collection destructor is not triggered. auto observerRegistry = stdx::make_unique<OpObserverRegistry>(); observerRegistry->addObserver(stdx::make_unique<UUIDCatalogObserver>()); serviceContext->setOpObserver(std::unique_ptr<OpObserver>(observerRegistry.release())); }
bool GenericSchedulerThread::startTask(const ThreadStartArgsPtr& inArgs) { { QMutexLocker quitLocker(&_imp->mustQuitMutex); if (!_imp->startingThreadAllowed || _imp->mustQuit) { return false; } } { QMutexLocker k1(&_imp->enqueuedTasksMutex); QMutexLocker k2(&_imp->abortRequestedMutex); #ifdef TRACE_GENERIC_SCHEDULER_THREAD qDebug() << QThread::currentThread() << ": Requesting task on" << getThreadName().c_str() << ", is thread aborted?" << (bool)(_imp->abortRequested > 0); #endif if (_imp->abortRequested > 0) { _imp->queuedTaskWhileProcessingAbort.push_back(inArgs); } else { _imp->enqueuedTasks.push_back(inArgs); } } if ( !isRunning() ) { start(); } else { ///Wake up the thread with a start request QMutexLocker locker(&_imp->startRequestsMutex); ++_imp->startRequests; _imp->startRequestsCond.wakeOne(); } return true; }
string getDistLockId() { string s = distLockIds.get(); if (s.empty()) { stringstream ss; ss << getDistLockProcess() << ":" << getThreadName() << ":" << rand(); s = ss.str(); distLockIds.set(s); } return s; }
KeyAnalysisThread::KeyAnalysisThread(SingleAudioFileForAnalysis* _fileToAnalyze, AudioFormatManager& _audioFormatManager) : Thread("Key Analysis Thread" + _fileToAnalyze->getFileName()), fileToAnalyze(_fileToAnalyze) //audioFormatManager(_audioFormatManager) { audioFormatReader = _audioFormatManager.createReaderFor(_fileToAnalyze->getFileToBeAnalyzed()); DBG("Creating thread: " << getThreadName()); interval = Random::getSystemRandom().nextInt(50) + 8; startThread(); }
//------------------------------------------------- void ofThread::startThread(bool mutexBlocks){ if(thread.isRunning()){ ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Cannot start, thread already running."; return; } _threadRunning = true; _mutexBlocks = mutexBlocks; thread.start(*this); }
void throw_error( const char* format, ... ){ char buf[2048] = {0}; va_list ap; va_start(ap, format); vsprintf(buf, format, ap); lockMutex(); if ( use_syslog ){ syslog(LOG_USER|LOG_ERR, "%s", buf ); }else{ if ( errno ) printf("%s %s: error type = %d, errno = %d(%s), error = %s\n", getThreadName(), getCurrentTime(), LOG_ERR, errno, strerror(errno), buf ); else printf("%s %s: error type = %d, error = %s\n", getThreadName(), getCurrentTime(), LOG_ERR, buf ); } unlockMutex(); //vsyslog(LOG_USER|err, format, ap ); va_end(ap); Exception ex(buf); throw ex; }
//------------------------------------------------- void ofThread::startThread(bool mutexBlocks){ std::unique_lock<std::mutex> lck(mutex); if(threadRunning || !threadDone){ ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Cannot start, thread already running."; return; } threadDone = false; threadRunning = true; this->mutexBlocks = mutexBlocks; thread = std::thread(std::bind(&ofThread::run,this)); }
void Logger::log(LogLevel lev, const std::string &text) { if (m_silenced_levels[lev]) return; const std::string thread_name = getThreadName(); const std::string label = getLevelLabel(lev); const std::string timestamp = getTimestamp(); std::ostringstream os(std::ios_base::binary); os << timestamp << ": " << label << "[" << thread_name << "]: " << text; logToOutputs(lev, os.str(), timestamp, thread_name, text); }
vector<string> getMyAddrs() { vector<string> out; ifaddrs * addrs; if (!serverGlobalParams.bind_ip.empty()) { boost::split(out, serverGlobalParams.bind_ip, boost::is_any_of(", ")); return out; } int status = getifaddrs(&addrs); massert(13469, "getifaddrs failure: " + errnoWithDescription(errno), status == 0); // based on example code from linux getifaddrs manpage for (ifaddrs * addr = addrs; addr != NULL; addr = addr->ifa_next) { if ( addr->ifa_addr == NULL ) continue; int family = addr->ifa_addr->sa_family; char host[NI_MAXHOST]; if (family == AF_INET || family == AF_INET6) { status = getnameinfo(addr->ifa_addr, (family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6)), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if ( status != 0 ) { freeifaddrs( addrs ); addrs = NULL; msgasserted( 13470, string("getnameinfo() failed: ") + gai_strerror(status) ); } out.push_back(host); } } freeifaddrs( addrs ); addrs = NULL; if (logger::globalLogDomain()->shouldLog(logger::LogSeverity::Debug(1))) { LogstreamBuilder builder(logger::globalLogDomain(), getThreadName(), logger::LogSeverity::Debug(1)); builder << "getMyAddrs():"; for (vector<string>::const_iterator it=out.begin(), end=out.end(); it!=end; ++it) { builder << " [" << *it << ']'; } builder << endl; } return out; }
//------------------------------------------------- void ofThread::run(){ ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - Started Thread."; #ifdef TARGET_ANDROID JNIEnv * env; jint attachResult = ofGetJavaVMPtr()->AttachCurrentThread(&env,NULL); #endif // user function // should loop endlessly. threadedFunction(); _threadRunning = false; #if !defined(TARGET_WIN32) && !defined(TARGET_ANDROID) // FIXME: this won't be needed once we update POCO https://github.com/pocoproject/poco/issues/79 if(!threadBeingWaitedFor){ //if threadedFunction() ended and the thread is not being waited for, detach it before exiting. pthread_detach(pthread_self()); } #endif #ifdef TARGET_ANDROID attachResult = ofGetJavaVMPtr()->DetachCurrentThread(); #endif ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - Thread Finished."; }
//------------------------------------------------- bool ofThread::lock(){ if(_mutexBlocks){ if(isCurrentThread()){ ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - ofThread waiting for its own mutex to be unlocked."; }else{ ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - External thread waiting for ofThread mutex to be unlocked"; } mutex.lock(); }else{ if(!mutex.tryLock()){ ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - Mutex is already locked, tryLock failed."; return false; } } if(isCurrentThread()){ ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - ofThread locked its own mutex."; }else{ ofLogVerbose("ofThread") << "- name: " << getThreadName() << " - External thread locked the ofThread mutex."; } return true; }
void log( const char* format, ... ){ if ( debug_off ) return; char buf[2048] = {0}; va_list ap; va_start(ap, format); vsprintf(buf, format, ap); lockMutex(); if ( use_syslog ) syslog(LOG_USER|LOG_INFO, "%s", buf ); else printf("%s %s: %s\n", getThreadName(), getCurrentTime(), buf ); unlockMutex(); //vsyslog(LOG_USER|err, format, ap ); va_end(ap); }
bool GenericSchedulerThread::quitThread(bool allowRestarts) { if ( !isRunning() ) { return false; } // Disallow temporarily any thread to request a new render so that we do not end up starting the thread again // just after the abort { QMutexLocker k(&_imp->mustQuitMutex); // We already called quitThread if (_imp->mustQuit || !_imp->lastQuitThreadAllowedRestart) { return true; } _imp->mustQuit = true; _imp->startingThreadAllowed = false; _imp->lastQuitThreadAllowedRestart = allowRestarts; } if (getThreadState() == eThreadStateActive) { abortThreadedTask(); } // Clear any task enqueued and push a fake request { QMutexLocker k(&_imp->enqueuedTasksMutex); _imp->enqueuedTasks.clear(); boost::shared_ptr<GenericThreadStartArgs> stubArgs( new GenericThreadStartArgs(true) ); _imp->enqueuedTasks.push_back(stubArgs); } // Wake-up the thread with a fake request { QMutexLocker l3(&_imp->startRequestsMutex); ++_imp->startRequests; _imp->startRequestsCond.wakeOne(); } #ifdef TRACE_GENERIC_SCHEDULER_THREAD qDebug() << QThread::currentThread() << ": Termination request on " << getThreadName().c_str(); #endif onQuitRequested(allowRestarts); return true; }
vector<string> getAllIPs(const string& iporhost) { addrinfo* addrs = NULL; addrinfo hints; memset(&hints, 0, sizeof(addrinfo)); hints.ai_socktype = SOCK_STREAM; hints.ai_family = (IPv6Enabled() ? AF_UNSPEC : AF_INET); static string portNum = BSONObjBuilder::numStr(serverGlobalParams.port); vector<string> out; int ret = getaddrinfo(iporhost.c_str(), portNum.c_str(), &hints, &addrs); if ( ret ) { warning() << "getaddrinfo(\"" << iporhost << "\") failed: " << gai_strerror(ret) << endl; return out; } for (addrinfo* addr = addrs; addr != NULL; addr = addr->ai_next) { int family = addr->ai_family; char host[NI_MAXHOST]; if (family == AF_INET || family == AF_INET6) { int status = getnameinfo(addr->ai_addr, addr->ai_addrlen, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); massert(13472, string("getnameinfo() failed: ") + gai_strerror(status), status == 0); out.push_back(host); } } freeaddrinfo(addrs); if (logger::globalLogDomain()->shouldLog(logger::LogSeverity::Debug(1))) { LogstreamBuilder builder(logger::globalLogDomain(), getThreadName(), logger::LogSeverity::Debug(1)); builder << "getallIPs(\"" << iporhost << "\"):"; for (vector<string>::const_iterator it=out.begin(), end=out.end(); it!=end; ++it) { builder << " [" << *it << ']'; } builder << endl; } return out; }
void ThreadStatus::logToQueryThreadLog(QueryThreadLog & thread_log) { QueryThreadLogElement elem; elem.event_time = time(nullptr); elem.query_start_time = query_start_time; elem.query_duration_ms = (getCurrentTimeNanoseconds() - query_start_time_nanoseconds) / 1000000U; elem.read_rows = progress_in.rows.load(std::memory_order_relaxed); elem.read_bytes = progress_in.bytes.load(std::memory_order_relaxed); elem.written_rows = progress_out.rows.load(std::memory_order_relaxed); elem.written_bytes = progress_out.bytes.load(std::memory_order_relaxed); elem.memory_usage = memory_tracker.get(); elem.peak_memory_usage = memory_tracker.getPeak(); elem.thread_name = getThreadName(); elem.thread_number = thread_number; elem.os_thread_id = os_thread_id; if (thread_group) { { std::lock_guard lock(thread_group->mutex); elem.master_thread_number = thread_group->master_thread_number; elem.master_os_thread_id = thread_group->master_thread_os_id; elem.query = thread_group->query; } } if (query_context) { elem.client_info = query_context->getClientInfo(); if (query_context->getSettingsRef().log_profile_events.value != 0) { /// NOTE: Here we are in the same thread, so we can make memcpy() elem.profile_counters = std::make_shared<ProfileEvents::Counters>(performance_counters.getPartiallyAtomicSnapshot()); } } thread_log.add(elem); }
static __attribute__((no_instrument_function)) void trace ( const char *state, void *this_fn, void *call_site ) { unsigned long now = getOffsetMsec(); const char *p = getProcName(); const char *t = getThreadName(); if ( firsttime ) { setup(); if ( fp != NULL ) { fprintf(fp,"!:state:process:thread:mSecTime:this_fn:call_site\n"); } } if ( fp != NULL ) { fprintf(fp,"@:%s:%s:%s" ":%lu:%08lx:%08lx\n", state,p,t, now,(unsigned long)this_fn,(unsigned long)call_site); fflush(fp); } }
void GlobalInfo::Functions::print::call(JSContext* cx, JS::CallArgs args) { logger::LogstreamBuilder builder(jsPrintLogDomain, getThreadName(), logger::LogSeverity::Log()); std::ostream& ss = builder.stream(); bool first = true; for (size_t i = 0; i < args.length(); i++) { if (first) first = false; else ss << " "; if (args.get(i).isNullOrUndefined()) { // failed to get object to convert ss << "[unknown type]"; continue; } JSStringWrapper jsstr(cx, JS::ToString(cx, args.get(i))); ss << jsstr.toStringData(); } ss << std::endl; args.rval().setUndefined(); }
//------------------------------------------------- void ofThread::startThread(bool mutexBlocks, bool verbose){ ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Calling startThread with verbose is deprecated."; startThread(mutexBlocks); }
ThreadClient::ThreadClient(ServiceContext* serviceContext) : ThreadClient(getThreadName(), serviceContext, nullptr) {}
//------------------------------------------------- void ofThread::threadedFunction(){ ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Override ofThread::threadedFunction() in your ofThread subclass."; }
void printThreadPinning() { pid_t pid = getpid(); #ifndef _WIN32 char dirname[1024]; sprintf(dirname, "/proc/%d/task", (int) pid); DIR* dp = opendir(dirname); if (dp) { dirent* ent; fprintf(STD_OUT, "%12s", ""); for (int i = 0;i < get_number_of_cpu_cores();i++) { fprintf(STD_OUT, " %2d", i); } fprintf(STD_OUT, "\n"); while ((ent = readdir(dp)) != NULL) { pid_t tid = atoi(ent->d_name); if (tid != 0) { fprintf(STD_OUT, "Thread %5d", tid); cpu_set_t threadmask; sched_getaffinity(tid, sizeof(threadmask), &threadmask); for (int i = 0;i < get_number_of_cpu_cores();i++) { if (CPU_ISSET(i, &threadmask)) { fprintf(STD_OUT, " X"); } else { fprintf(STD_OUT, " ."); } } fprintf(STD_OUT, " - "); const char* name = getThreadName(tid); fprintf(STD_OUT, "%s", name); if (CPU_COUNT(&threadmask) == 1) { for (int i = 0;i < get_number_of_cpu_cores();i++) { if (CPU_ISSET(i, &threadmask)) fprintf(STD_OUT, " - Pinned to core %d", i); } } char filename[1024]; sprintf(filename, "/proc/%d/task/%d/stat", (int) pid, (int) tid); FILE* fp = fopen(filename, "r"); if (fp != NULL) { char buffer[1024]; if (fgets(buffer, 1023, fp) == NULL) break; int count = 0; for (unsigned int i = 0;i < strlen(buffer);i++) { if (buffer[i] == ' ') { if (++count == 13) { int time; sscanf(&buffer[i + 1], "%d ", &time); fprintf(STD_OUT, " - Time: %d", time); break; } } } fclose(fp); } fprintf(STD_OUT, "\n"); } } closedir(dp); } #endif }
void Logstream::flush(Tee *t) { const size_t MAX_LOG_LINE = 1024 * 10; // this ensures things are sane if ( doneSetup == 1717 ) { string msg = ss.str(); string threadName = getThreadName(); const char * type = logLevelToString(logLevel); size_t msgLen = msg.size(); if ( msgLen > MAX_LOG_LINE ) msgLen = MAX_LOG_LINE; const int spaceNeeded = (int)( msgLen + 64 /* for extra info */ + threadName.size()); int bufSize = 128; while ( bufSize < spaceNeeded ) bufSize += 128; BufBuilder b(bufSize); char* dateStr = b.grow(24); curTimeString(dateStr); dateStr[23] = ' '; // change null char to space if (!threadName.empty()) { b.appendChar( '[' ); b.appendStr( threadName , false ); b.appendChar( ']' ); b.appendChar( ' ' ); } for ( int i=0; i<indent; i++ ) b.appendChar( '\t' ); if ( type[0] ) { b.appendStr( type , false ); b.appendStr( ": " , false ); } if ( msg.size() > MAX_LOG_LINE ) { stringstream sss; sss << "warning: log line attempted (" << msg.size() / 1024 << "k) over max size(" << MAX_LOG_LINE / 1024 << "k)"; sss << ", printing beginning and end ... "; b.appendStr( sss.str(), false ); const char * xx = msg.c_str(); b.appendBuf( xx , MAX_LOG_LINE / 3 ); b.appendStr( " .......... ", false ); b.appendStr( xx + msg.size() - ( MAX_LOG_LINE / 3 ) ); } else { b.appendStr( msg ); } string out( b.buf() , b.len() - 1); verify( b.len() < spaceNeeded ); scoped_lock lk(mutex); if( t ) t->write(logLevel,out); if ( globalTees ) { for ( unsigned i=0; i<globalTees->size(); i++ ) (*globalTees)[i]->write(logLevel,out); } #if defined(_WIN32) int fd = fileno( logfile ); if ( _isatty( fd ) ) { fflush( logfile ); writeUtf8ToWindowsConsole( out.data(), out.size() ); } #else if ( isSyslog ) { syslog( logLevelToSysLogLevel(logLevel) , "%s" , out.data() ); } #endif else if ( fwrite( out.data(), out.size(), 1, logfile ) ) { fflush(logfile); } else { int x = errno; cout << "Failed to write to logfile: " << errnoWithDescription(x) << ": " << out << endl; } #ifdef POSIX_FADV_DONTNEED // This only applies to pages that have already been flushed RARELY posix_fadvise(fileno(logfile), 0, 0, POSIX_FADV_DONTNEED); #endif } _init(); }
StatusWith<DistLockManager::ScopedDistLock> ReplSetDistLockManager::lock( StringData name, StringData whyMessage, milliseconds waitFor, milliseconds lockTryInterval) { Timer timer(_serviceContext->getTickSource()); Timer msgTimer(_serviceContext->getTickSource()); while (waitFor <= milliseconds::zero() || milliseconds(timer.millis()) < waitFor) { OID lockSessionID = OID::gen(); string who = str::stream() << _processID << ":" << getThreadName(); auto lockExpiration = _lockExpiration; MONGO_FAIL_POINT_BLOCK(setDistLockTimeout, customTimeout) { const BSONObj& data = customTimeout.getData(); lockExpiration = stdx::chrono::milliseconds(data["timeoutMs"].numberInt()); } LOG(1) << "trying to acquire new distributed lock for " << name << " ( lock timeout : " << durationCount<Milliseconds>(lockExpiration) << " ms, ping interval : " << durationCount<Milliseconds>(_pingInterval) << " ms, process : " << _processID << " )" << " with lockSessionID: " << lockSessionID << ", why: " << whyMessage; auto lockResult = _catalog->grabLock(name, lockSessionID, who, _processID, Date_t::now(), whyMessage); auto status = lockResult.getStatus(); if (status.isOK()) { // Lock is acquired since findAndModify was able to successfully modify // the lock document. LOG(0) << "distributed lock '" << name << "' acquired, ts : " << lockSessionID; return ScopedDistLock(lockSessionID, this); } if (status != ErrorCodes::LockStateChangeFailed) { // An error occurred but the write might have actually been applied on the // other side. Schedule an unlock to clean it up just in case. queueUnlock(lockSessionID); return status; } // Get info from current lock and check if we can overtake it. auto getLockStatusResult = _catalog->getLockByName(name); const auto& getLockStatus = getLockStatusResult.getStatus(); if (!getLockStatusResult.isOK() && getLockStatus != ErrorCodes::LockNotFound) { return getLockStatus; } // Note: Only attempt to overtake locks that actually exists. If lock was not // found, use the normal grab lock path to acquire it. if (getLockStatusResult.isOK()) { auto currentLock = getLockStatusResult.getValue(); auto canOvertakeResult = canOvertakeLock(currentLock, lockExpiration); if (!canOvertakeResult.isOK()) { return canOvertakeResult.getStatus(); } if (canOvertakeResult.getValue()) { auto overtakeResult = _catalog->overtakeLock(name, lockSessionID, currentLock.getLockID(), who, _processID, Date_t::now(), whyMessage); const auto& overtakeStatus = overtakeResult.getStatus(); if (overtakeResult.isOK()) { // Lock is acquired since findAndModify was able to successfully modify // the lock document. LOG(0) << "lock '" << name << "' successfully forced"; LOG(0) << "distributed lock '" << name << "' acquired, ts : " << lockSessionID; return ScopedDistLock(lockSessionID, this); } if (overtakeStatus != ErrorCodes::LockStateChangeFailed) { // An error occurred but the write might have actually been applied on the // other side. Schedule an unlock to clean it up just in case. queueUnlock(lockSessionID); return overtakeStatus; } } } LOG(1) << "distributed lock '" << name << "' was not acquired."; if (waitFor == milliseconds::zero()) { break; } // Periodically message for debugging reasons if (msgTimer.seconds() > 10) { LOG(0) << "waited " << timer.seconds() << "s for distributed lock " << name << " for " << whyMessage; msgTimer.reset(); } milliseconds timeRemaining = std::max(milliseconds::zero(), waitFor - milliseconds(timer.millis())); sleepFor(std::min(lockTryInterval, timeRemaining)); } return {ErrorCodes::LockBusy, str::stream() << "timed out waiting for " << name}; }
string ServerThread::getName() const { return getThreadName(); }
Optional<std::string> getCurrentThreadName() { return getThreadName(std::this_thread::get_id()); }
void GenericSchedulerThread::run() { for (;; ) { // Get the args to do the work ThreadStartArgsPtr args; TaskQueueBehaviorEnum behavior = tasksQueueBehaviour(); { QMutexLocker k(&_imp->enqueuedTasksMutex); switch (behavior) { case eTaskQueueBehaviorProcessInOrder: { if ( !_imp->enqueuedTasks.empty() ) { args = _imp->enqueuedTasks.front(); _imp->enqueuedTasks.pop_front(); } break; } case eTaskQueueBehaviorSkipToMostRecent: { if ( !_imp->enqueuedTasks.empty() ) { args = _imp->enqueuedTasks.back(); _imp->enqueuedTasks.clear(); } break; } } } ThreadStateEnum state = eThreadStateActive; { _imp->setThreadState(eThreadStateActive); Q_EMIT stateChanged( (int)state ); } if ( args && !args->isNull() ) { // Do the work! state = threadLoopOnce(args); } // The implementation might call resolveState from threadLoopOnce. If not, it will return eThreadStateActive by default so make // sure resolveState was called at least once if (state == eThreadStateActive) { // Returns eThreadStateActive if the thread was not aborted, otherwise returns eThreadStateAborted if aborted or eThreadStateStopped // if we must stop state = _imp->resolveState(); } // Handle abort and termination requests // If the thread has not been aborted, put it asleep if (state == eThreadStateActive) { state = eThreadStateIdle; } _imp->setThreadState(state); Q_EMIT stateChanged( (int)state ); if (state == eThreadStateStopped) { // The thread is now stopped #ifdef TRACE_GENERIC_SCHEDULER_THREAD qDebug() << getThreadName().c_str() << ": Quitting thread"; #endif QMutexLocker k(&_imp->mustQuitMutex); _imp->mustQuit = false; _imp->mustQuitCond.wakeAll(); return; } // Reset the abort requested flag: // If a thread A called abortThreadedTask() multiple times and the scheduler thread B was running in the meantime, it could very well // stop and wait in the startRequestsCond { QMutexLocker tasksLocker(&_imp->enqueuedTasksMutex); QMutexLocker k(&_imp->abortRequestedMutex); if (state == eThreadStateAborted) { // If the processing was aborted, clear task that were requested prior to the abort flag was passed, and insert the task that were posted // after the abort was requested up until now #ifdef TRACE_GENERIC_SCHEDULER_THREAD qDebug() << getThreadName().c_str() << ": Thread going idle after being aborted. " << _imp->queuedTaskWhileProcessingAbort.size() << "tasks were pushed while abort being processed."; #endif if (behavior == eTaskQueueBehaviorProcessInOrder) { _imp->enqueuedTasks.clear(); } _imp->enqueuedTasks.insert( _imp->enqueuedTasks.end(), _imp->queuedTaskWhileProcessingAbort.begin(), _imp->queuedTaskWhileProcessingAbort.end() ); _imp->queuedTaskWhileProcessingAbort.clear(); } else { #ifdef TRACE_GENERIC_SCHEDULER_THREAD qDebug() << getThreadName().c_str() << ": Thread going idle normally."; #endif } if (_imp->abortRequested > 0) { _imp->abortRequested = 0; _imp->abortRequestedCond.wakeAll(); } } { QMutexLocker l(&_imp->startRequestsMutex); while (_imp->startRequests <= 0) { _imp->startRequestsCond.wait(&_imp->startRequestsMutex); } ///We got the request if (_imp->startRequests > 0) { --_imp->startRequests; } #ifdef TRACE_GENERIC_SCHEDULER_THREAD qDebug() << getThreadName().c_str() << ": Received start request, startRequest = " << _imp->startRequests; #endif } } // for (;;) } // run()