VirtualBox

Ignore:
Timestamp:
Jun 5, 2022 8:29:53 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
151709
Message:

VBoxHeadless: Reworked the signal handling for macOS to make it work right, given that processEventQueue won't return VERR_INTERRUPTED after a Ctrl-C was delivered. [build fix, adjustments] bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp

    r95199 r95201  
    4444#include <iprt/env.h>
    4545#include <iprt/errcore.h>
     46#include <iprt/thread.h>
    4647#include <VBoxVideo.h>
    4748
     
    7980static IConsole *gConsole = NULL;
    8081static NativeEventQueue *gEventQ = NULL;
     82/** Inidcates whether gEventQ can safely be used or not. */
     83static volatile bool g_fEventQueueSafe = false;
    8184
    8285/* keep this handy for messages */
     
    8487static com::Utf8Str g_strVMUUID;
    8588
    86 /* flag whether frontend should terminate */
     89/** flag whether frontend should terminate */
    8790static volatile bool g_fTerminateFE = false;
    8891
     
    412415    if (pszThread)
    413416    {
    414         aSegs[cSegs++].iov_base = (char *)" on thread ";
     417        aSegs[cSegs++].iov_base = (char *)"(on thread ";
    415418        aSegs[cSegs++].iov_base = (char *)pszThread;       
    416     }
    417     aSegs[cSegs++].iov_base = (char *)"\n";
     419        aSegs[cSegs++].iov_base = (char *)")\n";
     420    }
     421    else
     422        aSegs[cSegs++].iov_base = (char *)"\n";
    418423    for (int i = 0; i < cSegs; i++)
    419424        aSegs[i].iov_len = strlen((const char *)aSegs[i].iov_base);
     
    485490        if (sigwait(&SigSetWait, &iSignal) == 0)
    486491        {
     492            LogRel(("VBoxHeadless: Caught signal: %s\n", strsignal(iSignal)));
     493            RTMsgInfo("");
     494            RTMsgInfo("Caught signal: %s", strsignal(iSignal));
    487495            g_fTerminateFE = true;
    488             RTMsgInfo("Caught signal: %s\n", strsignal(iSignal));
    489             LogRel(("VBoxHeadless: Caught signal: %s\n", strsignal(iSignal)));
    490496        }
    491497
    492498        /** @todo this is a little bit racy...   */
    493         if (g_fTerminateFE && gEventQ != NULL)
     499        if (g_fTerminateFE && g_fEventQueueSafe && gEventQ != NULL)
    494500            gEventQ->interruptEventQueueProcessing();
    495501    }
     
    769775            /* tell the VM to save state/power off */
    770776            g_fTerminateFE = true;
    771             gEventQ->interruptEventQueueProcessing();
     777            if (g_fEventQueueSafe && gEventQ != NULL)
     778                gEventQ->interruptEventQueueProcessing();
    772779
    773780            if (g_hCanQuit != NIL_RTSEMEVENT)
     
    795802
    796803
    797 static const char * const ctrl_event_names[] = {
     804static const char * const g_apszCtrlEventNames[] =
     805{
    798806    "CTRL_C_EVENT",
    799807    "CTRL_BREAK_EVENT",
     
    811819ConsoleCtrlHandler(DWORD dwCtrlType) RT_NOTHROW_DEF
    812820{
    813     const char *signame;
    814     char namebuf[48];
    815     int rc;
    816 
    817     if (dwCtrlType < RT_ELEMENTS(ctrl_event_names))
    818         signame = ctrl_event_names[dwCtrlType];
     821    const char *pszSigName;
     822    char szNameBuf[48];
     823    if (dwCtrlType < RT_ELEMENTS(g_apszCtrlEventNames))
     824        pszSigName = g_apszCtrlEventNames[dwCtrlType];
    819825    else
    820826    {
    821827        /* should not happen, but be prepared */
    822         RTStrPrintf(namebuf, sizeof(namebuf),
    823                     "<console control event %lu>", (unsigned long)dwCtrlType);
    824         signame = namebuf;
    825     }
    826     LogRel(("VBoxHeadless: got %s\n", signame));
    827     RTMsgInfo("Got %s\n", signame);
     828        RTStrPrintf(szNameBuf, sizeof(szNameBuf), "<console control event %u>", dwCtrlType);
     829        pszSigName = szNameBuf;
     830    }
     831
     832    LogRel(("VBoxHeadless: got %s\n", pszSigName));
     833    RTMsgInfo("Got %s", pszSigName);
    828834    RTMsgInfo("");
    829835
    830836    /* tell the VM to save state/power off */
    831837    g_fTerminateFE = true;
    832     gEventQ->interruptEventQueueProcessing();
     838    if (g_fEventQueueSafe && gEventQ != NULL)
     839        gEventQ->interruptEventQueueProcessing();
    833840
    834841    /*
     
    840847        LogRel(("VBoxHeadless: waiting for VM termination...\n"));
    841848
    842         rc = RTSemEventWait(g_hCanQuit, RT_INDEFINITE_WAIT);
     849        int rc = RTSemEventWait(g_hCanQuit, RT_INDEFINITE_WAIT);
    843850        if (RT_FAILURE(rc))
    844851            LogRel(("VBoxHeadless: Failed to wait for VM termination: %Rrc\n", rc));
     
    12981305        gConsole = console;
    12991306        gEventQ = com::NativeEventQueue::getMainEventQueue();
     1307        g_fEventQueueSafe = true;
    13001308
    13011309        /* VirtualBoxClient events registration. */
     
    15871595    } while (0);
    15881596
     1597    /* No point in trying to post dummy messages to the event queue now. */
     1598    g_fEventQueueSafe = false;
     1599
    15891600    /* VirtualBox callback unregistration. */
    15901601    if (vboxListener)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette