Ignore:
Timestamp:
Sep 21, 2020, 12:59:41 PM (5 years ago)
Author:
bird
Message:

kmk: Added some refinements to the recent repeat-output-from-failing-command-in-die hack.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/output.c

    r3432 r3479  
    5858#else
    5959# define STREAM_OK(_s) 1
     60#endif
     61
     62
     63#if defined(KMK) && !defined(NO_OUTPUT_SYNC)
     64/* Non-negative if we're counting output lines.
     65
     66   This is used by die_with_job_output to decide whether the initial build
     67   error needs to be repeated because there was too much output from parallel
     68   jobs between it and the actual make termination. */
     69int output_metered = -1;
     70
     71static void meter_output_block (char const *buffer, size_t len)
     72{
     73  while (len > 0)
     74    {
     75      char *nl = (char *)memchr (buffer, '\n', len);
     76      size_t linelen;
     77      if (nl)
     78        {
     79          linelen = nl - buffer + 1;
     80          output_metered++;
     81        }
     82      else
     83          linelen = len;
     84      output_metered += linelen / 132;
     85
     86      /* advance */
     87      buffer += linelen;
     88      len    -= linelen;
     89    }
     90}
    6091#endif
    6192
     
    78109static int combined_output = -1;
    79110
     111/* Helper for membuf_reset and output_reset */
     112static membuf_reset (struct output *out)
     113{
     114  struct output_segment *seg;
     115  while ((seg = out->out.head_seg))
     116    {
     117     out->out.head_seg = seg->next;
     118     free (seg);
     119    }
     120  out->out.tail_seg = NULL;
     121  out->out.tail_run = NULL;
     122  out->out.head_run = NULL;
     123  out->out.left     = 0;
     124  out->out.total    = 0;
     125
     126  while ((seg = out->err.head_seg))
     127    {
     128     out->err.head_seg = seg->next;
     129     free (seg);
     130    }
     131  out->err.tail_seg = NULL;
     132  out->err.tail_run = NULL;
     133  out->err.head_run = NULL;
     134  out->err.left     = 0;
     135  out->err.total    = 0;
     136
     137  out->seqno = 0;
     138}
     139
     140/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
     141void output_reset (struct output *out)
     142{
     143  if (out && (out->out.total || out->err.total))
     144    membuf_reset (out);
     145}
     146
    80147/* Internal worker for output_dump and membuf_dump_most. */
    81148static void membuf_dump (struct output *out)
     
    86153      struct output_run *err_run;
    87154      struct output_run *out_run;
    88       struct output_segment *seg;
    89155      FILE *prevdst;
    90156
     
    130196            fflush(prevdst);
    131197          prevdst = dst;
     198#ifdef KMK
     199          if (output_metered < 0)
     200            { /* likely */ }
     201          else
     202            meter_output_block (src, len);
     203#endif
    132204# if 0 /* for debugging */
    133205          while (len > 0)
     
    179251
    180252      /* Free the segments and reset the state. */
    181       while ((seg = out->out.head_seg))
    182         {
    183          out->out.head_seg = seg->next;
    184          free (seg);
    185         }
    186       out->out.tail_seg = NULL;
    187       out->out.tail_run = NULL;
    188       out->out.head_run = NULL;
    189       out->out.left     = 0;
    190       out->out.total    = 0;
    191 
    192       while ((seg = out->err.head_seg))
    193         {
    194          out->err.head_seg = seg->next;
    195          free (seg);
    196         }
    197       out->err.tail_seg = NULL;
    198       out->err.tail_run = NULL;
    199       out->err.head_run = NULL;
    200       out->err.left     = 0;
    201       out->err.total    = 0;
    202 
    203       out->seqno = 0;
     253      membuf_reset (out);
    204254    }
    205255  else
     
    756806      if (len <= 0)
    757807        break;
     808#ifdef KMK
     809      if (output_metered < 0)
     810        { /* likely */ }
     811      else
     812        meter_output_block (buffer, len);
     813#endif
    758814      if (fwrite (buffer, len, 1, to) < 1)
    759815        {
     
    9531009#endif
    9541010}
     1011
     1012# if defined(KMK) && !defined(CONFIG_WITH_OUTPUT_IN_MEMORY)
     1013/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
     1014void output_reset (struct output *out)
     1015{
     1016  if (out)
     1017    {
     1018      if (out->out != OUTPUT_NONE)
     1019        {
     1020          int e;
     1021          lseek (out->out, 0, SEEK_SET);
     1022          EINTRLOOP (e, ftruncate (out->out, 0));
     1023        }
     1024      if (out->err != OUTPUT_NONE && out->err != out->out)
     1025        {
     1026          int e;
     1027          lseek (out->err, 0, SEEK_SET);
     1028          EINTRLOOP (e, ftruncate (out->err, 0));
     1029        }
     1030    }
     1031}
     1032# endif
    9551033#endif /* NO_OUTPUT_SYNC */
    9561034
Note: See TracChangeset for help on using the changeset viewer.