VirtualBox

Changeset 85566 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Jul 30, 2020 4:44:19 PM (4 years ago)
Author:
vboxsync
Message:

DnD/VBoxClient: Fixed properly shutting down HGCM thread. bugref:8415.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp

    r85498 r85566  
    642642      , m_hEventSem(NIL_RTSEMEVENT)
    643643      , m_pCurDnD(NULL)
    644       , m_fSrvStopping(false)
    645     {}
     644      , m_fStop(false)
     645    {
     646        RT_ZERO(m_dndCtx);
     647    }
    646648
    647649    int init(void);
     
    665667    RTTHREAD             m_hHGCMThread;
    666668    RTTHREAD             m_hX11Thread;
     669    /** This service' DnD command context. */
     670    VBGLR3GUESTDNDCMDCTX m_dndCtx;
    667671    RTSEMEVENT           m_hEventSem;
    668672    DragInstance        *m_pCurDnD;
    669     bool                 m_fSrvStopping;
     673    /** Stop indicator flag to signal the thread that it should shut down. */
     674    bool                 m_fStop;
    670675
    671676    friend class DragInstance;
     
    30453050    {
    30463051        rc = RTSemEventCreate(&m_hEventSem);
    3047         if (RT_FAILURE(rc))
    3048             break;
     3052        AssertRCBreak(rc);
    30493053
    30503054        rc = RTCritSectInit(&m_eventQueueCS);
    3051         if (RT_FAILURE(rc))
    3052             break;
     3055        AssertRCBreak(rc);
     3056
     3057        rc = VbglR3DnDConnect(&m_dndCtx);
     3058        AssertRCBreak(rc);
    30533059
    30543060        /* Event thread for events coming from the HGCM device. */
    30553061        rc = RTThreadCreate(&m_hHGCMThread, hgcmEventThread, this,
    30563062                            0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, "dndHGCM");
    3057         if (RT_FAILURE(rc))
    3058             break;
     3063        AssertRCBreak(rc);
    30593064
    30603065        rc = RTThreadUserWait(m_hHGCMThread, 10 * 1000 /* 10s timeout */);
    3061         if (RT_FAILURE(rc))
    3062             break;
    3063 
    3064         if (ASMAtomicReadBool(&m_fSrvStopping))
     3066        AssertRCBreak(rc);
     3067
     3068        if (ASMAtomicReadBool(&m_fStop))
    30653069            break;
    30663070
     
    30683072        rc = RTThreadCreate(&m_hX11Thread, x11EventThread, this,
    30693073                            0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, "dndX11");
    3070         if (RT_FAILURE(rc))
    3071             break;
     3074        AssertRCBreak(rc);
    30723075
    30733076        rc = RTThreadUserWait(m_hX11Thread, 10 * 1000 /* 10s timeout */);
    3074         if (RT_FAILURE(rc))
    3075             break;
    3076 
    3077         if (ASMAtomicReadBool(&m_fSrvStopping))
     3077        AssertRCBreak(rc);
     3078
     3079        if (ASMAtomicReadBool(&m_fStop))
    30783080            break;
    30793081
    30803082    } while (0);
    30813083
    3082     if (m_fSrvStopping)
     3084    if (m_fStop)
    30833085        rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */
    30843086
     
    32723274            XFlush(m_pDisplay);
    32733275
    3274         } while (!ASMAtomicReadBool(&m_fSrvStopping));
     3276        } while (!ASMAtomicReadBool(&m_fStop));
    32753277
    32763278        VBClLogInfo("Stopped with rc=%Rrc\n", rc);
     
    32923294    LogFlowFuncEnter();
    32933295
    3294     VBClLogInfo("Terminating threads ...\n");
    3295 
    3296     ASMAtomicXchgBool(&m_fSrvStopping, true);
     3296    VBClLogInfo("Terminating ...\n");
     3297
     3298    /* Set stop flag first. */
     3299    ASMAtomicXchgBool(&m_fStop, true);
     3300
     3301    /* Disconnect from the HGCM host service, which in turn will make the HGCM thread stop. */
     3302    VbglR3DnDDisconnect(&m_dndCtx);
    32973303
    32983304    /*
     
    33023308    if (m_hHGCMThread != NIL_RTTHREAD)
    33033309    {
    3304 #if 0 /** @todo Does not work because we don't cancel the HGCM call! */
     3310        VBClLogInfo("Terminating HGCM thread ...\n");
     3311
    33053312        rc2 = RTThreadWait(m_hHGCMThread, 30 * 1000 /* 30s timeout */, &rcThread);
    3306 #else
    3307         rc2 = RTThreadWait(m_hHGCMThread, 200 /* 200ms timeout */, &rcThread);
    3308 #endif
    33093313        if (RT_SUCCESS(rc2))
    33103314            rc2 = rcThread;
     
    33163320    if (m_hX11Thread != NIL_RTTHREAD)
    33173321    {
    3318 #if 0
    3319         rc2 = RTThreadWait(m_hX11Thread, 30 * 1000 /* 30s timeout */, &rcThread);
    3320 #else
     3322        VBClLogInfo("Terminating X11 thread ...\n");
     3323
    33213324        rc2 = RTThreadWait(m_hX11Thread, 200 /* 200ms timeout */, &rcThread);
    3322 #endif
    33233325        if (RT_SUCCESS(rc2))
    33243326            rc2 = rcThread;
     
    33493351    AssertPtrReturn(pvUser, VERR_INVALID_PARAMETER);
    33503352    DragAndDropService *pThis = static_cast<DragAndDropService*>(pvUser);
    3351     AssertPtr(pThis);
    3352 
    3353     /* This thread has an own DnD context, e.g. an own client ID. */
    3354     VBGLR3GUESTDNDCMDCTX dndCtx;
    3355 
    3356     /*
    3357      * Initialize thread.
    3358      */
    3359     int rc = VbglR3DnDConnect(&dndCtx);
    3360 
    3361     /* Set stop indicator on failure. */
    3362     if (RT_FAILURE(rc))
    3363         ASMAtomicXchgBool(&pThis->m_fSrvStopping, true);
    33643353
    33653354    /* Let the service instance know in any case. */
    3366     int rc2 = RTThreadUserSignal(hThread);
    3367     AssertRC(rc2);
    3368 
    3369     if (RT_FAILURE(rc))
    3370         return rc;
     3355    int rc = RTThreadUserSignal(hThread);
     3356    AssertRCReturn(rc, rc);
    33713357
    33723358    /* Number of invalid messages skipped in a row. */
     
    33803366
    33813367        /* Wait for new events. */
    3382         rc = VbglR3DnDEventGetNext(&dndCtx, &e.hgcm);
     3368        rc = VbglR3DnDEventGetNext(&pThis->m_dndCtx, &e.hgcm);
    33833369        if (RT_SUCCESS(rc))
    33843370        {
     
    33923378        else
    33933379        {
    3394             VBClLogError("Processing next message failed with rc=%Rrc\n", rc);
    3395 
    3396             /* Old(er) hosts either are broken regarding DnD support or otherwise
    3397              * don't support the stuff we do on the guest side, so make sure we
    3398              * don't process invalid messages forever. */
    3399             if (cMsgSkippedInvalid++ > 32)
     3380            if (rc == VERR_INTERRUPTED) /* Can happen due to disconnect, for instance. */
     3381                rc = VINF_SUCCESS;
     3382
     3383            if (RT_FAILURE(rc))
    34003384            {
    3401                 VBClLogError("Too many invalid/skipped messages from host, exiting ...\n");
    3402                 break;
     3385                VBClLogError("Processing next message failed with rc=%Rrc\n", rc);
     3386
     3387                /* Old(er) hosts either are broken regarding DnD support or otherwise
     3388                 * don't support the stuff we do on the guest side, so make sure we
     3389                 * don't process invalid messages forever. */
     3390
     3391                if (cMsgSkippedInvalid++ > 32)
     3392                {
     3393                    VBClLogError("Too many invalid/skipped messages from host, exiting ...\n");
     3394                    break;
     3395                }
    34033396            }
    34043397        }
    34053398
    3406     } while (!ASMAtomicReadBool(&pThis->m_fSrvStopping));
    3407 
    3408     VbglR3DnDDisconnect(&dndCtx);
     3399    } while (!ASMAtomicReadBool(&pThis->m_fStop));
    34093400
    34103401    LogFlowFuncLeaveRC(rc);
     
    34333424    /* Set stop indicator on failure. */
    34343425    if (RT_FAILURE(rc))
    3435         ASMAtomicXchgBool(&pThis->m_fSrvStopping, true);
     3426        ASMAtomicXchgBool(&pThis->m_fStop, true);
    34363427
    34373428    /* Let the service instance know in any case. */
     
    34853476            RTThreadSleep(25 /* ms */);
    34863477
    3487     } while (!ASMAtomicReadBool(&pThis->m_fSrvStopping));
     3478    } while (!ASMAtomicReadBool(&pThis->m_fStop));
    34883479
    34893480    LogFlowFuncLeaveRC(rc);
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