Ignore:
Timestamp:
Mar 28, 2018, 8:56:21 PM (7 years ago)
Author:
bird
Message:

kmk,kWorker: Catch output from kWorker processes when --output-sync isn't 'none'.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/kWorker.c

    r3198 r3199  
    928928
    929929/** Whether control-C/SIGINT or Control-Break/SIGBREAK have been seen. */
    930 static KBOOL volatile g_fCtrlC = K_FALSE;
     930static int volatile g_rcCtrlC = 0;
     931
     932/** The communication pipe handle.  We break this when we see Ctrl-C such. */
     933#ifdef KBUILD_OS_WINDOWS
     934static HANDLE       g_hPipe = INVALID_HANDLE_VALUE;
     935#else
     936static int          g_hPipe = -1;
     937#endif
     938
    931939
    932940/* Further down. */
     
    66576665    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile);
    66586666    g_cWriteFileCalls++;
    6659     kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_fCtrlC);
     6667    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_rcCtrlC != 0);
    66606668    if (idxHandle < g_Sandbox.cHandles)
    66616669    {
     
    73687376    BOOL        fRet;
    73697377    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hObject);
    7370     kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_fCtrlC);
     7378    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_rcCtrlC != 0);
    73717379    if (idxHandle < g_Sandbox.cHandles)
    73727380    {
     
    95269534KU32 const                  g_cSandboxGetProcReplacements = K_ELEMENTS(g_aSandboxGetProcReplacements);
    95279535
     9536/**
     9537 * Thread that is spawned by the first terminal kwSandboxCtrlHandler invocation.
     9538 *
     9539 * This will wait 5 second in a hope that the main thread will shut down the
     9540 * process nicly, otherwise it will terminate it forcefully.
     9541 */
     9542static DWORD WINAPI kwSandboxCtrlThreadProc(PVOID pvUser)
     9543{
     9544    int i;
     9545    for (i = 0; i < 10; i++)
     9546    {
     9547        Sleep(500);
     9548        CancelIoEx(g_hPipe, NULL);
     9549    }
     9550    TerminateProcess(GetCurrentProcess(), (int)(intptr_t)pvUser);
     9551    return -1;
     9552}
     9553
    95289554
    95299555/**
     
    95359561static BOOL WINAPI kwSandboxCtrlHandler(DWORD dwCtrlType)
    95369562{
     9563    DWORD        cbIgn;
     9564    int volatile rc; /* volatile for debugging */
     9565    int volatile rcPrev;
     9566    const char  *pszMsg;
    95379567    switch (dwCtrlType)
    95389568    {
    95399569        case CTRL_C_EVENT:
    9540             fprintf(stderr, "kWorker: Ctrl-C\n");
    9541             g_fCtrlC = K_TRUE;
    9542             exit(9);
     9570            rc = 9;
     9571            pszMsg = "kWorker: Ctrl-C\r\n";
    95439572            break;
    95449573
    95459574        case CTRL_BREAK_EVENT:
    9546             fprintf(stderr, "kWorker: Ctrl-Break\n");
    9547             g_fCtrlC = K_TRUE;
    9548             exit(10);
     9575            rc = 10;
     9576            pszMsg = "kWorker: Ctrl-Break\r\n";
    95499577            break;
    95509578
    95519579        case CTRL_CLOSE_EVENT:
    9552             fprintf(stderr, "kWorker: console closed\n");
    9553             g_fCtrlC = K_TRUE;
    9554             exit(11);
     9580            rc = 11;
     9581            pszMsg = "kWorker: console closed\r\n";
    95559582            break;
    95569583
    95579584        case CTRL_LOGOFF_EVENT:
    9558             fprintf(stderr, "kWorker: logoff event\n");
    9559             g_fCtrlC = K_TRUE;
    9560             exit(11);
     9585            rc = 11;
     9586            pszMsg = "kWorker: logoff event\r\n";
    95619587            break;
    95629588
    95639589        case CTRL_SHUTDOWN_EVENT:
    9564             fprintf(stderr, "kWorker: shutdown event\n");
    9565             g_fCtrlC = K_TRUE;
    9566             exit(11);
     9590            rc = 11;
     9591            pszMsg = "kWorker: shutdown event\r\n";
    95679592            break;
    95689593
    95699594        default:
    95709595            fprintf(stderr, "kwSandboxCtrlHandler: %#x\n", dwCtrlType);
    9571             break;
    9572     }
     9596            return TRUE;
     9597    }
     9598
     9599    /*
     9600     * Terminate the process after 5 seconds.
     9601     *
     9602     * We don't want to wait here as the console server will otherwise not
     9603     * signal the other processes in the console, which is bad for kmk as it
     9604     * will continue to forge ahead.  So, the first time we get here we start
     9605     * a thread for doing the delayed termination.
     9606     *
     9607     * If we get here a second time we just terminate the process ourselves.
     9608     *
     9609     * Note! We do no try call exit() here as it turned out to deadlock a lot
     9610     *       flusing file descriptors (stderr back when we first wrote to it).
     9611     */
     9612    rcPrev = g_rcCtrlC;
     9613    g_rcCtrlC = rc;
     9614    WriteFile(GetStdHandle(STD_ERROR_HANDLE), pszMsg, (DWORD)strlen(pszMsg), &cbIgn, NULL);
     9615    CancelIoEx(g_hPipe, NULL); /* wake up idle main thread */
     9616    if (rcPrev == 0)
     9617    {
     9618        CreateThread(NULL, 0, kwSandboxCtrlThreadProc, (void*)(intptr_t)rc, 0 /*fFlags*/, NULL);
     9619        return TRUE;
     9620    }
     9621    TerminateProcess(GetCurrentProcess(), rc);
    95739622    return TRUE;
    95749623}
     
    1060710656    KU8 const  *pbBuf  = (KU8 const *)pvBuf;
    1060810657    KU32        cbLeft = cbToWrite;
    10609     for (;;)
     10658    while (g_rcCtrlC == 0)
    1061010659    {
    1061110660        DWORD cbActuallyWritten = 0;
     
    1062710676        }
    1062810677    }
     10678    return -1;
    1062910679}
    1063010680
     
    1064610696    KU8 *pbBuf  = (KU8 *)pvBuf;
    1064710697    KU32 cbLeft = cbToRead;
    10648     for (;;)
     10698    while (g_rcCtrlC == 0)
    1064910699    {
    1065010700        DWORD cbActuallyRead = 0;
     
    1067110721        }
    1067210722    }
     10723    return -1;
    1067310724}
    1067410725
     
    1123811289                    {
    1123911290                        close(fdNul);
    11240                         kHlpAssert(GetStdHandle(STD_INPUT_HANDLE) != hPipe);
    1124111291                        hPipe = hDuplicate;
    1124211292                    }
     
    1125711307        return kwErrPrintfRc(2, "The specified --pipe %p is not a pipe handle: type %#x (last err %u)!\n",
    1125811308                             GetFileType(hPipe), GetLastError());
     11309    g_hPipe = hPipe;
    1125911310
    1126011311    /*
     
    1129611347                    /* The first string after the header is the command. */
    1129711348                    psz = (const char *)&pbMsgBuf[sizeof(cbMsg)];
    11298                     if (strcmp(psz, "JOB") == 0)
     11349                    if (   strcmp(psz, "JOB") == 0
     11350                        && g_rcCtrlC == 0)
    1129911351                    {
    1130011352                        struct
     
    1131411366                        {
    1131511367                            kwSandboxCleanupLate(&g_Sandbox);
    11316                             continue;
     11368                            if (g_rcCtrlC == 0)
     11369                                continue;
    1131711370                        }
    1131811371                    }
     
    1134711400        if (getenv("KWORKER_STATS") != NULL)
    1134811401            kwPrintStats();
    11349         return rc > 0 ? 0 : 1;
     11402        return g_rcCtrlC != 0 ? g_rcCtrlC : rc > 0 ? 0 : 1;
    1135011403    }
    1135111404}
Note: See TracChangeset for help on using the changeset viewer.