Back to index

wims  3.65+svn20090927
fork.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018               /* fork management */
00019 
00020 #define MAX_FORK 1024
00021 #define MAX_DELAY 1500      /* At most these seconds of execution */
00022 
00023 struct {
00024     pid_t pid;
00025     time_t t;
00026     int type;
00027     int pad;
00028 } forklist[MAX_FORK];
00029 int forkcnt;
00030 
00031 void addfork(pid_t pid, int type)
00032 {
00033     if(forkcnt>=MAX_FORK) {
00034        kill(pid,SIGKILL); return;
00035     }
00036     forklist[forkcnt].pid=pid;
00037     forklist[forkcnt].t=time(NULL);
00038     forklist[forkcnt].type=type;
00039     forkcnt++;
00040 }
00041 
00042        /* forklist management */
00043 void forkman(int kz) 
00044 {
00045     int delay, i, t, st;
00046     time_t now;
00047     delay=MAX_DELAY; 
00048     if(forkcnt>=MAX_FORK/2) delay=delay/5;
00049     if(forkcnt*4>=MAX_FORK*3) delay=delay/4;
00050     now=time(NULL);
00051     for(i=forkcnt-1; i>=0; i--) {
00052        if(now-forklist[i].t>delay) kill(forklist[i].pid,SIGKILL);
00053        t=waitpid(forklist[i].pid,&st,WNOHANG);
00054        if(t==0 || !WIFEXITED(st)) continue;
00055        memmove(forklist+i,forklist+i+1,forkcnt-1-i);
00056        forkcnt--;
00057     }
00058     if(kz) waitpid(-1,NULL,WNOHANG); /* kill zombies */
00059 }
00060 
00061 void wait_children(void)
00062 {
00063     time_t now;
00064     int i;
00065     do {
00066        now=time(NULL);
00067        for(i=0; i<forkcnt; i++) {
00068            if(forklist[i].type && forklist[i].t < now-MAX_DELAY) break;          
00069        }
00070        if(i>=forkcnt) return;
00071        sleep(1);
00072     }
00073     while(1);
00074 }
00075