VirtualBox

Ignore:
Timestamp:
Feb 14, 2014 5:23:03 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
92310
Message:

Additions/x11/VBoxClient: remove the host event thread and run the code on the main thread.

Location:
trunk/src/VBox/Additions/x11/VBoxClient
Files:
3 edited

Legend:

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

    r50374 r50471  
    3636    mX11MonitorThread = NIL_RTTHREAD;
    3737    mX11MonitorThreadStopping = false;
    38     mHostEventThread = NIL_RTTHREAD;
    39     mHostEventThreadRunning = false;
    40     mHostEventThreadStopping = false;
    4138}
    4239
     
    6057    LogRelFlowFunc(("\n"));
    6158    do {
    62         pszStage = "Checking that we are not already running";
    63         rc = VERR_INTERNAL_ERROR;
    64         if (mHostEventThread)  /* Assertion */
    65             break;
    6659        pszStage = "Testing event loop cancellation";
    6760        VbglR3InterruptEventWaits();
     
    7568        if (RT_FAILURE(rc))
    7669            break;
    77         /* Create a thread to wait for requests from the host.  This is currently
    78          * done on a separate thread as the main thread monitors the X11 server
    79          * for disconnections. */
    80         /** @todo Move the disconnection monitoring to its own thread (better, the
    81          *  VT monitor thread) and run this logic on the main service thread. */
    82         pszStage = "Starting host event thread";
    83         rc = startHostEventThread();
    84         if (RT_FAILURE(rc))
    85             break;
    8670        pszStage = "Setting guest IRQ filter mask";
    8771        rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0);
     
    9276        if (RT_FAILURE(rc))
    9377            break;
     78        pszStage = "Running event loop";
     79        /* This will only exit if something goes wrong. */
     80        /** @todo Add a "stopping" variable.  Actually "pausing" the service
     81         * should be enough. */
     82        while (RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN || rc == VERR_INTERRUPTED)
     83        {
     84            if (RT_FAILURE(rc))
     85                /* If we are not stopping, sleep for a bit to avoid using up too
     86                    much CPU while retrying. */
     87                RTThreadYield();
     88            rc = nextStateChangeEvent();
     89        }
    9490    } while(0);
    9591    if (RT_FAILURE(rc))
     
    109105    VbglR3SeamlessSetCap(false);
    110106    VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
    111     if (mHostEventThread)
    112         stopHostEventThread();
    113107    stopX11MonitorThread();
    114108    mX11Monitor.uninit();
     
    175169
    176170/**
    177  * Thread to listen for seamless state change notifications from the host.
    178  */
    179 int SeamlessMain::hostEventThread(RTTHREAD self, void *pvUser)
    180 {
    181     SeamlessMain *pHost = (SeamlessMain *)pvUser;
    182 
    183     LogRelFlowFunc(("\n"));
    184     pHost->mHostEventThreadRunning = true;
    185     if (0 != pHost)
    186     {
    187         while (!pHost->mHostEventThreadStopping)
    188         {
    189             /* This thread is stopped by setting @a mHostEventThreadStopping
    190              * and sending a cancel to the state change event wait, see below.
    191              */
    192             int rc = pHost->nextStateChangeEvent();
    193             if (RT_FAILURE(rc) && !pHost->mHostEventThreadStopping)
    194             {
    195                 /* If we are not stopping, sleep for a bit to avoid using up too
    196                     much CPU while retrying. */
    197                 RTThreadYield();
    198             }
    199         }
    200     }
    201     pHost->mHostEventThreadRunning = false;
    202     return VINF_SUCCESS;
    203 }
    204 
    205 /**
    206  * Start the seamless state change notification listener thread.
    207  */
    208 int SeamlessMain::startHostEventThread()
    209 {
    210     int rc;
    211 
    212     mHostEventThreadStopping = false;
    213     rc = RTThreadCreate(&mHostEventThread, hostEventThread, this, 0,
    214                         RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
    215                         "Host events");
    216     if (RT_FAILURE(rc))
    217         LogRel(("VBoxClient: failed to start seamless event thread, rc=%Rrc.\n",
    218                 rc));
    219     return rc;
    220 }
    221 
    222 /**
    223  * Send a signal to the host event thread that it should exit and poke it.
    224  */
    225 void SeamlessMain::stopHostEventThread()
    226 {
    227     int rc;
    228 
    229     LogRelFlowFunc(("\n"));
    230     mHostEventThreadStopping = true;
    231     cancelEvent();
    232     rc = RTThreadWait(mHostEventThread, RT_INDEFINITE_WAIT, NULL);
    233     if (RT_SUCCESS(rc))
    234         mHostEventThread = NIL_RTTHREAD;
    235     else
    236         LogRelThisFunc(("Failed to stop seamless event thread, rc=%Rrc!\n",
    237                         rc));
    238     LogRelFlowFunc(("returning\n"));
    239 }
    240 
    241 /**
    242171 * The actual X11 window configuration change monitor thread function.
    243172 */
     
    294223}
    295224
     225/** @todo Re-arrange the service to support pausing and resuming.  The state
     226 * needs to become more complex: we need to know: whether seamless is currently
     227 * requested by the host; whether we are currently in charge of the guest
     228 * desktop; whether the guest monitoring thead is currently active. */
    296229/** VBoxClient service class wrapping the logic for the seamless service while
    297230 *  the main VBoxClient code provides the daemon logic needed by all services.
     
    309242    virtual int run(bool fDaemonised /* = false */)
    310243    {
    311         Display *pDisplay = NULL;
    312         const char *pszStage;
    313         XEvent ev;
    314244        int rc;
    315 
    316         do {
    317             pszStage = "Checking that we are not already running";
    318             rc = VERR_INTERNAL_ERROR;
    319             if (mIsInitialised)  /* Assertion */
    320                 break;
    321             pszStage = "Connecting to the X server";
    322             rc = VERR_INTERNAL_ERROR;
    323             pDisplay = XOpenDisplay(NULL);
    324             if (!pDisplay)
    325                 break;
    326             pszStage = "Starting the service";
    327             rc = mSeamless.start();
    328             if (RT_FAILURE(rc))
    329                 break;
    330         } while(0);
    331         if (RT_FAILURE(rc))
    332         {
    333             LogRelFunc(("VBoxClient seamless service control: failed at stage: \"%s\".  Error: %Rrc\n",
    334                         pszStage, rc));
    335             mSeamless.stop();
    336             if (pDisplay)
    337                 XCloseDisplay(pDisplay);
    338             return rc;
    339         }
     245        if (mIsInitialised)
     246            return VERR_INTERNAL_ERROR;
    340247        mIsInitialised = true;
    341         /* Stay running as long as X does... */
    342         while (true)
    343             XNextEvent(pDisplay, &ev);
    344         return VERR_INTERRUPTED;
     248        rc = mSeamless.start();
     249        LogRelFunc(("VBoxClient: seamless service failed to start.  Error: %Rrc\n",
     250                    rc));
     251        return rc;
    345252    }
    346253    virtual void cleanup()
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless.h

    r50376 r50471  
    4444    /** Should the X11 monitor thread be stopping? */
    4545    volatile bool mX11MonitorThreadStopping;
    46     /** Host seamless event thread. */
    47     RTTHREAD mHostEventThread;
    48     /** Is the thread running? */
    49     volatile bool mHostEventThreadRunning;
    50     /** Should the thread be stopping? */
    51     volatile bool mHostEventThreadStopping;
    5246
    5347    /**
     
    6458    void cancelEvent(void) { VbglR3InterruptEventWaits(); }
    6559   
    66     /** Thread function to query seamless activation and deactivation events
    67      *  from the host. */
    68     static DECLCALLBACK(int) hostEventThread(RTTHREAD self, void *pvUser);
    69 
    70     /** Helper to start the seamless state change notification listener
    71      * thread. */
    72     int startHostEventThread();
    73 
    74     /** Helper to stop the event query thread again. */
    75     void stopHostEventThread();
    76 
    7760    /** Thread function to monitor X11 window configuration changes. */
    7861    static DECLCALLBACK(int) x11MonitorThread(RTTHREAD self, void *pvUser);
  • trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp

    r50373 r50471  
    115115    /* Set an X11 error handler, so that we don't die when we get unavoidable errors. */
    116116    XSetErrorHandler(vboxClientXLibErrorHandler);
    117     RTPrintf("\nPress <Enter> to exit...\n");
     117    RTPrintf("\nType Ctrl-C to exit...\n");
    118118    RTSemEventCreate(&eventSem);
    119119    /** Our instance of the seamless class. */
     
    125125        RTPrintf("Failed to initialise seamless Additions, rc = %Rrc\n", rc);
    126126    }
    127     RTStrmGetLine(g_pStdIn, ach, sizeof(ach));
    128127    return rc;
    129128}
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