/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1990-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Research
*
* wait for and return status of job or the next coshell job that completes
* job==co for non-blocking wait
*/
#include "colib.h"
#include <ctype.h>
/*
* cat and remove fd {1,2} serialized output
*/
static void
{
{
}
else
*path = 0;
}
/*
* the number of running+zombie jobs
* these would count against --jobs or NPROC
*/
int
{
int any;
int n;
if (co)
any = 0;
return -1;
else
any = 1;
n = 0;
do
{
n += co->outstanding;
return n;
}
/*
* the number of pending cowait()'s
*/
int
{
int any;
int n;
if (co)
any = 0;
return -1;
else
any = 1;
n = 0;
do
{
return n;
}
/*
* the number of completed jobs not cowait()'d for
* cowait() always reaps the zombies first
*/
int
{
int any;
int n;
if (co)
any = 0;
return -1;
else
any = 1;
n = 0;
do
{
return n;
}
{
register char* s;
register ssize_t n;
char* b;
char* e;
unsigned long user;
unsigned long sys;
int active;
int any;
int id;
int loop;
int to;
int type;
static unsigned long serial = 0;
serial++;
any = 0;
goto echild;
else
any = 1;
/*
* first drain the zombies
*/
active = 0;
do
{
#if 0
errormsg(state.lib, 2, "coshell %d zombie wait %lu timeout=%d outstanding=<%d,%d> running=<%d,%d>", co->index, serial, timeout, co->outstanding, co->svc_outstanding, co->running, co->svc_running);
#endif
{
co->svc_outstanding--;
else
co->outstanding--;
#if 0
errormsg(state.lib, 2, "coshell %d zombie wait %lu timeout=%d outstanding=<%d,%d> running=<%d,%d> reap job %d", co->index, serial, timeout, co->outstanding, co->svc_outstanding, co->running, co->svc_running, cj->id);
#endif
return cj;
}
{
co->svc_running--;
}
active = 1;
else if (co->svc_running > 0)
{
n = 0;
{
n = 1;
}
if (n)
goto zombies;
active = 1;
}
/*
* reap the active jobs
*/
if (!active)
goto echild;
if (any)
do
{
loop = 0;
for (;;)
{
{
loop++;
errormsg(state.lib, 2, "coshell %d wait %lu.%d timeout=%d outstanding=<%d,%d> running=<%d,%d>", co->index, serial, loop, timeout, co->outstanding, co->svc_outstanding, co->running, co->svc_running);
}
break;
{
if (n < 0)
{
return 0;
break;
}
if (timeout >= 0)
break;
/*
* check for a killed job with no status
*/
{
n = sfsprintf(buf, sizeof(buf), "kill -0 %d 2>/dev/null || echo k %d `wait %d 2>/dev/null; echo $?` >&$%s\n", cj->pid, cj->id, cj->pid, CO_ENV_MSGFD);
break;
}
}
/*
* get one coshell message
*/
break;
#if 0
errormsg(state.lib, 2, "coshell %d active wait %lu timeout=%d outstanding=<%d,%d> running=<%d,%d>", co->index, serial, timeout, co->outstanding, co->svc_outstanding, co->running, co->svc_running);
#endif
/*
* read and parse a coshell message packet of the form
*
* <type> <id> <args> <newline>
* %c %d %s %c
*/
while (isspace(*s))
s++;
goto invalid;
while (*++s && !isspace(*s));
if (*e && !isspace(*e))
goto invalid;
for (s = e; isspace(*s); s++);
/*
* locate id in the job list
*/
break;
if (!cj)
{
if (type == 'k')
continue;
return 0;
}
/*
* now interpret the message
*/
switch (type)
{
case 'a':
/*
* coexec() ack
*/
return cj;
break;
case 'j':
/*
* <s> is the job pid
*/
if (n == CO_PID_WARPED)
goto nuke;
break;
case 'k':
/*
* <s> is a synthesized killed status
*/
continue;
/*FALLTHROUGH*/
case 'x':
/*
* <s> is the job exit code and user,sys times
*/
for (;;)
{
if (e <= s)
break;
if (e <= s)
break;
}
{
nuke:
{
/*
* nuke the zombies
*/
}
co->svc_running--;
else
{
co->svc_outstanding--;
else
co->outstanding--;
#if 0
errormsg(state.lib, 2, "coshell %d active wait %lu timeout=%d outstanding=<%d,%d> running=<%d,%d> reap job %d", co->index, serial, timeout, co->outstanding, co->svc_outstanding, co->running, co->svc_running, cj->id);
#endif
return cj;
}
}
else
break;
}
}
return 0;
#if 0
#endif
return 0;
return 0;
}