#ifdef SCOUT
#include <scout/types.h>
#else /* SCOUT */
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#endif /* SCOUT */

#include "toba.h"
#include "java_lang_ProcessReaper.h"
#include "java_lang_UNIXProcess.h"

/* java/lang/ProcessReaper waitForDeath ()V */
Void waitForDeath__jgUPj(Object Harg1)
/*ARGSUSED*/
{
#ifdef SCOUT
    /* Don't do anything---scout doesn't grok processes */
#else /* SCOUT */
    pid_t pid;
    int status;

    /* 
     * this daemon process continually loops
     * waiting for children to die
     */
    for(;;) {
        if((pid = waitpid(-1, &status, 0)) == -1) {
            if(errno == EINTR) {
                continue;
            } else if (errno == ECHILD) {
		Object h = cl_java_lang_UNIXProcess.V.subprocs;
		struct mythread *mt = mythread();
		int monitor_held;

		/* We're the last child. We can't zero out the 
		 * hashtable in UNIXProcess, the preferred solution, because 
		 * Sun didn't make access to the table ref synchronized. 
		 * Instead, we wait on the hashtable, and have the native 
		 * UNIXProcess.fork() notify the hashtable. */
		monitorenter(h, mt, 1, &monitor_held);
		monitorwait(h, 0);
		monitorexit(h, mt, 0, &monitor_held);
		continue;
            } else {
		perror("java.lang.ProcessReaper(waitpid)");
                break;
            }
        }
        if(WIFEXITED(status)) {
            /* UNIXProcess.deadChild(int,int) */
            deadChild_ii_s5Vsh(pid, WEXITSTATUS(status));
        }
        if(WIFSIGNALED(status)) {
            /* UNIXProcess.deadChild(int,int) */
            deadChild_ii_s5Vsh(pid, -1);
        }
    }
#endif /* SCOUT */
    return;
}

