Changeset 2759 for trunk/src/kmk


Ignore:
Timestamp:
Jan 28, 2015, 5:14:00 PM (10 years ago)
Author:
bird
Message:

More generic ENOSPC workaround for windows.

Location:
trunk/src/kmk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/config.h.win

    r2702 r2759  
    1616GNU Make; see the file COPYING.  If not, write to the Free Software
    1717Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */
     18
     19#ifndef ___config_h_win
     20#define ___config_h_win
    1821
    1922/* Suppress some Visual C++ warnings.
     
    534537#define _DIRENT_HAVE_D_TYPE   1
    535538
    536 
    537 /* cygwin sucks to much in one end or the other. */
     539/* bird: Not sure if this is necessary any more... */
    538540#define BATCH_MODE_ONLY_SHELL
    539541
     
    557559#endif
    558560
     561/* bird: Include mscfakes.h to make sure we have all it's tricks applied. */
     562#ifndef ___mscfakes_h
     563# include "kmkbuiltin/mscfakes.h"
     564#endif
     565
     566#endif /* bird */
     567
  • trunk/src/kmk/kmkbuiltin/kDepObj.c

    r2591 r2759  
    2727*   Header Files                                                               *
    2828*******************************************************************************/
     29#define MSCFAKES_NO_WINDOWS_H
    2930#include "config.h"
    3031#include <stdio.h>
  • trunk/src/kmk/kmkbuiltin/mscfakes.c

    r2756 r2759  
    467467
    468468
    469 int writev(int fd, const struct iovec *vector, int count)
    470 {
    471     int size = 0;
    472     int i;
    473     for (i = 0; i < count; i++)
    474     {
    475         int cb = write(fd, vector[i].iov_base, (int)vector[i].iov_len);
    476         if (cb < 0)
     469/* We override the libc write function (in our modules only, unfortunately) so
     470   we can kludge our way around a ENOSPC problem observed on build servers
     471   capturing STDOUT and STDERR via pipes.  Apparently this may happen when the
     472   pipe buffer is full, even with the mscfake_init hack in place.
     473
     474   XXX: Probably need to hook into fwrite as well. */
     475ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc)
     476{
     477    ssize_t cbRet;
     478    if (cbSrc < UINT_MAX / 4)
     479    {
     480#ifndef MSC_WRITE_TEST
     481        cbRet = _write(fd, pvSrc, (unsigned int)cbSrc);
     482#else
     483        cbRet = -1; errno = ENOSPC;
     484#endif
     485        if (cbRet < 0)
    477486        {
    478487            /* ENOSPC on pipe kludge. */
    479             char  *pbCur;
    480             size_t cbLeft;
    481             int    cbLimit;
    482             int    cSinceLastSuccess;
    483             int    iErr = errno;
    484 
     488            int cbLimit;
     489            int cSinceLastSuccess;
     490
     491            if (cbSrc == 0)
     492                return 0;
    485493            if (errno != ENOSPC)
    486494                return -1;
    487             if ((int)vector[i].iov_len == 0)
    488                 continue;
     495#ifndef MSC_WRITE_TEST
    489496            if (!isPipeFd(fd))
    490497            {
     
    492499                return -1;
    493500            }
     501#endif
    494502
    495503            /* Likely a full pipe buffer, try write smaller amounts and do some
    496504               sleeping inbetween each unsuccessful one. */
    497             pbCur = vector[i].iov_base;
    498             cbLeft = vector[i].iov_len;
    499             cbLimit = cbLeft / 4;
     505            cbLimit = cbSrc / 4;
    500506            if (cbLimit < 4)
    501507                cbLimit = 4;
     
    503509                cbLimit = 512;
    504510            cSinceLastSuccess = 0;
    505 
    506             while (cbLeft > 0)
     511            cbRet = 0;
     512#ifdef MSC_WRITE_TEST
     513            cbLimit = 4;
     514#endif
     515
     516            while (cbSrc > 0)
    507517            {
    508                 int cbAttempt = cbLeft > cbLimit ? (int)cbLimit : (int)cbLeft;
    509                 cb = write(fd, pbCur, cbAttempt);
    510                 if (cb > 0)
     518                unsigned int cbAttempt = cbSrc > cbLimit ? (int)cbLimit : (int)cbSrc;
     519                ssize_t cbActual = _write(fd, pvSrc, cbAttempt);
     520                if (cbActual > 0)
    511521                {
    512                     assert(cb <= cbAttempt);
    513                     pbCur  += cb;
    514                     cbLeft -= cb;
    515                     size   += cb;
     522                    assert(cbActual <= (ssize_t)cbAttempt);
     523                    pvSrc  = (char *)pvSrc + cbActual;
     524                    cbSrc -= cbActual;
     525                    cbRet += cbActual;
     526#ifndef MSC_WRITE_TEST
    516527                    if (cbLimit < 32)
    517528                        cbLimit = 32;
     529#endif
    518530                    cSinceLastSuccess = 0;
    519531                }
     
    538550                }
    539551            }
    540             cb = 0;
    541         }
     552        }
     553    }
     554    else
     555    {
     556        /*
     557         * Type limit exceeded. Split the job up.
     558         */
     559        cbRet = 0;
     560        while (cbSrc > 0)
     561        {
     562            size_t  cbToWrite = cbSrc > UINT_MAX / 4 ? UINT_MAX / 4 : cbSrc;
     563            ssize_t cbWritten = msc_write(fd, pvSrc, cbToWrite);
     564            if (cbWritten > 0)
     565            {
     566                pvSrc  = (char *)pvSrc + (size_t)cbWritten;
     567                cbSrc -= (size_t)cbWritten;
     568                cbRet += (size_t)cbWritten;
     569            }
     570            else if (cbWritten == 0 || cbRet > 0)
     571                break;
     572            else
     573                return -1;
     574        }
     575    }
     576    return cbRet;
     577}
     578
     579ssize_t writev(int fd, const struct iovec *vector, int count)
     580{
     581    int size = 0;
     582    int i;
     583    for (i = 0; i < count; i++)
     584    {
     585        int cb = msc_write(fd, vector[i].iov_base, (int)vector[i].iov_len);
     586        if (cb < 0)
     587            return cb;
    542588        size += cb;
    543589    }
     
    626672
    627673
    628 
    629674/**
    630675 * This is a kludge to make pipe handles blocking.
  • trunk/src/kmk/kmkbuiltin/mscfakes.h

    r2713 r2759  
    2828#ifdef _MSC_VER
    2929
     30/* Include the config file (kmk's) so we don't need to duplicate stuff from it here. */
     31#include "config.h"
     32
    3033#include <io.h>
    3134#include <direct.h>
     
    3437#include <malloc.h>
    3538#include "getopt.h"
     39#ifndef MSCFAKES_NO_WINDOWS_H
     40# include <Windows.h>
     41#endif
    3642
    37 /* Note: Duplicated it config.h.win */
    3843#include <sys/stat.h>
    3944#include <io.h>
     
    7984typedef unsigned short gid_t;
    8085#endif
     86#if defined(_M_AMD64) || defined(_M_X64) || defined(_M_IA64) || defined(_WIN64)
     87typedef __int64 ssize_t;
     88#else
    8189typedef long ssize_t;
     90#endif
    8291typedef unsigned long u_long;
    8392typedef unsigned int u_int;
    8493typedef unsigned short u_short;
    8594
    86 #ifndef timerisset
     95#if !defined(timerisset) && defined(MSCFAKES_NO_WINDOWS_H)
    8796struct timeval
    8897{
     
    138147int symlink(const char *pszDst, const char *pszLink);
    139148int utimes(const char *pszPath, const struct timeval *paTimes);
    140 int writev(int fd, const struct iovec *vector, int count);
     149ssize_t writev(int fd, const struct iovec *vector, int count);
    141150
    142 
     151/* bird write ENOSPC hacks. */
     152#undef write
     153#define write msc_write
     154ssize_t msc_write(int fd, const void *pvSrc, size_t cbSrc);
    143155
    144156/*
Note: See TracChangeset for help on using the changeset viewer.