Esempio n. 1
0
    void BackgroundJob::jobBody() {

        const string threadName = name();
        if (!threadName.empty()) {
            setThreadName(threadName.c_str());
        }

        LOG(1) << "BackgroundJob starting: " << threadName << endl;

        try {
            run();
        }
        catch (const std::exception& e) {
            error() << "backgroundjob " << threadName << " exception: " << e.what();
            throw;
        }

        // We must cache this value so that we can use it after we leave the following scope.
        const bool selfDelete = _selfDelete;

#ifdef MONGO_CONFIG_SSL
        // TODO(sverch): Allow people who use the BackgroundJob to also specify cleanup tasks.
        // Currently the networking code depends on this class and this class depends on the
        // networking code because of this ad hoc cleanup.
        SSLManagerInterface* manager = getSSLManager();
        if (manager)
            manager->cleanupThreadLocals();
#endif

        {
            // It is illegal to access any state owned by this BackgroundJob after leaving this
            // scope, with the exception of the call to 'delete this' below.
            std::unique_lock<std::mutex> l( _status->mutex );
            _status->state = Done;
            _status->done.notify_all();
        }

        if( selfDelete )
            delete this;
    }
Esempio n. 2
0
        /**
         * Handles incoming messages from a given socket.
         *
         * Terminating conditions:
         * 1. Assertions while handling the request.
         * 2. Socket is closed.
         * 3. Server is shutting down (based on inShutdown)
         *
         * @param arg this method is in charge of cleaning up the arg object.
         *
         * @return NULL
         */
        static void* handleIncomingMsg(void* arg) {
            TicketHolderReleaser connTicketReleaser( &Listener::globalTicketHolder );

            scoped_ptr<HandleIncomingMsgParam> himArg(static_cast<HandleIncomingMsgParam*>(arg));
            MessagingPort* inPort = himArg->inPort;
            MessageHandler* handler = himArg->handler;

            {
                string threadName = "conn";
                if ( inPort->connectionId() > 0 )
                    threadName = str::stream() << threadName << inPort->connectionId();
                setThreadName( threadName.c_str() );
            }

            verify( inPort );
            inPort->psock->setLogLevel(1);
            scoped_ptr<MessagingPort> p( inPort );

            string otherSide;

            Message m;
            try {
                LastError * le = new LastError();
                lastError.reset( le ); // lastError now has ownership

                otherSide = p->psock->remoteString();

#ifdef MONGO_SSL
                std::string x509SubjectName = p->psock->doSSLHandshake();
                inPort->setX509SubjectName(x509SubjectName);
#endif 
                handler->connected( p.get() );

                while ( ! inShutdown() ) {
                    m.reset();
                    p->psock->clearCounters();

                    if ( ! p->recv(m) ) {
                        if( !cmdLine.quiet ){
                            int conns = Listener::globalTicketHolder.used()-1;
                            const char* word = (conns == 1 ? " connection" : " connections");
                            log() << "end connection " << otherSide << " (" << conns << word << " now open)" << endl;
                        }
                        p->shutdown();
                        break;
                    }

                    handler->process( m , p.get() , le );
                    networkCounter.hit( p->psock->getBytesIn() , p->psock->getBytesOut() );
                }
            }
            catch ( AssertionException& e ) {
                log() << "AssertionException handling request, closing client connection: " << e << endl;
                p->shutdown();
            }
            catch ( SocketException& e ) {
                log() << "SocketException handling request, closing client connection: " << e << endl;
                p->shutdown();
            }
            catch ( const DBException& e ) { // must be right above std::exception to avoid catching subclasses
                log() << "DBException handling request, closing client connection: " << e << endl;
                p->shutdown();
            }
            catch ( std::exception &e ) {
                error() << "Uncaught std::exception: " << e.what() << ", terminating" << endl;
                dbexit( EXIT_UNCAUGHT );
            }
            catch ( ... ) {
                error() << "Uncaught exception, terminating" << endl;
                dbexit( EXIT_UNCAUGHT );
            }

            // Normal disconnect path.
#ifdef MONGO_SSL
            SSLManagerInterface* manager = getSSLManager();
            if (manager)
                manager->cleanupThreadLocals();
#endif
            handler->disconnected( p.get() );

            return NULL;
        }
Esempio n. 3
0
        /**
         * Handles incoming messages from a given socket.
         *
         * Terminating conditions:
         * 1. Assertions while handling the request.
         * 2. Socket is closed.
         * 3. Server is shutting down (based on inShutdown)
         *
         * @param arg this method is in charge of cleaning up the arg object.
         *
         * @return NULL
         */
        static void* handleIncomingMsg(void* arg) {
            TicketHolderReleaser connTicketReleaser( &Listener::globalTicketHolder );

            invariant(arg);
            scoped_ptr<MessagingPortWithHandler> portWithHandler(
                static_cast<MessagingPortWithHandler*>(arg));
            MessageHandler* const handler = portWithHandler->getHandler();

            setThreadName(std::string(str::stream() << "conn" << portWithHandler->connectionId()));
            portWithHandler->psock->setLogLevel(logger::LogSeverity::Debug(1));

            Message m;
            int64_t counter = 0;
            try {
                LastError * le = new LastError();
                lastError.reset( le ); // lastError now has ownership

                handler->connected(portWithHandler.get());

                while ( ! inShutdown() ) {
                    m.reset();
                    portWithHandler->psock->clearCounters();

                    if (!portWithHandler->recv(m)) {
                        if (!serverGlobalParams.quiet) {
                            int conns = Listener::globalTicketHolder.used()-1;
                            const char* word = (conns == 1 ? " connection" : " connections");
                            log() << "end connection " << portWithHandler->psock->remoteString()
                                  << " (" << conns << word << " now open)" << endl;
                        }
                        portWithHandler->shutdown();
                        break;
                    }

                    handler->process(m, portWithHandler.get(), le);
                    networkCounter.hit(portWithHandler->psock->getBytesIn(),
                                       portWithHandler->psock->getBytesOut());

                    // Occasionally we want to see if we're using too much memory.
                    if ((counter++ & 0xf) == 0) {
                        markThreadIdle();
                    }
                }
            }
            catch ( AssertionException& e ) {
                log() << "AssertionException handling request, closing client connection: " << e << endl;
                portWithHandler->shutdown();
            }
            catch ( SocketException& e ) {
                log() << "SocketException handling request, closing client connection: " << e << endl;
                portWithHandler->shutdown();
            }
            catch ( const DBException& e ) { // must be right above std::exception to avoid catching subclasses
                log() << "DBException handling request, closing client connection: " << e << endl;
                portWithHandler->shutdown();
            }
            catch ( std::exception &e ) {
                error() << "Uncaught std::exception: " << e.what() << ", terminating" << endl;
                dbexit( EXIT_UNCAUGHT );
            }

            // Normal disconnect path.
#ifdef MONGO_SSL
            SSLManagerInterface* manager = getSSLManager();
            if (manager)
                manager->cleanupThreadLocals();
#endif
            handler->disconnected(portWithHandler.get());

            return NULL;
        }