Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

try to restart the server if a child dies

  • Loading branch information...
commit 57361db5d8a243ba28421e38d2e43c0d7c78e203 1 parent 5df09ba
@arnt arnt authored Abhijit Menon-Sen committed
Showing with 52 additions and 27 deletions.
  1. +52 −27 server/server.cpp
View
79 server/server.cpp
@@ -22,6 +22,9 @@
#include <stdio.h>
// sigaction, sigemptyset
#include <signal.h>
+// waitpid()
+#include <sys/types.h>
+#include <sys/wait.h>
// our own includes, _after_ the system header files. lots of system
// header files break if we've already defined UINT_MAX, etc.
@@ -403,39 +406,61 @@ void Server::fork()
} else if ( p > 0 ) {
exit( 0 );
}
+
d->mainProcess = true;
- uint children = 0;
- if ( d->name == "archiveopteryx" ) {
+ d->children = new List<pid_t>;
+ uint children = 1;
+ if ( d->name == "archiveopteryx" )
children = Configuration::scalar( Configuration::ServerProcesses );
- if ( children > 1 )
- d->children = new List<pid_t>;
+ uint i = 0;
+ while ( i < children ) {
+ d->children->append( new pid_t( 0 ) );
+ i++;
}
- uint i = 1;
- while ( d->children && i < children ) {
- pid_t * child = new pid_t;
- *child = ::fork();
- if ( *child < 0 ) {
- log( "Unable to fork server; pressing on. Error code " +
- fn( errno ), Log::Error );
- }
- else if ( *child > 0 ) {
- log( "Process " + fn( getpid() ) + " forked " + fn( *child ) );
- d->children->append( child );
+ while ( d->mainProcess ) {
+ List<pid_t>::Iterator c( d->children );
+ while ( c ) {
+ if ( *c ) {
+ int r = ::kill( *c, 0 );
+ if ( r < 0 && errno == ESRCH )
+ *c = 0;
+ }
+ ++c;
}
- else {
- d->mainProcess = false;
- d->children = 0;
- EventLoop::global()->closeAllExceptListeners();
- log( "Process " + fn( getpid() ) + " started" );
- if ( Configuration::toggle( Configuration::UseStatistics ) ) {
- uint port
- = Configuration::scalar( Configuration::StatisticsPort );
- log( "Using port " + fn( port + i ) +
- " for statistics queries" );
- Configuration::add( "statistics-port = " + fn( port + i ) );
+ c = d->children->first();
+ uint i = 0;
+ while ( c && d->mainProcess ) {
+ if ( !*c ) {
+ *c = ::fork();
+ if ( *c < 0 ) {
+ log( "Unable to fork server; pressing on. Error code " +
+ fn( errno ), Log::Error );
+ *c = 0;
+ }
+ else if ( *c > 0 ) {
+ // the parent, all is well
+ }
+ else {
+ // a child. fork() must return.
+ d->mainProcess = false;
+ }
}
+ ++i;
+ ++c;
}
- i++;
+ int status = 0;
+ ::waitpid( -1, &status, 0 );
+ }
+
+ // only a child gets this far
+ d->children = 0;
+ EventLoop::global()->closeAllExceptListeners();
+ log( "Process " + fn( getpid() ) + " started" );
+ if ( Configuration::toggle( Configuration::UseStatistics ) ) {
+ uint port = Configuration::scalar( Configuration::StatisticsPort );
+ log( "Using port " + fn( port + i - 1 ) +
+ " for statistics queries" );
+ Configuration::add( "statistics-port = " + fn( port + i - 1 ) );
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.