Changeset 60981 in vbox
- Timestamp:
- May 13, 2016 5:10:14 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp
r60967 r60981 227 227 228 228 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 } 229 238 } 230 239 … … 586 595 public: 587 596 DragAndDropService(void) 588 : m_pDisplay( 0)597 : m_pDisplay(NULL) 589 598 , m_hHGCMThread(NIL_RTTHREAD) 590 599 , m_hX11Thread(NIL_RTTHREAD) 591 600 , m_hEventSem(NIL_RTSEMEVENT) 592 , m_pCurDnD( 0)601 , m_pCurDnD(NULL) 593 602 , m_fSrvStopping(false) 594 603 {} 595 604 605 int init(void); 596 606 int run(bool fDaemonised = false); 607 void cleanup(void); 597 608 598 609 private: 599 610 600 int dragAndDropInit(void);601 611 static DECLCALLBACK(int) hgcmEventThread(RTTHREAD hThread, void *pvUser); 602 612 static DECLCALLBACK(int) x11EventThread(RTTHREAD hThread, void *pvUser); … … 2934 2944 2935 2945 /** 2946 * Initializes the drag and drop service. 2947 * 2948 * @returns IPRT status code. 2949 */ 2950 int 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 /** 2936 3023 * Main loop for the drag and drop service which does the HGCM message 2937 3024 * processing and routing to the according drag and drop instance(s). … … 2948 3035 do 2949 3036 { 2950 /* Initialize drag and drop. */2951 rc = dragAndDropInit();2952 if (RT_FAILURE(rc))2953 break;2954 2955 3037 m_pCurDnD = new DragInstance(m_pDisplay, this); 2956 3038 if (!m_pCurDnD) … … 3112 3194 } while (0); 3113 3195 3196 if (m_pCurDnD) 3197 { 3198 delete m_pCurDnD; 3199 m_pCurDnD = NULL; 3200 } 3201 3202 LogFlowFuncLeaveRC(rc); 3114 3203 return rc; 3115 3204 } 3116 3205 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; 3206 void 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(); 3170 3241 } 3171 3242 … … 3189 3260 VBGLR3GUESTDNDCMDCTX dndCtx; 3190 3261 3262 /* 3263 * Initialize thread. 3264 */ 3191 3265 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)) 3194 3276 return rc; 3195 3277 … … 3256 3338 int rc = VINF_SUCCESS; 3257 3339 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 3258 3350 DnDEvent e; 3259 3351 do … … 3329 3421 } 3330 3422 3423 static 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 3331 3432 static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised) 3332 3433 { … … 3334 3435 3335 3436 if (pSelf->uMagic != DRAGANDDROPSERVICE_MAGIC) 3336 VBClFatalError(("Bad displayservice object!\n"));3437 VBClFatalError(("Bad DnD service object!\n")); 3337 3438 return pSelf->mDragAndDrop.run(fDaemonised); 3338 3439 } … … 3340 3441 static void cleanup(struct VBCLSERVICE **ppInterface) 3341 3442 { 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(); 3344 3448 } 3345 3449 … … 3347 3451 { 3348 3452 getPidFilePath, 3349 VBClServiceDefaultHandler, /* init */3453 init, 3350 3454 run, 3351 3455 cleanup
Note:
See TracChangeset
for help on using the changeset viewer.