Changeset 77009


Ignore:
Timestamp:
Feb 13, 2012, 8:08:20 PM (6 years ago)
Author:
Noel Belcourt
Message:

Revert 77005, biffed the revert of 76862.

Location:
trunk/tools/build/v2/engine
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/build/v2/engine/execunix.c

    r77005 r77009  
    6767
    6868static clock_t tps = 0;
    69 static struct timeval tv;
     69static struct timespec tv;
    7070static int select_timeout = 0;
    7171static int intr = 0;
     
    9292    void   *closure;
    9393    time_t  start_dt;         /* start of command timestamp */
     94    long    msgsize[2];
    9495} cmdtab[ MAXJOBS ] = {{0}};
    9596
     
    343344int read_descriptor( int i, int s )
    344345{
    345     int  ret;
    346     int  len;
     346    int  ret = 1, len, err;
    347347    char buffer[BUFSIZ];
    348348
    349     while ( 0 < ( ret = fread( buffer, sizeof(char),  BUFSIZ-1, cmdtab[ i ].stream[ s ] ) ) )
    350     {
    351         buffer[ret] = 0;
    352         if  ( !cmdtab[ i ].buffer[ s ] )
    353         {
    354             /* Never been allocated. */
    355             cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( ret + 1 );
    356             memcpy( cmdtab[ i ].buffer[ s ], buffer, ret + 1 );
    357         }
    358         else
    359         {
    360             /* Previously allocated. */
    361             char * tmp = cmdtab[ i ].buffer[ s ];
    362             len = strlen( tmp );
    363             cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( len + ret + 1 );
    364             memcpy( cmdtab[ i ].buffer[ s ], tmp, len );
    365             memcpy( cmdtab[ i ].buffer[ s ] + len, buffer, ret + 1 );
    366             BJAM_FREE( tmp );
     349    while ( 0 < ( ret = fread( buffer, sizeof(char),  BUFSIZ-1, cmdtab[ i ].stream[ s ] ) ) ) {
     350
     351        /* only copy action data until hit buffer limit, then ignore rest of data */
     352        if (cmdtab[i].msgsize[s] < globs.maxbuf) {
     353            cmdtab[i].msgsize[s] += ret;
     354            buffer[ret] = 0;
     355            if  ( !cmdtab[ i ].buffer[ s ] )
     356            {
     357                /* Never been allocated. */
     358                cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( ret + 1 );
     359                memcpy( cmdtab[ i ].buffer[ s ], buffer, ret + 1 );
     360            }
     361            else
     362            {
     363                /* Previously allocated. */
     364                char * tmp = cmdtab[ i ].buffer[ s ];
     365                len = strlen( tmp );
     366                cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( len + ret + 1 );
     367                memcpy( cmdtab[ i ].buffer[ s ], tmp, len );
     368                memcpy( cmdtab[ i ].buffer[ s ] + len, buffer, ret + 1 );
     369                BJAM_FREE( tmp );
     370            }
     371
     372            /* buffer was truncated, append newline to ensure pjl can find line end */
     373            if (globs.maxbuf <= cmdtab[i].msgsize[s]) {
     374                cmdtab[i].buffer[s][cmdtab[i].msgsize[s]-1] = '\n';
     375            }
    367376        }
    368377    }
     
    380389    close(cmdtab[ i ].fd[ s ]);
    381390    cmdtab[ i ].fd[ s ] = 0;
     391
     392    cmdtab[i].msgsize[s] = 0;
    382393}
    383394
     
    424435}
    425436
     437void cleanup_child(int i, int status)
     438{
     439    int         rstat;
     440    struct tms  new_time;
     441    timing_info time_info;
     442
     443    cmdtab[ i ].pid = 0;
     444
     445    /* Set reason for exit if not timed out. */
     446    if ( WIFEXITED( status ) ) {
     447        cmdtab[ i ].exit_reason = 0 == WEXITSTATUS( status )
     448            ? EXIT_OK : EXIT_FAIL;
     449    }
     450
     451    /* Print out the rule and target name. */
     452    out_action( cmdtab[ i ].action, cmdtab[ i ].target,
     453        cmdtab[ i ].command, cmdtab[ i ].buffer[ OUT ],
     454        cmdtab[ i ].buffer[ ERR ], cmdtab[ i ].exit_reason
     455    );
     456
     457    times( &new_time );
     458
     459    time_info.system = (double)( new_time.tms_cstime - old_time.tms_cstime ) / CLOCKS_PER_SEC;
     460    time_info.user   = (double)( new_time.tms_cutime - old_time.tms_cutime ) / CLOCKS_PER_SEC;
     461    time_info.start  = cmdtab[ i ].start_dt;
     462    time_info.end    = time( 0 );
     463
     464    old_time = new_time;
     465
     466    if ( intr )
     467        rstat = EXEC_CMD_INTR;
     468    else if ( status != 0 )
     469        rstat = EXEC_CMD_FAIL;
     470    else
     471        rstat = EXEC_CMD_OK;
     472
     473    /* Assume -p0 in effect so only pass buffer[ 0 ]
     474     * containing merged output.
     475     */
     476     (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat, &time_info, cmdtab[ i ].command, cmdtab[ i ].buffer[ 0 ] );
     477
     478     BJAM_FREE( cmdtab[ i ].buffer[ OUT ] );
     479     cmdtab[ i ].buffer[ OUT ] = 0;
     480
     481     BJAM_FREE( cmdtab[ i ].buffer[ ERR ] );
     482     cmdtab[ i ].buffer[ ERR ] = 0;
     483
     484     BJAM_FREE( cmdtab[ i ].command );
     485     cmdtab[ i ].command = 0;
     486
     487     cmdtab[ i ].func = 0;
     488     cmdtab[ i ].closure = 0;
     489     cmdtab[ i ].start_time = 0;
     490}
     491
    426492
    427493/*
     
    431497int exec_wait()
    432498{
    433     int         i;
     499    int         i, j;
    434500    int         ret;
    435501    int         fd_max;
     
    437503    int         status;
    438504    int         finished;
    439     int         rstat;
    440     timing_info time_info;
    441505    fd_set      fds;
    442     struct tms  new_time;
    443506
    444507    /* Handle naive make1() which does not know if commands are running. */
     
    458521             */
    459522            tv.tv_sec = select_timeout;
    460             tv.tv_usec = 0;
     523            tv.tv_nsec = 0;
    461524
    462525            /* select() will wait until: i/o on a descriptor, a signal, or we
    463526             * time out.
    464527             */
    465             ret = select( fd_max + 1, &fds, 0, 0, &tv );
     528            ret = pselect( fd_max + 1, &fds, 0, 0, &tv, &empty_sigmask );
    466529        }
    467530        else
    468531        {
    469             /* select() will wait until i/o on a descriptor or a signal. */
    470             ret = select( fd_max + 1, &fds, 0, 0, 0 );
     532            /* pselect() will wait until i/o on a descriptor or a signal. */
     533            ret = pselect( fd_max + 1, &fds, 0, 0, 0, &empty_sigmask );
     534        }
     535
     536        if (-1 == ret && errno != EINTR) {
     537            perror("pselect()");
     538            exit(-1);
     539        }
     540
     541        if (0 < child_events) {
     542            /* child terminated via SIGCHLD */
     543            for (i=0; i<MAXJOBS; ++i) {
     544                if (0 < terminated_children[i].pid) {
     545                    pid_t pid = terminated_children[i].pid;
     546                    /* get index of terminated pid */
     547                    for (j=0; j<globs.jobs; ++j) {
     548                        if (pid == cmdtab[j].pid) {
     549                            /* cleanup loose ends for terminated process */
     550                            close_streams(j, OUT);
     551                            if ( globs.pipe_action != 0 ) close_streams(j, ERR);
     552                            cleanup_child(j, terminated_children[i].status);
     553                            --cmdsrunning;
     554                            finished = 1;
     555                            break;
     556                        }
     557                    }
     558                    /* clear entry from list */
     559                    terminated_children[i].status = 0;
     560                    terminated_children[i].pid = 0;
     561                    --child_events;
     562                }
     563            }
    471564        }
    472565
     
    497590                    if ( pid == cmdtab[ i ].pid )
    498591                    {
     592                        /* move into function so signal handler can also use */
    499593                        finished = 1;
    500                         pid = 0;
    501                         cmdtab[ i ].pid = 0;
    502 
    503                         /* Set reason for exit if not timed out. */
    504                         if ( WIFEXITED( status ) )
    505                         {
    506                             cmdtab[ i ].exit_reason = 0 == WEXITSTATUS( status )
    507                                 ? EXIT_OK
    508                                 : EXIT_FAIL;
    509                         }
    510 
    511                         /* Print out the rule and target name. */
    512                         out_action( cmdtab[ i ].action, cmdtab[ i ].target,
    513                             cmdtab[ i ].command, cmdtab[ i ].buffer[ OUT ],
    514                             cmdtab[ i ].buffer[ ERR ], cmdtab[ i ].exit_reason
    515                         );
    516 
    517                         times( &new_time );
    518 
    519                         time_info.system = (double)( new_time.tms_cstime - old_time.tms_cstime ) / CLOCKS_PER_SEC;
    520                         time_info.user   = (double)( new_time.tms_cutime - old_time.tms_cutime ) / CLOCKS_PER_SEC;
    521                         time_info.start  = cmdtab[ i ].start_dt;
    522                         time_info.end    = time( 0 );
    523 
    524                         old_time = new_time;
    525 
    526                         /* Drive the completion. */
     594                        cleanup_child(i, status);
    527595                        --cmdsrunning;
    528 
    529                         if ( intr )
    530                             rstat = EXEC_CMD_INTR;
    531                         else if ( status != 0 )
    532                             rstat = EXEC_CMD_FAIL;
    533                         else
    534                             rstat = EXEC_CMD_OK;
    535 
    536                         /* Assume -p0 in effect so only pass buffer[ 0 ]
    537                          * containing merged output.
    538                          */
    539                         (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat,
    540                             &time_info, cmdtab[ i ].command,
    541                             cmdtab[ i ].buffer[ 0 ] );
    542 
    543                         BJAM_FREE( cmdtab[ i ].buffer[ OUT ] );
    544                         cmdtab[ i ].buffer[ OUT ] = 0;
    545 
    546                         BJAM_FREE( cmdtab[ i ].buffer[ ERR ] );
    547                         cmdtab[ i ].buffer[ ERR ] = 0;
    548 
    549                         BJAM_FREE( cmdtab[ i ].command );
    550                         cmdtab[ i ].command = 0;
    551 
    552                         cmdtab[ i ].func = 0;
    553                         cmdtab[ i ].closure = 0;
    554                         cmdtab[ i ].start_time = 0;
    555596                    }
    556597                    else
     
    563604        }
    564605    }
    565 
    566606    return 1;
    567607}
  • trunk/tools/build/v2/engine/jam.c

    r77005 r77009  
    103103
    104104
     105#include "limits.h"
     106
    105107#include "jam.h"
    106108#include "option.h"
     
    135137
    136138/* And UNIX for this. */
    137 #ifdef unix
     139#if defined(unix) || defined(__unix)
    138140    #include <sys/utsname.h>
     141    #include <sys/wait.h>
    139142    #include <signal.h>
     143
     144     #include <sys/utsname.h>
     145     #include <signal.h>
     146
     147     sigset_t empty_sigmask;
     148     volatile sig_atomic_t child_events = 0;
     149     struct terminated_child terminated_children[MAXJOBS] = {{ 0 }};
     150
     151     void child_sig_handler(int x) {
     152         pid_t pid;
     153         int i, status;
     154         pid = waitpid(-1, &status, WNOHANG);
     155         if (0 < pid) {
     156           /* save terminated child pid and status */
     157           for (i=0; i<MAXJOBS; ++i) {
     158             /* find first available slot */
     159             if (terminated_children[i].pid == 0) {
     160                 terminated_children[i].pid = pid;
     161                 terminated_children[i].status = status;
     162                 break;
     163             }
     164           }
     165         }
     166         ++child_events;
     167         signal(SIGCHLD, child_sig_handler);
     168     }
    140169#endif
    141170
     
    153182#endif
    154183    0,          /* output commands, not run them */
    155     0           /* action timeout */
     184    0,          /* action timeout */
     185    0,         
     186    INT_MAX     /* default is to accept all action output */
    156187};
    157188
     
    231262    module_t              * environ_module;
    232263
     264#if defined(unix) || defined(__unix)
     265    sigset_t sigmask;
     266    struct sigaction sa;
     267
     268    sigemptyset(&sigmask);
     269    sigaddset(&sigmask, SIGCHLD);
     270    sigprocmask(SIG_BLOCK, &sigmask, NULL);
     271    sa.sa_flags = 0;
     272    sa.sa_handler = child_sig_handler;
     273    sigaction(SIGCHLD, &sa, NULL);
     274    sigemptyset(&empty_sigmask);
     275#endif
     276
    233277    saved_argv0 = argv[0];
    234278
     
    242286    ++argv;
    243287
    244     if ( getoptions( argc, argv, "-:l:d:j:p:f:gs:t:ano:qv", optv ) < 0 )
     288    if ( getoptions( argc, argv, "-:l:m:d:j:p:f:gs:t:ano:qv", optv ) < 0 )
    245289    {
    246290        printf( "\nusage: %s [ options ] targets...\n\n", progname );
     
    252296        printf( "-jx     Run up to x shell commands concurrently.\n" );
    253297        printf( "-lx     Limit actions to x number of seconds after which they are stopped.\n" );
     298        printf( "-mx     Limit action output buffer to x kb's of data, after which action output is read and ignored.\n" );
    254299        printf( "-n      Don't actually execute the updating actions.\n" );
    255300        printf( "-ox     Write the updating actions to file x.\n" );
     
    318363    if ( ( s = getoptval( optv, 'l', 0 ) ) )
    319364        globs.timeout = atoi( s );
     365
     366    if ( ( s = getoptval( optv, 'm', 0 ) ) )
     367        globs.maxbuf = atoi( s ) * 1024;
    320368
    321369    /* Turn on/off debugging */
     
    397445
    398446        /* Set JAMUNAME. */
    399 #ifdef unix
     447#if defined(unix) || defined(__unix)
    400448        {
    401449            struct utsname u;
  • trunk/tools/build/v2/engine/jam.h

    r77005 r77009  
    457457                                 */
    458458    int    dart;                /* output build and test results formatted for Dart */
     459    int    maxbuf;              /* limit action output buffer to maxbuf kb's of data */
    459460};
    460461
    461462extern struct globs globs;
     463
     464struct terminated_child
     465{
     466    pid_t  pid;
     467    int    status;
     468};
     469
     470extern struct terminated_child terminated_children[MAXJOBS];
     471
    462472
    463473#define DEBUG_MAKE     ( globs.debug[ 1 ] )   /* show actions when executed */
     
    494504#include "debug.h"
    495505
    496 #endif
     506/* Handle child process termination */
     507#if defined(unix) || defined(__unix)
     508#include <signal.h>
     509extern sigset_t empty_sigmask;
     510extern volatile sig_atomic_t child_events;
     511void child_sig_handler(int x);
     512#endif
     513
     514#endif
Note: See TracChangeset for help on using the changeset viewer.