mirror of
https://github.com/boostorg/build.git
synced 2026-02-13 12:22:17 +00:00
Boost Jam code cleanup - internal execunix.c refactoring.
[SVN r79118]
This commit is contained in:
@@ -64,7 +64,6 @@ static int get_free_cmdtab_slot();
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
static clock_t tps;
|
||||
static int select_timeout;
|
||||
static int old_time_initialized;
|
||||
static struct tms old_time;
|
||||
|
||||
@@ -196,7 +195,7 @@ void exec_cmd
|
||||
cmdtab[ slot ].start_time = times( &buf );
|
||||
|
||||
/* Make a global, only do this once. */
|
||||
if ( tps == 0 ) tps = sysconf( _SC_CLK_TCK );
|
||||
if ( !tps ) tps = sysconf( _SC_CLK_TCK );
|
||||
}
|
||||
|
||||
/* Child does not need the read pipe ends used by the parent. */
|
||||
@@ -356,48 +355,35 @@ static void close_streams( int const i, int const s )
|
||||
}
|
||||
|
||||
|
||||
static void populate_file_descriptors( int * const fmax, fd_set * const fds )
|
||||
/*
|
||||
* Populate the file descriptors collection for use in select() and return the
|
||||
* maximal included file descriptor value.
|
||||
*/
|
||||
|
||||
static int populate_file_descriptors( fd_set * const fds )
|
||||
{
|
||||
int i;
|
||||
int fd_max = 0;
|
||||
struct tms buf;
|
||||
clock_t current = times( &buf );
|
||||
select_timeout = globs.timeout;
|
||||
|
||||
/* Compute max read file descriptor for use in select. */
|
||||
FD_ZERO( fds );
|
||||
for ( i = 0; i < globs.jobs; ++i )
|
||||
{
|
||||
if ( 0 < cmdtab[ i ].fd[ OUT ] )
|
||||
int fd;
|
||||
if ( ( fd = cmdtab[ i ].fd[ OUT ] ) > 0 )
|
||||
{
|
||||
if ( fd_max < cmdtab[ i ].fd[ OUT ] )
|
||||
fd_max = cmdtab[ i ].fd[ OUT ];
|
||||
FD_SET( cmdtab[ i ].fd[ OUT ], fds );
|
||||
if ( fd > fd_max ) fd_max = fd;
|
||||
FD_SET( fd, fds );
|
||||
}
|
||||
if ( globs.pipe_action )
|
||||
{
|
||||
if ( 0 < cmdtab[ i ].fd[ ERR ] )
|
||||
if ( ( fd = cmdtab[ i ].fd[ ERR ] ) > 0 )
|
||||
{
|
||||
if ( fd_max < cmdtab[ i ].fd[ ERR ] )
|
||||
fd_max = cmdtab[ i ].fd[ ERR ];
|
||||
FD_SET( cmdtab[ i ].fd[ ERR ], fds );
|
||||
}
|
||||
}
|
||||
|
||||
if ( globs.timeout && cmdtab[ i ].pid )
|
||||
{
|
||||
clock_t consumed = ( current - cmdtab[ i ].start_time ) / tps;
|
||||
clock_t process_timesout = globs.timeout - consumed;
|
||||
if ( 0 < process_timesout && process_timesout < select_timeout )
|
||||
select_timeout = process_timesout;
|
||||
if ( globs.timeout <= consumed )
|
||||
{
|
||||
killpg( cmdtab[ i ].pid, SIGKILL );
|
||||
cmdtab[ i ].exit_reason = EXIT_TIMEOUT;
|
||||
if ( fd > fd_max ) fd_max = fd;
|
||||
FD_SET( fd, fds );
|
||||
}
|
||||
}
|
||||
}
|
||||
*fmax = fd_max;
|
||||
return fd_max;
|
||||
}
|
||||
|
||||
|
||||
@@ -410,54 +396,81 @@ static void populate_file_descriptors( int * const fmax, fd_set * const fds )
|
||||
|
||||
void exec_wait()
|
||||
{
|
||||
int fd_max;
|
||||
int finished = 0;
|
||||
fd_set fds;
|
||||
|
||||
/* Process children that signaled. */
|
||||
while ( !finished )
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
struct timeval tv;
|
||||
struct timeval * ptv = NULL;
|
||||
int select_timeout = globs.timeout;
|
||||
|
||||
/* Compute max read file descriptor for use in select(). */
|
||||
populate_file_descriptors( &fd_max, &fds );
|
||||
/* Prepare file descriptor information for use in select(). */
|
||||
fd_set fds;
|
||||
int const fd_max = populate_file_descriptors( &fds );
|
||||
|
||||
/* Force select() to timeout so we can terminate expired processes. */
|
||||
if ( 0 < globs.timeout )
|
||||
/* Check for timeouts:
|
||||
* - kill children that already timed out
|
||||
* - decide how long until the next one times out
|
||||
*/
|
||||
if ( globs.timeout > 0 )
|
||||
{
|
||||
struct tms buf;
|
||||
clock_t const current = times( &buf );
|
||||
for ( i = 0; i < globs.jobs; ++i )
|
||||
if ( cmdtab[ i ].pid )
|
||||
{
|
||||
clock_t const consumed =
|
||||
( current - cmdtab[ i ].start_time ) / tps;
|
||||
if ( consumed >= globs.timeout )
|
||||
{
|
||||
killpg( cmdtab[ i ].pid, SIGKILL );
|
||||
cmdtab[ i ].exit_reason = EXIT_TIMEOUT;
|
||||
}
|
||||
else if ( globs.timeout - consumed < select_timeout )
|
||||
select_timeout = globs.timeout - consumed;
|
||||
}
|
||||
|
||||
/* If nothing else causes our select() call to exit, force it after
|
||||
* however long it takes for the next one of our child processes to
|
||||
* crossed its alloted processing time so we can terminate it.
|
||||
*/
|
||||
tv.tv_sec = select_timeout;
|
||||
tv.tv_usec = 0;
|
||||
ptv = &tv;
|
||||
}
|
||||
|
||||
/* select() will wait for I/O on a descriptor, a signal, or timeout. */
|
||||
while ( ( ret = select( fd_max + 1, &fds, 0, 0, ptv ) ) == -1 )
|
||||
if ( errno != EINTR )
|
||||
break;
|
||||
if ( ret <= 0 )
|
||||
continue;
|
||||
{
|
||||
int ret;
|
||||
while ( ( ret = select( fd_max + 1, &fds, 0, 0, ptv ) ) == -1 )
|
||||
if ( errno != EINTR )
|
||||
break;
|
||||
if ( ret <= 0 )
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( i = 0; i < globs.jobs; ++i )
|
||||
{
|
||||
int out = 0;
|
||||
int err = 0;
|
||||
int out_done = 0;
|
||||
int err_done = 0;
|
||||
if ( FD_ISSET( cmdtab[ i ].fd[ OUT ], &fds ) )
|
||||
out = read_descriptor( i, OUT );
|
||||
out_done = read_descriptor( i, OUT );
|
||||
|
||||
if ( globs.pipe_action && FD_ISSET( cmdtab[ i ].fd[ ERR ], &fds ) )
|
||||
err = read_descriptor( i, ERR );
|
||||
err_done = read_descriptor( i, ERR );
|
||||
|
||||
/* If feof on either descriptor, we are done. */
|
||||
if ( out || err )
|
||||
if ( out_done || err_done )
|
||||
{
|
||||
int pid;
|
||||
int status;
|
||||
int rstat;
|
||||
timing_info time_info;
|
||||
struct tms new_time;
|
||||
|
||||
/* We found a terminated child process - our search is done. */
|
||||
finished = 1;
|
||||
|
||||
/* Close the stream and pipe descriptors. */
|
||||
close_streams( i, OUT );
|
||||
@@ -468,28 +481,29 @@ void exec_wait()
|
||||
while ( ( pid = waitpid( cmdtab[ i ].pid, &status, 0 ) ) == -1 )
|
||||
if ( errno != EINTR )
|
||||
break;
|
||||
|
||||
if ( pid != cmdtab[ i ].pid )
|
||||
{
|
||||
printf( "unknown pid %d with errno = %d\n", pid, errno );
|
||||
exit( EXITBAD );
|
||||
}
|
||||
|
||||
finished = 1;
|
||||
cmdtab[ i ].pid = 0;
|
||||
|
||||
/* Set reason for exit if not timed out. */
|
||||
if ( WIFEXITED( status ) )
|
||||
cmdtab[ i ].exit_reason = WEXITSTATUS( status )
|
||||
? EXIT_FAIL
|
||||
: EXIT_OK;
|
||||
|
||||
times( &new_time );
|
||||
time_info.system = (double)( new_time.tms_cstime - old_time.tms_cstime ) / CLOCKS_PER_SEC;
|
||||
time_info.user = (double)( new_time.tms_cutime - old_time.tms_cutime ) / CLOCKS_PER_SEC;
|
||||
time_info.start = cmdtab[ i ].start_dt;
|
||||
time_info.end = time( 0 );
|
||||
old_time = new_time;
|
||||
{
|
||||
struct tms new_time;
|
||||
times( &new_time );
|
||||
time_info.system = (double)( new_time.tms_cstime -
|
||||
old_time.tms_cstime ) / CLOCKS_PER_SEC;
|
||||
time_info.user = (double)( new_time.tms_cutime -
|
||||
old_time.tms_cutime ) / CLOCKS_PER_SEC;
|
||||
time_info.start = cmdtab[ i ].start_dt;
|
||||
time_info.end = time( 0 );
|
||||
old_time = new_time;
|
||||
}
|
||||
|
||||
/* Drive the completion. */
|
||||
if ( interrupted() )
|
||||
@@ -504,6 +518,7 @@ void exec_wait()
|
||||
cmdtab[ i ].buffer[ OUT ], cmdtab[ i ].buffer[ ERR ],
|
||||
cmdtab[ i ].exit_reason );
|
||||
|
||||
/* Clean up the command's running commands table slot. */
|
||||
BJAM_FREE( cmdtab[ i ].buffer[ OUT ] );
|
||||
cmdtab[ i ].buffer[ OUT ] = 0;
|
||||
cmdtab[ i ].buf_size[ OUT ] = 0;
|
||||
@@ -512,6 +527,7 @@ void exec_wait()
|
||||
cmdtab[ i ].buffer[ ERR ] = 0;
|
||||
cmdtab[ i ].buf_size[ ERR ] = 0;
|
||||
|
||||
cmdtab[ i ].pid = 0;
|
||||
cmdtab[ i ].func = 0;
|
||||
cmdtab[ i ].closure = 0;
|
||||
cmdtab[ i ].start_time = 0;
|
||||
|
||||
Reference in New Issue
Block a user