pid_t pid = getpid();
int maxservers = 100;
int servernumber = 10;
int Instances = 0;
int startchild = 0;
int status;
ProxyHandler Proxy;
//Infinite Server Loop
for(;;)
{
//Clean proxyhandler zombies
while (waitpid(-1, &status, WNOHANG) > 0)
{
Instances--;
}
while ((startchild > 0) || (Instances < servernumber))
{
if ( (pid = fork()) < 0 ) //Fork Error
{
//Too many processes or out of memory?
LogFile::ErrorMessage("Could not fork proxychild: %s\n", strerror(errno));
//Lets hope the the causing error goes away soon
sleep(10);
}
else if ( pid == 0 ) //Child
{
//Install ProxyHandler Signals
if ( InstallSignal(1) < 0 )
{
LogFile::ErrorMessage("Error installing ProxyHandler signals\n");
sleep(10);
exit(1);
}
//Start processing requests
Proxy.Proxy( ProxyServer );
exit(1);
}
else //Parent
{
if ( startchild > 0 ) startchild--;
Instances++;
}
}
//Do we need more proxy-processes?
if ( Instances >= servernumber )
{
bool hangup = ProxyServer.CheckForData(0);
sleep(1);
if ( (hangup == true) && (Instances < maxservers) )
{
//Did a old process take care or is there still data? Create two if needed
if ( ProxyServer.CheckForData(0) )
{
if (LL>0) LogFile::ErrorMessage("All childs busy, spawning new (now: %d) - SERVERNUMBER might be too low\n", Instances+2);
startchild += 2;
}
}
}
} |
int InstallSignal( int level )
{
struct sigaction Signal;
memset(&Signal, 0, sizeof(Signal));
Signal.sa_flags = 0;
//Level 0 = Main CEV Process
//Level 1 = ProxyHandler Process
//Signals are inherited from previous level at forking..
if ( level == 0 ) //Main CEV Process
{
Signal.sa_handler = ExitProcess;
if (sigaction(SIGINT, &Signal, NULL) != 0) return -1;
if (sigaction(SIGTERM, &Signal, NULL) != 0) return -1;
Signal.sa_handler = RereadAll;
if (sigaction(SIGHUP, &Signal, NULL) != 0) return -1;
//Compatibility for 0.77 and older init-script
if (sigaction(SIGUSR2, &Signal, NULL) != 0) return -1;
Signal.sa_handler = ChildExited;
if (sigaction(SIGCHLD, &Signal, NULL) != 0) return -1;
Signal.sa_handler = SIG_IGN;
if (sigaction(SIGUSR1, &Signal, NULL) != 0) return -1;
if (sigaction(SIGPIPE, &Signal, NULL) != 0) return -1;
}
else if ( level == 1 ) //ProxyHandler Process
{
Signal.sa_handler = RestartChild;
if (sigaction(SIGUSR1, &Signal, NULL) != 0) return -1;
Signal.sa_handler = ChildChildExited;
if (sigaction(SIGCHLD, &Signal, NULL) != 0) return -1;
Signal.sa_handler = SIG_IGN;
if (sigaction(SIGHUP, &Signal, NULL) != 0) return -1;
if (sigaction(SIGUSR2, &Signal, NULL) != 0) return -1;
}
return 0;
} |