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; }
/** * 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; }
/** * 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; }