Changeset 50471 in vbox for trunk/src/VBox/Additions/x11/VBoxClient
- Timestamp:
- Feb 14, 2014 5:23:03 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 92310
- Location:
- trunk/src/VBox/Additions/x11/VBoxClient
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/VBoxClient/seamless.cpp
r50374 r50471 36 36 mX11MonitorThread = NIL_RTTHREAD; 37 37 mX11MonitorThreadStopping = false; 38 mHostEventThread = NIL_RTTHREAD;39 mHostEventThreadRunning = false;40 mHostEventThreadStopping = false;41 38 } 42 39 … … 60 57 LogRelFlowFunc(("\n")); 61 58 do { 62 pszStage = "Checking that we are not already running";63 rc = VERR_INTERNAL_ERROR;64 if (mHostEventThread) /* Assertion */65 break;66 59 pszStage = "Testing event loop cancellation"; 67 60 VbglR3InterruptEventWaits(); … … 75 68 if (RT_FAILURE(rc)) 76 69 break; 77 /* Create a thread to wait for requests from the host. This is currently78 * done on a separate thread as the main thread monitors the X11 server79 * for disconnections. */80 /** @todo Move the disconnection monitoring to its own thread (better, the81 * 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;86 70 pszStage = "Setting guest IRQ filter mask"; 87 71 rc = VbglR3CtlFilterMask(VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST, 0); … … 92 76 if (RT_FAILURE(rc)) 93 77 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 } 94 90 } while(0); 95 91 if (RT_FAILURE(rc)) … … 109 105 VbglR3SeamlessSetCap(false); 110 106 VbglR3CtlFilterMask(0, VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST); 111 if (mHostEventThread)112 stopHostEventThread();113 107 stopX11MonitorThread(); 114 108 mX11Monitor.uninit(); … … 175 169 176 170 /** 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 mHostEventThreadStopping190 * 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 too196 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 else236 LogRelThisFunc(("Failed to stop seamless event thread, rc=%Rrc!\n",237 rc));238 LogRelFlowFunc(("returning\n"));239 }240 241 /**242 171 * The actual X11 window configuration change monitor thread function. 243 172 */ … … 294 223 } 295 224 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. */ 296 229 /** VBoxClient service class wrapping the logic for the seamless service while 297 230 * the main VBoxClient code provides the daemon logic needed by all services. … … 309 242 virtual int run(bool fDaemonised /* = false */) 310 243 { 311 Display *pDisplay = NULL;312 const char *pszStage;313 XEvent ev;314 244 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; 340 247 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; 345 252 } 346 253 virtual void cleanup() -
trunk/src/VBox/Additions/x11/VBoxClient/seamless.h
r50376 r50471 44 44 /** Should the X11 monitor thread be stopping? */ 45 45 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;52 46 53 47 /** … … 64 58 void cancelEvent(void) { VbglR3InterruptEventWaits(); } 65 59 66 /** Thread function to query seamless activation and deactivation events67 * from the host. */68 static DECLCALLBACK(int) hostEventThread(RTTHREAD self, void *pvUser);69 70 /** Helper to start the seamless state change notification listener71 * thread. */72 int startHostEventThread();73 74 /** Helper to stop the event query thread again. */75 void stopHostEventThread();76 77 60 /** Thread function to monitor X11 window configuration changes. */ 78 61 static DECLCALLBACK(int) x11MonitorThread(RTTHREAD self, void *pvUser); -
trunk/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
r50373 r50471 115 115 /* Set an X11 error handler, so that we don't die when we get unavoidable errors. */ 116 116 XSetErrorHandler(vboxClientXLibErrorHandler); 117 RTPrintf("\n Press <Enter>to exit...\n");117 RTPrintf("\nType Ctrl-C to exit...\n"); 118 118 RTSemEventCreate(&eventSem); 119 119 /** Our instance of the seamless class. */ … … 125 125 RTPrintf("Failed to initialise seamless Additions, rc = %Rrc\n", rc); 126 126 } 127 RTStrmGetLine(g_pStdIn, ach, sizeof(ach));128 127 return rc; 129 128 }
Note:
See TracChangeset
for help on using the changeset viewer.