VirtualBox

Changeset 60981 in vbox


Ignore:
Timestamp:
May 13, 2016 5:10:14 PM (9 years ago)
Author:
vboxsync
Message:

DnD/VBoxClient: Use proper initialization callback handler, fixed some memory leaks on termination, better deal with non-available host service.

File:
1 edited

Legend:

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

    r60967 r60981  
    227227
    228228        return m_pInstance;
     229    }
     230
     231    static void destroyInstance(void)
     232    {
     233        if (m_pInstance)
     234        {
     235            delete m_pInstance;
     236            m_pInstance = NULL;
     237        }
    229238    }
    230239
     
    586595public:
    587596    DragAndDropService(void)
    588       : m_pDisplay(0)
     597      : m_pDisplay(NULL)
    589598      , m_hHGCMThread(NIL_RTTHREAD)
    590599      , m_hX11Thread(NIL_RTTHREAD)
    591600      , m_hEventSem(NIL_RTSEMEVENT)
    592       , m_pCurDnD(0)
     601      , m_pCurDnD(NULL)
    593602      , m_fSrvStopping(false)
    594603    {}
    595604
     605    int init(void);
    596606    int run(bool fDaemonised = false);
     607    void cleanup(void);
    597608
    598609private:
    599610
    600     int dragAndDropInit(void);
    601611    static DECLCALLBACK(int) hgcmEventThread(RTTHREAD hThread, void *pvUser);
    602612    static DECLCALLBACK(int) x11EventThread(RTTHREAD hThread, void *pvUser);
     
    29342944
    29352945/**
     2946 * Initializes the drag and drop service.
     2947 *
     2948 * @returns IPRT status code.
     2949 */
     2950int DragAndDropService::init(void)
     2951{
     2952    LogFlowFuncEnter();
     2953
     2954    /* Initialise the guest library. */
     2955    int rc = VbglR3InitUser();
     2956    if (RT_FAILURE(rc))
     2957    {
     2958        VBClFatalError(("DnD: Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
     2959        return rc;
     2960    }
     2961
     2962    /* Connect to the x11 server. */
     2963    m_pDisplay = XOpenDisplay(NULL);
     2964    if (!m_pDisplay)
     2965    {
     2966        VBClFatalError(("DnD: Unable to connect to X server -- running in a terminal session?\n"));
     2967        return VERR_NOT_FOUND;
     2968    }
     2969
     2970    xHelpers *pHelpers = xHelpers::getInstance(m_pDisplay);
     2971    if (!pHelpers)
     2972        return VERR_NO_MEMORY;
     2973
     2974    do
     2975    {
     2976        rc = RTSemEventCreate(&m_hEventSem);
     2977        if (RT_FAILURE(rc))
     2978            break;
     2979
     2980        rc = RTCritSectInit(&m_eventQueueCS);
     2981        if (RT_FAILURE(rc))
     2982            break;
     2983
     2984        /* Event thread for events coming from the HGCM device. */
     2985        rc = RTThreadCreate(&m_hHGCMThread, hgcmEventThread, this,
     2986                            0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, "dndHGCM");
     2987        if (RT_FAILURE(rc))
     2988            break;
     2989
     2990        rc = RTThreadUserWait(m_hHGCMThread, 10 * 1000 /* 10s timeout */);
     2991        if (RT_FAILURE(rc))
     2992            break;
     2993
     2994        if (ASMAtomicReadBool(&m_fSrvStopping))
     2995            break;
     2996
     2997        /* Event thread for events coming from the x11 system. */
     2998        rc = RTThreadCreate(&m_hX11Thread, x11EventThread, this,
     2999                            0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, "dndX11");
     3000        if (RT_FAILURE(rc))
     3001            break;
     3002
     3003        rc = RTThreadUserWait(m_hX11Thread, 10 * 1000 /* 10s timeout */);
     3004        if (RT_FAILURE(rc))
     3005            break;
     3006
     3007        if (ASMAtomicReadBool(&m_fSrvStopping))
     3008            break;
     3009
     3010    } while (0);
     3011
     3012    if (m_fSrvStopping)
     3013        rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */
     3014
     3015    if (RT_FAILURE(rc))
     3016        LogRel(("DnD: Failed to initialize, rc=%Rrc\n", rc));
     3017
     3018    LogFlowFuncLeaveRC(rc);
     3019    return rc;
     3020}
     3021
     3022/**
    29363023 * Main loop for the drag and drop service which does the HGCM message
    29373024 * processing and routing to the according drag and drop instance(s).
     
    29483035    do
    29493036    {
    2950         /* Initialize drag and drop. */
    2951         rc = dragAndDropInit();
    2952         if (RT_FAILURE(rc))
    2953             break;
    2954 
    29553037        m_pCurDnD = new DragInstance(m_pDisplay, this);
    29563038        if (!m_pCurDnD)
     
    31123194    } while (0);
    31133195
     3196    if (m_pCurDnD)
     3197    {
     3198        delete m_pCurDnD;
     3199        m_pCurDnD = NULL;
     3200    }
     3201
     3202    LogFlowFuncLeaveRC(rc);
    31143203    return rc;
    31153204}
    31163205
    3117 /**
    3118  * Initializes the drag and drop instance.
    3119  *
    3120  * @returns IPRT status code.
    3121  */
    3122 int DragAndDropService::dragAndDropInit(void)
    3123 {
    3124     /* Initialise the guest library. */
    3125     int rc = VbglR3InitUser();
    3126     if (RT_FAILURE(rc))
    3127         VBClFatalError(("DnD: Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
    3128 
    3129     /* Connect to the x11 server. */
    3130     m_pDisplay = XOpenDisplay(NULL);
    3131     if (!m_pDisplay)
    3132     {
    3133         VBClFatalError(("DnD: Unable to connect to X server -- running in a terminal session?\n"));
    3134         return VERR_NOT_FOUND;
    3135     }
    3136 
    3137     xHelpers *pHelpers = xHelpers::getInstance(m_pDisplay);
    3138     if (!pHelpers)
    3139         return VERR_NO_MEMORY;
    3140 
    3141     do
    3142     {
    3143         rc = RTSemEventCreate(&m_hEventSem);
    3144         if (RT_FAILURE(rc))
    3145             break;
    3146 
    3147         rc = RTCritSectInit(&m_eventQueueCS);
    3148         if (RT_FAILURE(rc))
    3149             break;
    3150 
    3151         /* Event thread for events coming from the HGCM device. */
    3152         rc = RTThreadCreate(&m_hHGCMThread, hgcmEventThread, this,
    3153                             0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
    3154                             "dndHGCM");
    3155         if (RT_FAILURE(rc))
    3156             break;
    3157 
    3158         /* Event thread for events coming from the x11 system. */
    3159         rc = RTThreadCreate(&m_hX11Thread, x11EventThread, this,
    3160                             0, RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
    3161                             "dndX11");
    3162     } while (0);
    3163 
    3164     /* No clean-up code for now, as we have no good way of testing it and things
    3165      * should get cleaned up when the user process/X11 client exits. */
    3166     if (RT_FAILURE(rc))
    3167         LogRel(("DnD: Failed to start, rc=%Rrc\n", rc));
    3168 
    3169     return rc;
     3206void DragAndDropService::cleanup(void)
     3207{
     3208    LogFlowFuncEnter();
     3209
     3210    LogRel2(("DnD: Terminating threads ...\n"));
     3211
     3212    /*
     3213     * Wait for threads to terminate.
     3214     */
     3215    int rcThread, rc2;
     3216    if (m_hHGCMThread != NIL_RTTHREAD)
     3217    {
     3218        rc2 = RTThreadWait(m_hHGCMThread, 30 * 1000 /* 30s timeout */, &rcThread);
     3219        if (RT_SUCCESS(rc2))
     3220            rc2 = rcThread;
     3221
     3222        if (RT_FAILURE(rc2))
     3223            LogRel(("DnD: Error waiting for HGCM thread to terminate: %Rrc\n", rc2));
     3224    }
     3225
     3226    if (m_hX11Thread != NIL_RTTHREAD)
     3227    {
     3228        rc2 = RTThreadWait(m_hX11Thread, 30 * 1000 /* 30s timeout */, &rcThread);
     3229        if (RT_SUCCESS(rc2))
     3230            rc2 = rcThread;
     3231
     3232        if (RT_FAILURE(rc2))
     3233            LogRel(("DnD: Error waiting for X11 thread to terminate: %Rrc\n", rc2));
     3234    }
     3235
     3236    LogRel2(("DnD: Terminating threads done\n"));
     3237
     3238    xHelpers::destroyInstance();
     3239
     3240    VbglR3Term();
    31703241}
    31713242
     
    31893260    VBGLR3GUESTDNDCMDCTX dndCtx;
    31903261
     3262    /*
     3263     * Initialize thread.
     3264     */
    31913265    int rc = VbglR3DnDConnect(&dndCtx);
    3192     /* Note: Can return VINF_PERMISSION_DENIED if HGCM host service is not available. */
    3193     if (rc != VINF_SUCCESS)
     3266
     3267    /* Set stop indicator on failure. */
     3268    if (RT_FAILURE(rc))
     3269        ASMAtomicXchgBool(&pThis->m_fSrvStopping, true);
     3270
     3271    /* Let the service instance know in any case. */
     3272    int rc2 = RTThreadUserSignal(hThread);
     3273    AssertRC(rc2);
     3274
     3275    if (RT_FAILURE(rc))
    31943276        return rc;
    31953277
     
    32563338    int rc = VINF_SUCCESS;
    32573339
     3340    /* Note: Nothing to initialize here (yet). */
     3341
     3342    /* Set stop indicator on failure. */
     3343    if (RT_FAILURE(rc))
     3344        ASMAtomicXchgBool(&pThis->m_fSrvStopping, true);
     3345
     3346    /* Let the service instance know in any case. */
     3347    int rc2 = RTThreadUserSignal(hThread);
     3348    AssertRC(rc2);
     3349
    32583350    DnDEvent e;
    32593351    do
     
    33293421}
    33303422
     3423static int init(struct VBCLSERVICE **ppInterface)
     3424{
     3425    struct DRAGANDDROPSERVICE *pSelf = (struct DRAGANDDROPSERVICE *)ppInterface;
     3426
     3427    if (pSelf->uMagic != DRAGANDDROPSERVICE_MAGIC)
     3428        VBClFatalError(("Bad DnD service object!\n"));
     3429    return pSelf->mDragAndDrop.init();
     3430}
     3431
    33313432static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
    33323433{
     
    33343435
    33353436    if (pSelf->uMagic != DRAGANDDROPSERVICE_MAGIC)
    3336         VBClFatalError(("Bad display service object!\n"));
     3437        VBClFatalError(("Bad DnD service object!\n"));
    33373438    return pSelf->mDragAndDrop.run(fDaemonised);
    33383439}
     
    33403441static void cleanup(struct VBCLSERVICE **ppInterface)
    33413442{
    3342     NOREF(ppInterface);
    3343     VbglR3Term();
     3443   struct DRAGANDDROPSERVICE *pSelf = (struct DRAGANDDROPSERVICE *)ppInterface;
     3444
     3445    if (pSelf->uMagic != DRAGANDDROPSERVICE_MAGIC)
     3446        VBClFatalError(("Bad DnD service object!\n"));
     3447    return pSelf->mDragAndDrop.cleanup();
    33443448}
    33453449
     
    33473451{
    33483452    getPidFilePath,
    3349     VBClServiceDefaultHandler, /* init */
     3453    init,
    33503454    run,
    33513455    cleanup
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