VirtualBox

Changeset 89749 in vbox


Ignore:
Timestamp:
Jun 16, 2021 5:00:54 PM (3 years ago)
Author:
vboxsync
Message:

Additions: X11: VBoxClient: VMSVGA: process graceful shutdown, bugref:10028.

  • Prevent X11 listener thread from infinite waiting for XEvent and let it detect that shutdown request was issued.
  • Prevent host listener thread from infinite waiting for host event and let it detect that shutdown request was issued.
  • Fix crash on X11 de-initialisation code path, reorder resources release calls.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/display-svga-x11.cpp

    r89635 r89749  
    6767#define MILLIS_PER_INCH (25.4)
    6868#define DEFAULT_DPI (96.0)
     69
     70/* Time in milliseconds to relax if no X11 events available. */
     71#define VBOX_SVGA_X11_RELAX_TIME_MS  (500)
     72/* Time in milliseconds to wait for host events. */
     73#define VBOX_SVGA_HOST_EVENT_RX_TIMEOUT_MS  (500)
    6974
    7075/** Maximum number of supported screens.  DRM and X11 both limit this to 32. */
     
    579584{
    580585    XEvent event;
    581     XNextEvent(x11Context.pDisplayRandRMonitoring, &event);
    582     int eventTypeOffset = event.type - x11Context.hRandREventBase;
    583     switch (eventTypeOffset)
    584     {
    585         case RRScreenChangeNotify:
    586             VBClLogInfo("RRScreenChangeNotify event received\n");
    587             queryMonitorPositions();
    588             break;
    589         default:
    590             break;
     586
     587    if (XPending(x11Context.pDisplayRandRMonitoring) > 0)
     588    {
     589        XNextEvent(x11Context.pDisplayRandRMonitoring, &event);
     590        int eventTypeOffset = event.type - x11Context.hRandREventBase;
     591        VBClLogInfo("received X11 event (%d)\n", event.type);
     592        switch (eventTypeOffset)
     593        {
     594            case RRScreenChangeNotify:
     595                VBClLogInfo("RRScreenChangeNotify event received\n");
     596                queryMonitorPositions();
     597                break;
     598            default:
     599                break;
     600        }
     601    } else
     602    {
     603        RTThreadSleep(VBOX_SVGA_X11_RELAX_TIME_MS);
    591604    }
    592605}
     
    602615        monitorRandREvents();
    603616    }
     617
     618    VBClLogInfo("X11 thread gracefully terminated\n");
     619
    604620    return 0;
    605621}
     
    623639static int stopX11MonitorThread(void)
    624640{
    625     int rc;
     641    int rc = VINF_SUCCESS;
    626642    if (mX11MonitorThread != NIL_RTTHREAD)
    627643    {
     
    748764static DECLCALLBACK(void) vbclSVGAStop(void)
    749765{
     766    int rc;
     767
     768    rc = stopX11MonitorThread(); /** @todo r=andy We ignore rc!? */
     769    if (RT_FAILURE(rc))
     770    {
     771        VBClLogFatalError("cannot stop X11 monitor thread (%Rrc)\n", rc);
     772        return;
     773    }
     774
    750775    if (mpMonitorPositions)
    751776    {
     
    754779    }
    755780
    756     stopX11MonitorThread(); /** @todo r=andy We ignore rc!? */
     781#ifdef WITH_DISTRO_XRAND_XINERAMA
     782    XRRSelectInput(x11Context.pDisplayRandRMonitoring, x11Context.rootWindow, 0);
     783#else
     784    if (x11Context.pXRRSelectInput)
     785        x11Context.pXRRSelectInput(x11Context.pDisplayRandRMonitoring, x11Context.rootWindow, 0);
     786#endif
     787
     788    XCloseDisplay(x11Context.pDisplay);
     789    XCloseDisplay(x11Context.pDisplayRandRMonitoring);
    757790
    758791    if (x11Context.pRandLibraryHandle)
     
    761794        x11Context.pRandLibraryHandle = NULL;
    762795    }
    763 #ifdef WITH_DISTRO_XRAND_XINERAMA
    764     XRRSelectInput(x11Context.pDisplayRandRMonitoring, x11Context.rootWindow, 0);
    765     XRRFreeScreenResources(x11Context.pScreenResources);
    766 #else
    767     if (x11Context.pXRRSelectInput)
    768         x11Context.pXRRSelectInput(x11Context.pDisplayRandRMonitoring, x11Context.rootWindow, 0);
    769     if (x11Context.pXRRFreeScreenResources)
    770         x11Context.pXRRFreeScreenResources(x11Context.pScreenResources);
    771 #endif
    772     XCloseDisplay(x11Context.pDisplay);
    773     XCloseDisplay(x11Context.pDisplayRandRMonitoring);
    774796}
    775797
     
    13211343static DECLCALLBACK(int) vbclSVGAWorker(bool volatile *pfShutdown)
    13221344{
    1323     RT_NOREF(pfShutdown);
    1324 
    13251345    /* Do not acknowledge the first event we query for to pick up old events,
    13261346     * e.g. from before a guest reboot. */
     
    14091429        do
    14101430        {
    1411             rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, RT_INDEFINITE_WAIT, &events);
    1412         } while (rc == VERR_INTERRUPTED);
    1413         if (RT_FAILURE(rc))
     1431            rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, VBOX_SVGA_HOST_EVENT_RX_TIMEOUT_MS, &events);
     1432        } while (rc == VERR_TIMEOUT && !ASMAtomicReadBool(pfShutdown));
     1433
     1434        if (ASMAtomicReadBool(pfShutdown))
     1435        {
     1436            /* Shutdown requested. */
     1437            break;
     1438        }
     1439        else if (RT_FAILURE(rc))
     1440        {
    14141441            VBClLogFatalError("Failure waiting for event, rc=%Rrc\n", rc);
    1415     }
     1442        }
     1443
     1444    };
     1445
     1446    return VINF_SUCCESS;
    14161447}
    14171448
Note: See TracChangeset for help on using the changeset viewer.

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