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