static int try_kill_one() { /* Only need to check if a timeout was specified with the -l option. */ if ( globs.timeout > 0 ) { int i; for ( i = 0; i < globs.jobs; ++i ) if ( cmdtab[ i ].pi.hProcess ) { double const t = running_time( cmdtab[ i ].pi.hProcess ); if ( t > (double)globs.timeout ) { /* The job may have left an alert dialog around, try and get * rid of it before killing the job itself. */ close_alert( &cmdtab[ i ].pi ); /* We have a "runaway" job, kill it. */ kill_process_tree( cmdtab[ i ].pi.dwProcessId, cmdtab[ i ].pi.hProcess ); /* And return its running commands table slot. */ return i; } } } return -1; }
static int try_kill_one() { /* Only need to check if a timeout was specified with the -l option. */ if ( globs.timeout > 0 ) { int i; for ( i = 0; i < globs.jobs; ++i ) { double t = running_time( cmdtab[ i ].pi.hProcess ); if ( t > (double)globs.timeout ) { /* The job may have left an alert dialog around, try and get rid * of it before killing */ close_alert( cmdtab[ i ].pi.hProcess ); /* We have a "runaway" job, kill it. */ kill_process_tree( 0, cmdtab[ i ].pi.hProcess ); /* And return it marked as a timeout. */ cmdtab[ i ].exit_reason = EXIT_TIMEOUT; return i; } } } return -1; }
static void close_alerts() { /* We only attempt this every 5 seconds, or so, because it is not a cheap * operation, and we will catch the alerts eventually. This check uses * floats as some compilers define CLOCKS_PER_SEC as a float or double. */ if ( ( (float)clock() / (float)( CLOCKS_PER_SEC * 5 ) ) < ( 1.0 / 5.0 ) ) { int i; for ( i = 0; i < globs.jobs; ++i ) close_alert( cmdtab[ i ].pi.hProcess ); } }
static int my_wait( int *status ) { int i, num_active = 0; DWORD exitcode, waitcode; HANDLE active_handles[MAXJOBS]; /* first see if any non-waited-for processes are dead, * and return if so. */ for ( i = 0; i < globs.jobs; i++ ) { int pid = cmdtab[i].pid; if ( pid ) { process_state state = check_process_exit((HANDLE)pid, status, active_handles, &num_active); if ( state == process_error ) goto FAILED; else if ( state == process_finished ) return pid; } } /* if a child exists, wait for it to die */ if ( !num_active ) { errno = ECHILD; return -1; } if ( globs.timeout > 0 ) { unsigned int alert_wait = 1; /* with a timeout we wait for a finish or a timeout, we check every second to see if something timed out */ for (waitcode = WAIT_TIMEOUT; waitcode == WAIT_TIMEOUT; ++alert_wait) { waitcode = WaitForMultipleObjects( num_active, active_handles, FALSE, 1*1000 /* 1 second */ ); if ( waitcode == WAIT_TIMEOUT ) { /* check if any jobs have surpassed the maximum run time. */ for ( i = 0; i < num_active; ++i ) { double t = running_time(active_handles[i]); /* periodically (each 5 secs) check and close message boxes displayed by any of our child processes */ if ((alert_wait % ((unsigned int) 5)) == 0) close_alert(active_handles[i]); if ( t > (double)globs.timeout ) { /* the job may have left an alert dialog around, try and get rid of it before killing */ close_alert(active_handles[i]); /* we have a "runaway" job, kill it */ kill_all(0,active_handles[i]); /* indicate the job "finished" so we query its status below */ waitcode = WAIT_ABANDONED_0+i; } } } } } else { /* no timeout, so just wait indefinately for something to finish */ waitcode = WaitForMultipleObjects( num_active, active_handles, FALSE, INFINITE ); } if ( waitcode != WAIT_FAILED ) { if ( waitcode >= WAIT_ABANDONED_0 && waitcode < WAIT_ABANDONED_0 + num_active ) i = waitcode - WAIT_ABANDONED_0; else i = waitcode - WAIT_OBJECT_0; if ( check_process_exit(active_handles[i], status, 0, 0) == process_finished ) return (int)active_handles[i]; } FAILED: errno = GetLastError(); return -1; }