Changeset 22847 in vbox for trunk/src/VBox/Main/glue
- Timestamp:
- Sep 8, 2009 8:37:54 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 52083
- Location:
- trunk/src/VBox/Main/glue
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/glue/EventQueue.cpp
r22722 r22847 69 69 70 70 #endif // !defined (RT_OS_WINDOWS) 71 72 EventQueue* EventQueue::mMainQueue = NULL; 71 73 72 74 /** … … 146 148 } 147 149 150 /* static */ int EventQueue::init() 151 { 152 mMainQueue = new EventQueue(); 153 #if defined (VBOX_WITH_XPCOM) 154 nsCOMPtr<nsIEventQueue> q; 155 nsresult rv = NS_GetMainEventQ(getter_AddRefs(q)); 156 Assert(NS_SUCCEEDED(rv)); 157 Assert(q == mMainQueue->mEventQ); 158 PRBool fIsNative = PR_FALSE; 159 rv = mMainQueue->mEventQ->IsQueueNative(&fIsNative); 160 Assert(NS_SUCCEEDED(rv) && fIsNative); 161 #endif 162 return VINF_SUCCESS; 163 } 164 165 /* static */ int EventQueue::deinit() 166 { 167 delete mMainQueue; 168 mMainQueue = NULL; 169 return VINF_SUCCESS; 170 } 171 172 /* static */ EventQueue* EventQueue::getMainEventQueue() 173 { 174 return mMainQueue; 175 } 176 177 #ifdef RT_OS_DARWIN 178 static int 179 timedWaitForEventsOnDarwin(nsIEventQueue *pQueue, PRInt32 cMsTimeout) 180 { 181 // This deals with the common case where the caller is the main 182 // application thread and the queue is a native one. 183 OSStatus orc = -1; 184 CFTimeInterval rdTimeout = (double)cMsTimeout / 1000; 185 orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, rdTimeout, true /*returnAfterSourceHandled*/); 186 if (orc == kCFRunLoopRunHandledSource) 187 orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, false /*returnAfterSourceHandled*/); 188 if (!orc || orc == kCFRunLoopRunHandledSource) 189 return VINF_SUCCESS; 190 191 if (orc != kCFRunLoopRunTimedOut) 192 { 193 NS_WARNING("Unexpected status code from CFRunLoopRunInMode"); 194 } 195 196 return VERR_TIMEOUT; 197 } 198 #endif 199 200 #ifdef RT_OS_WINDOWS 201 static int 202 processPendingEventsOnWindows() 203 { 204 MSG Msg; 205 int rc = VERR_TIMEOUT; 206 while (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE)) 207 { 208 if (Msg.message == WM_QUIT) 209 rc = VERR_INTERRUPTED; 210 DispatchMessage(&Msg); 211 if (rc == VERR_INTERRUPTED) 212 break; 213 rc = VINF_SUCCESS; 214 } 215 return rc; 216 } 217 /** For automatic cleanup, */ 218 class MyThreadHandle 219 { 220 public: 221 HANDLE mh; 222 223 MyThreadHandle() 224 { 225 if (!DuplicateHandle(GetCurrentProcess(), 226 GetCurrentThread(), 227 GetCurrentProcess(), 228 &mh, 229 0 /*dwDesiredAccess*/, 230 FALSE /*bInheritHandle*/, 231 DUPLICATE_SAME_ACCESS)) 232 mh = INVALID_HANDLE_VALUE; 233 } 234 235 ~MyThreadHandle() 236 { 237 CloseHandle(mh); 238 mh = INVALID_HANDLE_VALUE; 239 } 240 }; 241 #endif 242 #include <stdio.h> 243 int EventQueue::processEventQueue(uint32_t cMsTimeout) 244 { 245 int rc = VINF_SUCCESS; 246 #if defined (VBOX_WITH_XPCOM) 247 do { 248 PRBool fHasEvents = PR_FALSE; 249 nsresult rc; 250 251 rc = mEventQ->PendingEvents(&fHasEvents); 252 if (NS_FAILED (rc)) 253 return VERR_INTERNAL_ERROR_3; 254 255 if (fHasEvents || cMsTimeout == 0) 256 break; 257 258 /** 259 * Unfortunately, WaitForEvent isn't interruptible with Ctrl-C, 260 * while select() is. 261 */ 262 263 if (cMsTimeout == RT_INDEFINITE_WAIT) 264 { 265 #if 0 266 PLEvent *pEvent = NULL; 267 int rc1 = mEventQ->WaitForEvent(&pEvent); 268 if (NS_FAILED(rc1) || pEvent == NULL) 269 { 270 rc = VERR_INTERRUPTED; 271 break; 272 } 273 mEventQ->HandleEvent(pEvent); 274 break; 275 #else 276 /* Pretty close to forever */ 277 cMsTimeout = 0xffff0000; 278 #endif 279 } 280 281 /* Bit tricky part - perform timed wait */ 282 # ifdef RT_OS_DARWIN 283 rc = timedWaitForEventsOnDarwin(mEventQ, cMsTimeout); 284 # else 285 int fd = mEventQ->GetEventQueueSelectFD(); 286 fd_set fdsetR, fdsetE; 287 struct timeval tv; 288 289 FD_ZERO(&fdsetR); 290 FD_SET(fd, &fdsetR); 291 292 fdsetE = fdsetR; 293 tv.tv_sec = (PRInt64)cMsTimeout / 1000; 294 tv.tv_usec = ((PRInt64)cMsTimeout % 1000) * 1000; 295 296 int aCode = select(fd + 1, &fdsetR, NULL, &fdsetE, &tv); 297 if (aCode == 0) 298 rc = VERR_TIMEOUT; 299 else if (aCode == EINTR) 300 rc = VERR_INTERRUPTED; 301 else if (aCode < 0) 302 rc = VERR_INTERNAL_ERROR_4; 303 304 # endif 305 } while (0); 306 307 mEventQ->ProcessPendingEvents(); 308 #else /* Windows */ 309 do { 310 int aCode = processPendingEventsOnWindows(); 311 if (aCode != VERR_TIMEOUT || cMsTimeout == 0) 312 { 313 rc = aCode; 314 break; 315 } 316 317 if (cMsTimeout == RT_INDEFINITE_WAIT) 318 { 319 Event* aEvent = NULL; 320 321 fHasEvent = waitForEvent(&aEvent); 322 if (fHasEvent) 323 handleEvent(aEvent); 324 else 325 rc = VERR_INTERRUPTED; 326 break; 327 } 328 329 /* Perform timed wait */ 330 MyThreadHandle aHandle; 331 332 DWORD aCode = MsgWaitForMultipleObjects(1, &aHandle.mh, 333 TRUE /*fWaitAll*/, 334 0 /*ms*/, 335 QS_ALLINPUT); 336 if (aCode == WAIT_TIMEOUT) 337 rc = VERR_TIMEOUT; 338 else if (aCode == WAIT_OBJECT_0) 339 rc = VINF_SUCCESS; 340 else 341 rc = VERR_INTERNAL_ERROR_4; 342 } while (0); 343 344 processPendingEventsOnWindows(); 345 #endif 346 return rc; 347 348 } 349 350 int EventQueue::interruptEventQueueProcessing() 351 { 352 postEvent(NULL); 353 return VINF_SUCCESS; 354 } 355 148 356 /** 149 357 * Posts an event to this event loop asynchronously. … … 287 495 288 496 #else 289 290 /** For automatic cleanup. */291 class MyThreadHandle292 {293 public:294 HANDLE mh;295 296 MyThreadHandle(HANDLE hThread)297 {298 if (!DuplicateHandle(GetCurrentProcess(), hThread, GetCurrentProcess(),299 &mh, 0 /*dwDesiredAccess*/, FALSE /*bInheritHandle*/,300 DUPLICATE_SAME_ACCESS))301 mh = INVALID_HANDLE_VALUE;302 }303 304 ~MyThreadHandle()305 {306 CloseHandle(mh);307 mh = INVALID_HANDLE_VALUE;308 }309 };310 497 311 498 /** COM version of nsIEventQueue::PendingEvents. */ … … 386 573 return VERR_NOT_FOUND; 387 574 #else 388 MyThreadHandle q (GetCurrentThread());575 MyThreadHandle q; 389 576 #endif 390 577 … … 530 717 return VINF_SUCCESS; 531 718 } 532 533 719 } 534 720 /* namespace com */ -
trunk/src/VBox/Main/glue/initterm.cpp
r21878 r22847 53 53 #include "VBox/com/com.h" 54 54 #include "VBox/com/assert.h" 55 #include "VBox/com/EventQueue.h" 55 56 56 57 #include "../include/Logging.h" … … 497 498 AssertComRC (rc); 498 499 500 EventQueue::init(); 501 499 502 return rc; 500 503 } … … 503 506 { 504 507 HRESULT rc = S_OK; 508 509 EventQueue::deinit(); 505 510 506 511 #if !defined (VBOX_WITH_XPCOM)
Note:
See TracChangeset
for help on using the changeset viewer.