Esempio n. 1
0
//-------------------------------------------------
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.";
            }
        }
    }
}
Esempio n. 2
0
	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;
	}
Esempio n. 3
0
//-------------------------------------------------
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;
}
Esempio n. 5
0
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();
}
Esempio n. 9
0
//-------------------------------------------------
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);
}
Esempio n. 10
0
        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;
        }
Esempio n. 11
0
//-------------------------------------------------
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));
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
    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;
    }
Esempio n. 14
0
//-------------------------------------------------
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.";
}
Esempio n. 15
0
//-------------------------------------------------
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;
}
Esempio n. 16
0
        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);
        }
Esempio n. 17
0
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;
}
Esempio n. 18
0
    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;
    }
Esempio n. 19
0
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);
}
Esempio n. 20
0
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);
    }
}
Esempio n. 21
0
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();
}
Esempio n. 22
0
//-------------------------------------------------
void ofThread::startThread(bool mutexBlocks, bool verbose){
    ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Calling startThread with verbose is deprecated.";
    startThread(mutexBlocks);
}
Esempio n. 23
0
ThreadClient::ThreadClient(ServiceContext* serviceContext)
    : ThreadClient(getThreadName(), serviceContext, nullptr) {}
Esempio n. 24
0
//-------------------------------------------------
void ofThread::threadedFunction(){
	ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Override ofThread::threadedFunction() in your ofThread subclass.";
}
Esempio n. 25
0
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
}
Esempio n. 26
0
    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};
}
Esempio n. 28
0
	string ServerThread::getName() const
	{
		return getThreadName();
	}
Esempio n. 29
0
Optional<std::string> getCurrentThreadName() {
  return getThreadName(std::this_thread::get_id());
}
Esempio n. 30
0
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()