void threadRun( MessagingPort * inPort) { TicketHolderReleaser connTicketReleaser( &connTicketHolder ); setThreadName( "conn" ); assert( inPort ); inPort->setLogLevel(1); scoped_ptr<MessagingPort> p( inPort ); p->postFork(); string otherSide; Message m; try { LastError * le = new LastError(); lastError.reset( le ); // lastError now has ownership otherSide = p->remoteString(); handler->connected( p.get() ); while ( ! inShutdown() ) { m.reset(); p->clearCounters(); if ( ! p->recv(m) ) { if( !cmdLine.quiet ) log() << "end connection " << otherSide << endl; p->shutdown(); break; } handler->process( m , p.get() , le ); networkCounter.hit( p->getBytesIn() , p->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 ClockSkewException & ) { log() << "ClockSkewException - shutting down" << endl; exitCleanly( EXIT_CLOCK_SKEW ); } catch ( std::exception &e ) { error() << "Uncaught std::exception: " << e.what() << ", terminating" << endl; dbexit( EXIT_UNCAUGHT ); } catch ( ... ) { error() << "Uncaught exception, terminating" << endl; dbexit( EXIT_UNCAUGHT ); } handler->disconnected( p.get() ); }
void threadRun( MessagingPort * inPort) { TicketHolderReleaser connTicketReleaser( &connTicketHolder ); assert( inPort ); setThreadName( "conn" ); auto_ptr<MessagingPort> p( inPort ); string otherSide; Message m; try { otherSide = p->farEnd.toString(); while ( 1 ) { m.reset(); p->clearCounters(); if ( ! p->recv(m) ) { if( !cmdLine.quiet ) log() << "end connection " << otherSide << endl; p->shutdown(); break; } handler->process( m , p.get() ); networkCounter.hit( p->getBytesIn() , p->getBytesOut() ); } } catch ( const SocketException& ) { log() << "unclean socket shutdown from: " << otherSide << endl; } catch ( const std::exception& e ) { problem() << "uncaught exception (" << e.what() << ")(" << demangleName( typeid(e) ) <<") in PortMessageServer::threadRun, closing connection" << endl; } catch ( ... ) { problem() << "uncaught exception in PortMessageServer::threadRun, closing connection" << endl; } handler->disconnected( p.get() ); }
void threadRun( MessagingPort * inPort) { TicketHolderReleaser connTicketReleaser( &connTicketHolder ); setThreadName( "conn" ); verify( inPort ); inPort->psock->setLogLevel(1); scoped_ptr<MessagingPort> p( inPort ); p->psock->postFork(); string otherSide; Message m; try { LastError * le = new LastError(); lastError.reset( le ); // lastError now has ownership otherSide = p->psock->remoteString(); handler->connected( p.get() ); while ( ! inShutdown() ) { m.reset(); p->psock->clearCounters(); if ( ! p->recv(m) ) { if( !cmdLine.quiet ){ int conns = connTicketHolder.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 ); } handler->disconnected( p.get() ); }
/** * 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; }
/* we create one thread for each connection from an app server database. app server will open a pool of threads. todo: one day, asio... */ void connThread( MessagingPort * inPort ) { TicketHolderReleaser connTicketReleaser( &connTicketHolder ); /* todo: move to Client object */ LastError *le = new LastError(); lastError.reset(le); inPort->_logLevel = 1; auto_ptr<MessagingPort> dbMsgPort( inPort ); Client& c = Client::initThread("conn", inPort); try { c.getAuthenticationInfo()->isLocalHost = dbMsgPort->farEnd.isLocalHost(); Message m; while ( 1 ) { if ( !dbMsgPort->recv(m) ) { if( !cmdLine.quiet ) log() << "end connection " << dbMsgPort->farEnd.toString() << endl; dbMsgPort->shutdown(); break; } sendmore: if ( inShutdown() ) { log() << "got request after shutdown()" << endl; break; } lastError.startRequest( m , le ); DbResponse dbresponse; if ( !assembleResponse( m, dbresponse, dbMsgPort->farEnd ) ) { log() << curTimeMillis() % 10000 << " end msg " << dbMsgPort->farEnd.toString() << endl; /* todo: we may not wish to allow this, even on localhost: very low priv accounts could stop us. */ if ( dbMsgPort->farEnd.isLocalHost() ) { dbMsgPort->shutdown(); sleepmillis(50); problem() << "exiting end msg" << endl; dbexit(EXIT_CLEAN); } else { log() << " (not from localhost, ignoring end msg)" << endl; } } if ( dbresponse.response ) { dbMsgPort->reply(m, *dbresponse.response, dbresponse.responseTo); if( dbresponse.exhaust ) { MsgData *header = dbresponse.response->header(); QueryResult *qr = (QueryResult *) header; long long cursorid = qr->cursorId; if( cursorid ) { assert( dbresponse.exhaust && *dbresponse.exhaust != 0 ); string ns = dbresponse.exhaust; // before reset() free's it... m.reset(); BufBuilder b(512); b.appendNum((int) 0 /*size set later in appendData()*/); b.appendNum(header->id); b.appendNum(header->responseTo); b.appendNum((int) dbGetMore); b.appendNum((int) 0); b.appendStr(ns); b.appendNum((int) 0); // ntoreturn b.appendNum(cursorid); m.appendData(b.buf(), b.len()); b.decouple(); DEV log() << "exhaust=true sending more" << endl; beNice(); goto sendmore; } } } m.reset(); } } catch ( AssertionException& e ) { log() << "AssertionException in connThread, closing client connection" << endl; log() << ' ' << e.what() << endl; dbMsgPort->shutdown(); } catch ( SocketException& ) { problem() << "SocketException in connThread, closing client connection" << endl; dbMsgPort->shutdown(); } catch ( const ClockSkewException & ) { exitCleanly( EXIT_CLOCK_SKEW ); } catch ( std::exception &e ) { problem() << "Uncaught std::exception: " << e.what() << ", terminating" << endl; dbexit( EXIT_UNCAUGHT ); } catch ( ... ) { problem() << "Uncaught exception, terminating" << endl; dbexit( EXIT_UNCAUGHT ); } // thread ending... { Client * c = currentClient.get(); if( c ) c->shutdown(); } globalScriptEngine->threadDone(); }