Changeset 778 for trunk/src/gmake/main.c


Ignore:
Timestamp:
Jan 21, 2007, 1:29:17 AM (19 years ago)
Author:
bird
Message:

Attempt at dealing with deadlocked kmk on Ctrl-C by dispatching the SIGINT/SIGBREAK on the main thread instead of the ctrl-event thread (Windows).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gmake/main.c

    r765 r778  
    927927  return (sh_found);
    928928}
     929
     930/* bird: */
     931#ifdef CONFIG_NEW_WIN32_CTRL_EVENT
     932#include <process.h>
     933static UINT g_tidMainThread = 0;
     934static int g_sigPending = 0; /* lazy bird */
     935
     936static __declspec(naked) void dispatch_stub(void)
     937{
     938    __asm  {
     939        pushfd
     940        pushad
     941        cld
     942    }
     943    fflush(stdout);
     944    /*fprintf(stderr, "dbg: raising %s on the main thread (%d)\n", g_sigPending == SIGINT ? "SIGINT" : "SIGBREAK", _getpid());*/
     945    raise(g_sigPending);
     946    __asm  {
     947        popad
     948        popfd
     949        ret
     950    }
     951}
     952
     953static BOOL WINAPI ctrl_event(DWORD CtrlType)
     954{
     955    int sig = (CtrlType == CTRL_C_EVENT) ? SIGINT : SIGBREAK;
     956    HANDLE hThread;
     957    CONTEXT Ctx;
     958
     959    /* open the main thread and suspend it. */
     960    hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, g_tidMainThread);
     961    SuspendThread(hThread);
     962
     963    /* Get the thread context and */
     964    memset(&Ctx, 0, sizeof(Ctx));
     965    Ctx.ContextFlags = CONTEXT_FULL;
     966    GetThreadContext(hThread, &Ctx);
     967
     968    /* If we've got a valid Esp, dispatch it on the main thread
     969       otherwise raise the signal in the ctrl-event thread (this). */
     970    if (Ctx.Esp >= 0x1000)
     971    {
     972        ((uintptr_t *)Ctx.Esp)[-1] = Ctx.Eip;
     973        Ctx.Esp -= sizeof(uintptr_t);
     974        Ctx.Eip = (uintptr_t)&dispatch_stub;
     975
     976        SetThreadContext(hThread, &Ctx);
     977        g_sigPending = sig;
     978        ResumeThread(hThread);
     979        CloseHandle(hThread);
     980    }
     981    else
     982    {
     983        fprintf(stderr, "dbg: raising %s on the ctrl-event thread (%d)\n", sig == SIGINT ? "SIGINT" : "SIGBREAK", _getpid());
     984        raise(sig);
     985        ResumeThread(hThread);
     986        CloseHandle(hThread);
     987        exit(130);
     988    }
     989
     990    Sleep(1);
     991    return TRUE;
     992}
     993#endif /* CONFIG_NEW_WIN32_CTRL_EVENT */
     994
    929995#endif  /* WINDOWS32 */
    930996
     
    10951161  FATAL_SIG (SIGXFSZ);
    10961162#endif
     1163
     1164#ifdef CONFIG_NEW_WIN32_CTRL_EVENT
     1165  /* bird: dispatch signals in our own way to try avoid deadlocks. */
     1166  g_tidMainThread = GetCurrentThreadId ();
     1167  SetConsoleCtrlHandler (ctrl_event, TRUE);
     1168#endif /* CONFIG_NEW_WIN32_CTRL_EVENT */
    10971169
    10981170#undef  FATAL_SIG
Note: See TracChangeset for help on using the changeset viewer.