extern "C" int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) { int retval = 0; struct timespec sleepTime = {0, 1000}; siginfo_t siginfop; memset(&siginfop, 0, sizeof(siginfop)); /* waitid returns 0 in case of success as well as when WNOHANG is specified * and we need to distinguish those two cases.man page for waitid says: * If WNOHANG was specified in options and there were no children in a * waitable state, then waitid() returns 0 immediately and the state of * the siginfo_t structure pointed to by infop is unspecified. To * distinguish this case from that where a child was in a waitable state, * zero out the si_pid field before the call and check for a nonzero value * in this field after the call returns. * * See comments above wait4() */ while (retval == 0) { DMTCP_PLUGIN_DISABLE_CKPT(); pid_t currPid = VIRTUAL_TO_REAL_PID (id); retval = _real_waitid (idtype, currPid, &siginfop, options | WNOHANG); if (retval != -1) { pid_t virtualPid = REAL_TO_VIRTUAL_PID ( siginfop.si_pid ); siginfop.si_pid = virtualPid; if ( siginfop.si_code == CLD_EXITED || siginfop.si_code == CLD_KILLED ) dmtcp::VirtualPidTable::instance().erase(virtualPid); } DMTCP_PLUGIN_ENABLE_CKPT(); if ((options & WNOHANG) || retval == -1 || siginfop.si_pid != 0) { break; } else { if (sleepTime.tv_sec == 0) { sleepTime.tv_nsec *= 2; if (sleepTime.tv_nsec >= 1000 * 1000 * 1000) { sleepTime.tv_sec++; sleepTime.tv_nsec = 0; } } nanosleep(&sleepTime, NULL); } } if (retval == 0 && infop != NULL) { *infop = siginfop; } return retval; }
extern "C" int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) { siginfo_t siginfop; memset(&siginfop, 0, sizeof(siginfop)); int retval = _real_waitid (idtype, id, &siginfop, options); if (retval != -1) { if ( siginfop.si_code == CLD_EXITED || siginfop.si_code == CLD_KILLED ) dmtcp::ProcessInfo::instance().eraseChild ( siginfop.si_pid ); } if (retval == 0 && infop != NULL) { *infop = siginfop; } return retval; }