0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

Close listener sockets on exit

This commit is contained in:
Aaron 2009-04-01 12:26:31 -04:00
parent d39de1e407
commit ed35b0874c
10 changed files with 56 additions and 13 deletions

View File

@ -134,7 +134,10 @@ namespace mongo {
OurListener l(port);
startReplication();
boost::thread thr(webServerThread);
l.listen();
if ( l.init() ) {
registerListenerSocket( l.socket() );
l.listen();
}
}
class JniMessagingPort : public AbstractMessagingPort {

View File

@ -254,7 +254,7 @@ namespace mongo {
string dbname;
{
stringstream z;
z << "mongodb " << getHostName() << ':' << port << ' ';
z << "mongodb " << getHostName() << ':' << mongo::port << ' ';
dbname = z.str();
}
ss << dbname << "</title></head><body><h2>" << dbname << "</h2><p>\n<pre>";
@ -447,6 +447,7 @@ namespace mongo {
DbWebServer mini;
int p = port + 1000;
if ( mini.init(p) ) {
registerListenerSocket( mini.socket() );
log() << "web admin interface listening on port " << p << '\n';
mini.run();
}

View File

@ -610,6 +610,13 @@ namespace mongo {
void recCacheCloseAll();
boost::mutex &listenerSocketMutex( *( new boost::mutex ) );
vector< int > listenerSockets;
void registerListenerSocket( int socket ) {
boostlock lk( listenerSocketMutex );
listenerSockets.push_back( socket );
}
boost::mutex &exitMutex( *( new boost::mutex ) );
bool firstExit = true;
@ -629,7 +636,16 @@ namespace mongo {
stringstream ss;
ss << "dbexit: " << why << endl;
rawOut( ss.str() );
{
// close listener sockets
// We would only hang here if a synchronous signal is received
// during a registerListenerSocket() call, which we don't expect.
boostlock lk( listenerSocketMutex );
for( vector< int >::iterator i = listenerSockets.begin(); i != listenerSockets.end(); ++i )
close( *i );
}
stringstream ss2;
flushOpLog( ss2 );
rawOut( ss2.str() );

View File

@ -97,7 +97,9 @@ namespace mongo {
void receivedQuery(DbResponse& dbresponse, /*AbstractMessagingPort& dbMsgPort, */Message& m, stringstream& ss, bool logit);
void getDatabaseNames( vector< string > &names );
// must call with db lock
void registerListenerSocket( int socket );
// --- local client ---
class DBDirectClient : public DBClientBase {

View File

@ -21,6 +21,7 @@
9302D9A00F30AB8C00DFA4EF /* ShellUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShellUtils.h; sourceTree = "<group>"; };
9302D9A20F30AB8C00DFA4EF /* utils.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = utils.js; sourceTree = "<group>"; };
931183420F8277FD00A6DC44 /* repl7.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = repl7.js; sourceTree = "<group>"; };
931184DC0F83C95800A6DC44 /* message_server_port.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = message_server_port.cpp; sourceTree = "<group>"; };
931A027A0F58AA4400147C0E /* jsobjmanipulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = jsobjmanipulator.h; sourceTree = "<group>"; };
93278F570F72D32900844664 /* gridfs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gridfs.cpp; sourceTree = "<group>"; };
93278F580F72D32900844664 /* gridfs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gridfs.h; sourceTree = "<group>"; };
@ -453,6 +454,7 @@
934DD87B0EFAD23B00459CC1 /* util */ = {
isa = PBXGroup;
children = (
931184DC0F83C95800A6DC44 /* message_server_port.cpp */,
936B89590F4C899400934AF2 /* file.h */,
936B895A0F4C899400934AF2 /* md5.c */,
936B895B0F4C899400934AF2 /* md5.h */,

View File

@ -40,12 +40,12 @@ namespace mongo {
/* listener ------------------------------------------------------------------- */
void Listener::listen() {
bool Listener::init() {
SockAddr me(port);
int sock = socket(AF_INET, SOCK_STREAM, 0);
sock = ::socket(AF_INET, SOCK_STREAM, 0);
if ( sock == INVALID_SOCKET ) {
log() << "ERROR: listen(): invalid socket? " << errno << endl;
return;
return false;
}
prebindOptions( sock );
if ( ::bind(sock, (sockaddr *) &me.sa, me.addressSize) != 0 ) {
@ -53,19 +53,27 @@ namespace mongo {
if ( errno == 98 )
log() << "98 == addr already in use" << endl;
closesocket(sock);
return;
return false;
}
if ( ::listen(sock, 128) != 0 ) {
log() << "listen(): listen() failed " << errno << endl;
closesocket(sock);
return;
return false;
}
return true;
}
void Listener::listen() {
SockAddr from;
while ( 1 ) {
int s = accept(sock, (sockaddr *) &from.sa, &from.addressSize);
if ( s < 0 ) {
if ( errno == ECONNABORTED ) {
log() << "Listener on port " << port << " aborted" << endl;
return;
}
log() << "Listener: accept() returns " << s << " errno:" << errno << endl;
continue;
}

View File

@ -32,12 +32,15 @@ namespace mongo {
public:
Listener(int p) : port(p) { }
virtual ~Listener() {}
bool init(); // set up socket
int socket() const { return sock; }
void listen(); // never returns (start a thread)
/* spawn a thread, etc., then return */
virtual void accepted(MessagingPort *mp) = 0;
private:
int port;
int sock;
};
class AbstractMessagingPort {

View File

@ -59,6 +59,7 @@ namespace mongo {
}
void run(){
assert( init() );
listen();
}

View File

@ -28,9 +28,10 @@ namespace mongo {
sock = 0;
}
bool MiniWebServer::init(int port) {
bool MiniWebServer::init(int _port) {
port = _port;
SockAddr me(port);
sock = socket(AF_INET, SOCK_STREAM, 0);
sock = ::socket(AF_INET, SOCK_STREAM, 0);
if ( sock == INVALID_SOCKET ) {
log() << "ERROR: MiniWebServer listen(): invalid socket? " << errno << endl;
return false;
@ -191,6 +192,10 @@ namespace mongo {
while ( 1 ) {
int s = accept(sock, (sockaddr *) &from.sa, &from.addressSize);
if ( s < 0 ) {
if ( errno == ECONNABORTED ) {
log() << "Listener on port " << port << " aborted." << endl;
return;
}
log() << "MiniWebServer: accept() returns " << s << " errno:" << errno << endl;
sleepmillis(200);
continue;

View File

@ -27,7 +27,7 @@ namespace mongo {
MiniWebServer();
virtual ~MiniWebServer() {}
bool init(int port);
bool init(int _port);
void run();
virtual void doRequest(
@ -39,7 +39,8 @@ namespace mongo {
vector<string>& headers // if completely empty, content-type: text/html will be added
) = 0;
int socket() const { return sock; }
protected:
string parseURL( const char * buf );
string parseMethod( const char * headers );
@ -51,6 +52,7 @@ namespace mongo {
void accepted(int s);
static bool fullReceive( const char *buf );
int port;
int sock;
};