- Timestamp:
- Feb 5, 2014 7:10:45 PM (11 years ago)
- 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 62 62 seamless-host.cpp \ 63 63 seamless-x11.cpp \ 64 thread.cpp \65 64 display.cpp \ 66 65 hostversion.cpp … … 112 111 testcase/tstSeamlessX11.cpp \ 113 112 seamless-host.cpp \ 114 seamless-x11.cpp \ 115 thread.cpp 113 seamless-x11.cpp 116 114 tstSeamlessX11_LIBPATH = \ 117 115 $(VBOX_LIBPATH_X11) -
trunk/src/VBox/Additions/x11/VBoxClient/seamless-host.cpp
r50324 r50336 25 25 26 26 #include "seamless-host.h" 27 #include "seamless-x11.h" 27 28 28 29 /** … … 35 36 36 37 LogRelFlowFunc(("\n")); 37 if (m Running) /* Assertion */38 if (mThread) /* Assertion */ 38 39 { 39 40 LogRel(("VBoxClient: seamless service started twice!\n")); … … 49 50 { 50 51 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)) 57 56 { 58 57 LogRel(("VBoxClient: failed to start seamless event thread, rc=%Rrc. Disabled seamless capability on host again.\n", rc)); … … 71 70 void VBoxGuestSeamlessHost::stop(RTMSINTERVAL cMillies /* = RT_INDEFINITE_WAIT */) 72 71 { 73 LogRelFlowFunc(("returning\n")); 74 if (!mRunning) /* Assertion */ 75 { 72 LogRelFlowFunc(("\n")); 73 if (!mThread) /* Assertion */ 76 74 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(); 80 79 VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST); 81 80 VbglR3SeamlessSetCap(false); 82 mRunning = false;83 81 LogRelFlowFunc(("returning\n")); 84 82 } … … 106 104 #endif 107 105 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")); 109 112 break; 110 113 case VMMDev_Seamless_Host_Window: … … 120 123 #endif 121 124 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")); 123 129 } 124 130 } … … 146 152 } 147 153 148 /** 149 * The actual thread function. 150 * 151 * @returns iprt status code as thread return value152 * @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 */ 158 int 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) 163 169 { 164 170 /* If we are not stopping, sleep for a bit to avoid using up too 165 171 much CPU while retrying. */ 166 mThread->yield();172 RTThreadYield(); 167 173 } 168 174 } 169 175 } 176 pHost->mThreadRunning = false; 170 177 LogRelFlowFunc(("returning VINF_SUCCESS\n")); 171 178 return VINF_SUCCESS; … … 173 180 174 181 /** 182 * Send a signal to the thread that it should exit 183 */ 184 void 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 */ 213 int 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 /** 175 233 * Send a signal to the thread function that it should exit 176 234 */ 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 } 235 void 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 19 19 # define __Additions_client_seamless_host_h 20 20 21 #include <iprt/thread.h> 22 21 23 #include <VBox/log.h> 22 24 #include <VBox/VBoxGuestLib.h> /* for the R3 guest library functions */ 23 25 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 }; 26 class VBoxGuestSeamlessX11; 63 27 64 28 /** … … 78 42 class VBoxGuestSeamlessHost : public VBoxGuestSeamlessHostInt 79 43 { 80 friend class VBoxGuestSeamlessHostThread;81 44 public: 82 45 /** Events which can be reported by this class */ … … 98 61 /** Thread to start and stop when we enter and leave seamless mode which 99 62 * 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; 103 68 /** 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; 107 74 /** Last request issued by the host. */ 108 75 meEvent mState; … … 120 87 */ 121 88 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); 122 102 123 103 public: 124 104 /** 125 105 * Initialise the guest and ensure that it is capable of handling seamless mode 126 * @param pX11Monitor Thread Thread class to monitorguest windows.106 * @param pX11Monitor Object to monitor X11 guest windows. 127 107 * 128 108 * @returns iprt status code 129 109 */ 130 int init(VBoxGuest Thread *pX11MonitorThread)110 int init(VBoxGuestSeamlessX11 *pX11Monitor) 131 111 { 132 112 LogRelFlowFunc(("\n")); 133 if (mX11Monitor Thread != 0) /* Assertion */113 if (mX11Monitor != NULL) /* Assertion */ 134 114 { 135 115 LogRel(("VBoxClient: ERROR: attempt to initialise seamless host object twice!\n")); 136 116 return VERR_INTERNAL_ERROR; 137 117 } 138 mX11Monitor Thread = pX11MonitorThread;118 mX11Monitor = pX11Monitor; 139 119 LogRelFlowFunc(("returning VINF_SUCCESS\n")); 140 120 return VINF_SUCCESS; … … 161 141 virtual void notify(RTRECT *pRects, size_t cRects); 162 142 163 VBoxGuestSeamlessHost(void) : mThreadFunction(this), 164 mThread(&mThreadFunction, 0, RTTHREADTYPE_MSG_PUMP, 165 RTTHREADFLAGS_WAITABLE, "Host events") 143 VBoxGuestSeamlessHost(void) 166 144 { 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; 169 151 mState = NONE; 170 152 } … … 173 155 { 174 156 LogRelFlowFunc(("\n")); 175 if (m Running) /* Assertion */157 if (mThread) /* Assertion */ 176 158 { 177 159 LogRel(("VBoxClient: seamless host object still running! Stopping...\n")); -
trunk/src/VBox/Additions/x11/VBoxClient/seamless-x11.h
r50324 r50336 147 147 }; 148 148 149 class VBoxGuestSeamlessX11;150 151 149 class VBoxGuestSeamlessX11 152 150 { -
trunk/src/VBox/Additions/x11/VBoxClient/seamless.h
r50324 r50336 24 24 #include "seamless-x11.h" 25 25 26 /** Thread function class for VBoxGuestSeamlessX11. */27 class VBoxGuestSeamlessGuestThread: public VBoxGuestThreadFunction28 {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 sensible36 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 value47 * @param pParent the VBoxGuestThread running this thread function48 */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 exit68 */69 virtual void stop(void) { mGuest->interruptEvent(); }70 };71 72 26 class VBoxGuestSeamless 73 27 { … … 75 29 VBoxGuestSeamlessHost mHost; 76 30 VBoxGuestSeamlessX11 mGuest; 77 VBoxGuestSeamlessGuestThread mGuestFunction;78 VBoxGuestThread mGuestThread;79 31 80 32 bool isInitialised; … … 92 44 if (RT_SUCCESS(rc)) 93 45 { 94 rc = mHost.init(&mGuest Thread);46 rc = mHost.init(&mGuest); 95 47 } 96 48 if (RT_SUCCESS(rc)) … … 120 72 { 121 73 mHost.stop(cMillies); 122 mGuestThread.stop(cMillies, 0);123 74 mGuest.uninit(); 124 75 isInitialised = false; … … 127 78 } 128 79 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; } 135 81 ~VBoxGuestSeamless() { uninit(); } 136 82 };
Note:
See TracChangeset
for help on using the changeset viewer.