[R-gregmisc-users] SF.net SVN: r-gregmisc: [1053] trunk/fork
Brought to you by:
warnes
From: <wa...@us...> - 2007-02-14 22:49:26
|
Revision: 1053 http://svn.sourceforge.net/r-gregmisc/?rev=1053&view=rev Author: warnes Date: 2007-02-14 14:48:47 -0800 (Wed, 14 Feb 2007) Log Message: ----------- Add code to install SIGCHLD handler to avoid forked children from becoming zombies Added Paths: ----------- trunk/fork/src/sigchld_handler.c trunk/fork/tests/ trunk/fork/tests/test_many_fork.R Added: trunk/fork/src/sigchld_handler.c =================================================================== --- trunk/fork/src/sigchld_handler.c (rev 0) +++ trunk/fork/src/sigchld_handler.c 2007-02-14 22:48:47 UTC (rev 1053) @@ -0,0 +1,73 @@ +#include <R.h> +#include <Rdefines.h> + +/* + Code taken from a posting to the Gimp-developer mailing list by + Raphael Quinet quinet at gamers.org accessible at: + http://lists.xcf.berkeley.edu/lists/gimp-developer/2000-November/013572.html +*/ + +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +int installed=0; // Has our sigcld signal hander already been installed? + +struct sigaction sa ; // our sigcld signal handler +struct sigaction osa; // original (R) signal hander + +void sigchld_hander(int dummy) +{ + int st; + while (wait3(&st, WNOHANG, NULL) > 0); +} + + +void R_install_sigcld_handler() +{ + int ret; + + if(installed==0) + { + Rprintf ("Installing SIGCHLD signal handler..."); + //sa.sa_handler = sigchld_handler; + sa.sa_handler = waiter; + //sigfillset (&sa.sa_mask); + //sa.sa_flags = SA_RESTART; + ret = sigaction (SIGCHLD, &sa, &osa); + if (ret < 0) + { + error("Cannot set signal handler"); + } + installed=-1; + Rprintf("Done.\n"); + } + else + { + warning("SIGCLD signal handler already installed"); + } + +} + +void R_restore_sigcld_handler() +{ + int ret; + + if(installed==-1) + { + Rprintf ("Restoring original SIGCHLD signal handler..."); + ret = sigaction (SIGCHLD, &osa, &sa); + if (ret < 0) + { + error("Cannot reset signal handler"); + } + installed=0; + Rprintf("Done.\n"); + } + else + { + warning("SIGCLD signal handler not installed: cannot reset."); + } + +} Added: trunk/fork/tests/test_many_fork.R =================================================================== --- trunk/fork/tests/test_many_fork.R (rev 0) +++ trunk/fork/tests/test_many_fork.R 2007-02-14 22:48:47 UTC (rev 1053) @@ -0,0 +1,20 @@ +library(fork) + +# ignore sigchld signals so child processes will die cleanly +#signal("SIGCHLD","ignore") + +# start signal handler +.C("R_install_sigcld_handler") + +for(i in 1:100) + { + pid = fork(slave=NULL) + if(pid==0) { + cat("Hi from the child process\n"); exit() + } else { + cat("Hi from the parent process\n"); + } + } + +# remove signal handler +.C("R_restore_sigcld_handler") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |