VirtualBox

Changeset 50336 in vbox for trunk


Ignore:
Timestamp:
Feb 5, 2014 7:10:45 PM (11 years ago)
Author:
vboxsync
Message:

Additions/x11/VBoxClient: removed more unnecessary abstraction.

Location:
trunk/src/VBox/Additions/x11/VBoxClient
Files:
2 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk

    r49877 r50336  
    6262        seamless-host.cpp \
    6363        seamless-x11.cpp \
    64         thread.cpp \
    6564        display.cpp \
    6665        hostversion.cpp
     
    112111           testcase/tstSeamlessX11.cpp \
    113112           seamless-host.cpp \
    114            seamless-x11.cpp \
    115            thread.cpp
     113           seamless-x11.cpp
    116114   tstSeamlessX11_LIBPATH = \
    117115           $(VBOX_LIBPATH_X11)
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp

    r50324 r50336  
    2525
    2626#include "seamless-host.h"
     27#include "seamless-x11.h"
    2728
    2829/**
     
    3536
    3637    LogRelFlowFunc(("\n"));
    37     if (mRunning)  /* Assertion */
     38    if (mThread)  /* Assertion */
    3839    {
    3940        LogRel(("VBoxClient: seamless service started twice!\n"));
     
    4950    {
    5051        LogRel(("VBoxClient: enabled seamless capability on host.\n"));
    51         rc = mThread.start();
    52         if (RT_SUCCESS(rc))
    53         {
    54             mRunning = true;
    55         }
    56         else
     52        rc = RTThreadCreate(&mThread, threadFunction, this, 0,
     53                            RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE,
     54                            "Host events");
     55        if (RT_FAILURE(rc))
    5756        {
    5857            LogRel(("VBoxClient: failed to start seamless event thread, rc=%Rrc.  Disabled seamless capability on host again.\n", rc));
     
    7170void VBoxGuestSeamlessHost::stop(RTMSINTERVAL cMillies /* = RT_INDEFINITE_WAIT */)
    7271{
    73     LogRelFlowFunc(("returning\n"));
    74     if (!mRunning)  /* Assertion */
    75     {
     72    LogRelFlowFunc(("\n"));
     73    if (!mThread)  /* Assertion */
    7674        LogRel(("VBoxClient: tried to stop seamless service which is not running!\n"));
    77         return;
    78     }
    79     mThread.stop(cMillies, 0);
     75    else
     76        stopThread(cMillies);
     77    if (mX11MonitorRTThread)
     78        stopX11Thread();
    8079    VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST);
    8180    VbglR3SeamlessSetCap(false);
    82     mRunning = false;
    8381    LogRelFlowFunc(("returning\n"));
    8482}
     
    106104#endif
    107105                mState = ENABLE;
    108                 mX11MonitorThread->start();
     106                mX11ThreadStopping = false;
     107                /** @todo Do something on failure, like bail out. */
     108                if (RT_FAILURE(RTThreadCreate(&mX11MonitorRTThread,
     109                               x11ThreadFunction, this, 0, RTTHREADTYPE_MSG_PUMP,
     110                               RTTHREADFLAGS_WAITABLE, "X11 events")))
     111                    LogRelFunc(("Warning: failed to start X11 monitor thread (VBoxClient).\n"));
    109112                break;
    110113            case VMMDev_Seamless_Host_Window:
     
    120123#endif
    121124                mState = DISABLE;
    122                 mX11MonitorThread->stop(RT_INDEFINITE_WAIT, 0);
     125                if (mX11MonitorRTThread)
     126                    stopX11Thread();
     127                else
     128                    LogRelThisFunc(("Attempted to stop X11 monitor thread which is not running (VBoxClient)!\n"));
    123129        }
    124130    }
     
    146152}
    147153
    148 /**
    149  * The actual thread function.
    150  *
    151  * @returns iprt status code as thread return value
    152  * @param pParent the VBoxGuestThread running this thread function
    153  */
    154 int VBoxGuestSeamlessHostThread::threadFunction(VBoxGuestThread *pThread)
    155 {
    156     LogRelFlowFunc(("\n"));
    157     if (0 != mHost)
    158     {
    159         mThread = pThread;
    160         while (!mThread->isStopping())
    161         {
    162             if (RT_FAILURE(mHost->nextEvent()) && !mThread->isStopping())
     154
     155/**
     156 * The actual event thread function.
     157 */
     158int VBoxGuestSeamlessHost::threadFunction(RTTHREAD self, void *pvUser)
     159{
     160    VBoxGuestSeamlessHost *pHost = (VBoxGuestSeamlessHost *)pvUser;
     161
     162    LogRelFlowFunc(("\n"));
     163    pHost->mThreadRunning = true;
     164    if (0 != pHost)
     165    {
     166        while (!pHost->mThreadStopping)
     167        {
     168            if (RT_FAILURE(pHost->nextEvent()) && !pHost->mThreadStopping)
    163169            {
    164170                /* If we are not stopping, sleep for a bit to avoid using up too
    165171                    much CPU while retrying. */
    166                 mThread->yield();
     172                RTThreadYield();
    167173            }
    168174        }
    169175    }
     176    pHost->mThreadRunning = false;
    170177    LogRelFlowFunc(("returning VINF_SUCCESS\n"));
    171178    return VINF_SUCCESS;
     
    173180
    174181/**
     182 * Send a signal to the thread that it should exit
     183 */
     184void VBoxGuestSeamlessHost::stopThread(RTMSINTERVAL cMillies)
     185{
     186    int rc;
     187
     188    LogRelFlowFunc(("\n"));
     189    /**
     190     * @todo is this reasonable?  If the thread is in the event loop then the cancelEvent()
     191     *       will cause it to exit.  If it enters or exits the event loop it will also
     192     *       notice that we wish it to exit.  And if it is somewhere in-between, the
     193     *       yield() should give it time to get to one of places mentioned above.
     194     */
     195    mThreadStopping = true;
     196    for (int i = 0; (i < 5) && mThreadRunning; ++i)
     197    {
     198        cancelEvent();
     199        RTThreadYield();
     200    }
     201    rc = RTThreadWait(mThread, RT_INDEFINITE_WAIT, NULL);
     202    if (RT_SUCCESS(rc))
     203        mThread = NIL_RTTHREAD;
     204    else
     205        LogRelThisFunc(("Failed to stop seamless event thread, rc=%Rrc!\n",
     206                        rc));
     207    LogRelFlowFunc(("returning\n"));
     208}
     209
     210/**
     211 * The actual X11 event thread function.
     212 */
     213int VBoxGuestSeamlessHost::x11ThreadFunction(RTTHREAD self, void *pvUser)
     214{
     215    VBoxGuestSeamlessHost *pHost = (VBoxGuestSeamlessHost *)pvUser;
     216    int rc = VINF_SUCCESS;
     217
     218    LogRelFlowFunc(("\n"));
     219    rc = pHost->mX11Monitor->start();
     220    if (RT_SUCCESS(rc))
     221    {
     222        while (!pHost->mX11ThreadStopping)
     223        {
     224            pHost->mX11Monitor->nextEvent();
     225        }
     226        pHost->mX11Monitor->stop();
     227    }
     228    LogRelFlowFunc(("returning %Rrc\n", rc));
     229    return rc;
     230}
     231
     232/**
    175233 * Send a signal to the thread function that it should exit
    176234 */
    177 void VBoxGuestSeamlessHostThread::stop(void)
    178 {
    179     LogRelFlowFunc(("\n"));
    180     if (0 != mHost)
    181     {
    182         /**
    183          * @todo is this reasonable?  If the thread is in the event loop then the cancelEvent()
    184          *       will cause it to exit.  If it enters or exits the event loop it will also
    185          *       notice that we wish it to exit.  And if it is somewhere in-between, the
    186          *       yield() should give it time to get to one of places mentioned above.
    187          */
    188         for (int i = 0; (i < 5) && mThread->isRunning(); ++i)
    189         {
    190             mHost->cancelEvent();
    191             mThread->yield();
    192         }
    193     }
    194     LogRelFlowFunc(("returning\n"));
    195 }
     235void VBoxGuestSeamlessHost::stopX11Thread(void)
     236{
     237    int rc;
     238
     239    mX11ThreadStopping = true;
     240    mX11Monitor->interruptEvent();
     241    rc = RTThreadWait(mX11MonitorRTThread, RT_INDEFINITE_WAIT, NULL);
     242    if (RT_SUCCESS(rc))
     243        mX11MonitorRTThread = NIL_RTTHREAD;
     244    else
     245        LogRelThisFunc(("Failed to stop X11 monitor thread, rc=%Rrc!\n",
     246                        rc));
     247}
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.h

    r50324 r50336  
    1919# define __Additions_client_seamless_host_h
    2020
     21#include <iprt/thread.h>
     22
    2123#include <VBox/log.h>
    2224#include <VBox/VBoxGuestLib.h>      /* for the R3 guest library functions  */
    2325
    24 #include "thread.h"                 /* for VBoxGuestThread */
    25 
    26 class VBoxGuestSeamlessHost;
    27 
    28 /**
    29  * Host event (i.e. enter or leave seamless mode) thread function for the main
    30  * seamless class
    31  */
    32 class VBoxGuestSeamlessHostThread : public VBoxGuestThreadFunction
    33 {
    34 private:
    35     // Copying or assigning a thread object is not sensible
    36     VBoxGuestSeamlessHostThread(const VBoxGuestSeamlessHostThread&);
    37     VBoxGuestSeamlessHostThread& operator=(const VBoxGuestSeamlessHostThread&);
    38 
    39     // Private member variables
    40     /** The host proxy object */
    41     VBoxGuestSeamlessHost *mHost;
    42 
    43     /** The thread object running us. */
    44     VBoxGuestThread *mThread;
    45 public:
    46     VBoxGuestSeamlessHostThread(VBoxGuestSeamlessHost *pHost)
    47     {
    48         mHost = pHost;
    49     }
    50     virtual ~VBoxGuestSeamlessHostThread(void) {}
    51     /**
    52       * The actual thread function.
    53       *
    54       * @returns iprt status code as thread return value
    55       * @param pParent the VBoxGuestThread running this thread function
    56       */
    57     virtual int threadFunction(VBoxGuestThread *pThread);
    58     /**
    59      * Send a signal to the thread function that it should exit
    60      */
    61     virtual void stop(void);
    62 };
     26class VBoxGuestSeamlessX11;
    6327
    6428/**
     
    7842class VBoxGuestSeamlessHost : public VBoxGuestSeamlessHostInt
    7943{
    80     friend class VBoxGuestSeamlessHostThread;
    8144public:
    8245    /** Events which can be reported by this class */
     
    9861    /** Thread to start and stop when we enter and leave seamless mode which
    9962     *  monitors X11 windows in the guest. */
    100     VBoxGuestThread *mX11MonitorThread;
    101     /** Host seamless event (i.e. enter and leave) thread function. */
    102     VBoxGuestSeamlessHostThread mThreadFunction;
     63    RTTHREAD mX11MonitorRTThread;
     64    /** X11 event monitor class */
     65    VBoxGuestSeamlessX11 *mX11Monitor;
     66    /** Should the X11 monitor thread be stopping? */
     67    volatile bool mX11ThreadStopping;
    10368    /** Host seamless event thread. */
    104     VBoxGuestThread mThread;
    105     /** Is the service running? */
    106     bool mRunning;
     69    RTTHREAD mThread;
     70    /** Is the thread running? */
     71    volatile bool mThreadRunning;
     72    /** Should the thread be stopping? */
     73    volatile bool mThreadStopping;
    10774    /** Last request issued by the host. */
    10875    meEvent mState;
     
    12087     */
    12188    void cancelEvent(void) { VbglR3InterruptEventWaits(); }
     89   
     90    /** Thread function to query seamless activation and deactivation events
     91     *  from the host. */
     92    static DECLCALLBACK(int) threadFunction(RTTHREAD self, void *pvUser);
     93
     94    /** Helper to stop the event query thread again. */
     95    void stopThread(RTMSINTERVAL cMillies);
     96
     97    /** Thread function to monitor X11 window configuration changes. */
     98    static DECLCALLBACK(int) x11ThreadFunction(RTTHREAD self, void *pvUser);
     99
     100    /** Helper to stop the X11 monitor thread again. */
     101    void stopX11Thread(void);
    122102
    123103public:
    124104    /**
    125105     * Initialise the guest and ensure that it is capable of handling seamless mode
    126      * @param   pX11MonitorThread Thread class to monitor guest windows.
     106     * @param   pX11Monitor Object to monitor X11 guest windows.
    127107     *
    128108     * @returns iprt status code
    129109     */
    130     int init(VBoxGuestThread *pX11MonitorThread)
     110    int init(VBoxGuestSeamlessX11 *pX11Monitor)
    131111    {
    132112        LogRelFlowFunc(("\n"));
    133         if (mX11MonitorThread != 0)  /* Assertion */
     113        if (mX11Monitor != NULL)  /* Assertion */
    134114        {
    135115            LogRel(("VBoxClient: ERROR: attempt to initialise seamless host object twice!\n"));
    136116            return VERR_INTERNAL_ERROR;
    137117        }
    138         mX11MonitorThread = pX11MonitorThread;
     118        mX11Monitor = pX11Monitor;
    139119        LogRelFlowFunc(("returning VINF_SUCCESS\n"));
    140120        return VINF_SUCCESS;
     
    161141    virtual void notify(RTRECT *pRects, size_t cRects);
    162142
    163     VBoxGuestSeamlessHost(void) : mThreadFunction(this),
    164                                   mThread(&mThreadFunction, 0, RTTHREADTYPE_MSG_PUMP,
    165                                   RTTHREADFLAGS_WAITABLE, "Host events")
     143    VBoxGuestSeamlessHost(void)
    166144    {
    167         mX11MonitorThread = 0;
    168         mRunning = false;
     145        mX11MonitorRTThread = NIL_RTTHREAD;
     146        mX11Monitor = NULL;
     147        mX11ThreadStopping = false;
     148        mThread = NIL_RTTHREAD;
     149        mThreadRunning = false;
     150        mThreadStopping = false;
    169151        mState = NONE;
    170152    }
     
    173155    {
    174156        LogRelFlowFunc(("\n"));
    175         if (mRunning)  /* Assertion */
     157        if (mThread)  /* Assertion */
    176158        {
    177159            LogRel(("VBoxClient: seamless host object still running!  Stopping...\n"));
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h

    r50324 r50336  
    147147};
    148148
    149 class VBoxGuestSeamlessX11;
    150 
    151149class VBoxGuestSeamlessX11
    152150{
  • trunk/src/VBox/Additions/x11/VBoxClient/seamless.h

    r50324 r50336  
    2424#include "seamless-x11.h"
    2525
    26 /** Thread function class for VBoxGuestSeamlessX11. */
    27 class VBoxGuestSeamlessGuestThread: public VBoxGuestThreadFunction
    28 {
    29 private:
    30     /** The guest class "owning" us. */
    31     VBoxGuestSeamlessX11 *mGuest;
    32     /** Should we exit the thread? */
    33     bool mExit;
    34 
    35     // Copying or assigning a thread object is not sensible
    36     VBoxGuestSeamlessGuestThread(const VBoxGuestSeamlessGuestThread&);
    37     VBoxGuestSeamlessGuestThread& operator=(const VBoxGuestSeamlessGuestThread&);
    38 
    39 public:
    40     VBoxGuestSeamlessGuestThread(VBoxGuestSeamlessX11 *pGuest)
    41     { mGuest = pGuest; mExit = false; }
    42     virtual ~VBoxGuestSeamlessGuestThread(void) {}
    43     /**
    44       * The actual thread function.
    45       *
    46       * @returns iprt status code as thread return value
    47       * @param pParent the VBoxGuestThread running this thread function
    48       */
    49     virtual int threadFunction(VBoxGuestThread *pThread)
    50     {
    51         int rc = VINF_SUCCESS;
    52 
    53         LogRelFlowFunc(("\n"));
    54         rc = mGuest->start();
    55         if (RT_SUCCESS(rc))
    56         {
    57             while (!pThread->isStopping())
    58             {
    59                 mGuest->nextEvent();
    60             }
    61             mGuest->stop();
    62         }
    63         LogRelFlowFunc(("returning %Rrc\n", rc));
    64         return rc;
    65     }
    66     /**
    67      * Send a signal to the thread function that it should exit
    68      */
    69     virtual void stop(void) { mGuest->interruptEvent(); }
    70 };
    71 
    7226class VBoxGuestSeamless
    7327{
     
    7529    VBoxGuestSeamlessHost mHost;
    7630    VBoxGuestSeamlessX11 mGuest;
    77     VBoxGuestSeamlessGuestThread mGuestFunction;
    78     VBoxGuestThread mGuestThread;
    7931
    8032    bool isInitialised;
     
    9244        if (RT_SUCCESS(rc))
    9345        {
    94             rc = mHost.init(&mGuestThread);
     46            rc = mHost.init(&mGuest);
    9547        }
    9648        if (RT_SUCCESS(rc))
     
    12072        {
    12173            mHost.stop(cMillies);
    122             mGuestThread.stop(cMillies, 0);
    12374            mGuest.uninit();
    12475            isInitialised = false;
     
    12778    }
    12879
    129     VBoxGuestSeamless() : mGuestFunction(&mGuest),
    130                           mGuestThread(&mGuestFunction, 0, RTTHREADTYPE_MSG_PUMP,
    131                                        RTTHREADFLAGS_WAITABLE, "Guest events")
    132     {
    133         isInitialised = false;
    134     }
     80    VBoxGuestSeamless() { isInitialised = false; }
    13581    ~VBoxGuestSeamless() { uninit(); }
    13682};
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