Changeset 22911 in vbox
- Timestamp:
- Sep 10, 2009 12:02:36 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
-
include/VBox/com/EventQueue.h (modified) (2 diffs)
-
src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp (modified) (2 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManage.cpp (modified) (2 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManage.h (modified) (2 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp (modified) (3 diffs)
-
src/VBox/Frontends/VBoxSDL/Framebuffer.cpp (modified) (1 diff)
-
src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp (modified) (5 diffs)
-
src/VBox/Frontends/VBoxShell/vboxshell.py (modified) (2 diffs)
-
src/VBox/Main/glue/EventQueue.cpp (modified) (8 diffs)
-
src/VBox/Main/webservice/vboxweb.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/com/EventQueue.h
r22847 r22911 90 90 BOOL waitForEvent (Event **event); 91 91 BOOL handleEvent (Event *event); 92 static int processThreadEventQueue(uint32_t cMsTimeout, bool (*pfnExitCheck)(void *pvUser) = 0,93 void *pvUser = 0, uint32_t cMsPollInterval = 1000,94 bool fReturnOnEvent = true);95 92 /** 96 93 * Process events pending on this event queue, and wait … … 104 101 */ 105 102 int interruptEventQueueProcessing(); 103 /** 104 * Get select()'able selector for this event queue, can be -1 105 * on platforms not supporting such functionality. 106 */ 107 int getSelectFD(); 106 108 /** 107 109 * Initialize/deinitialize event queues. -
trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
r22810 r22911 810 810 } 811 811 812 /* create an event queue */813 EventQueue eventQ;814 815 812 /* initialize global references */ 816 813 gSession = session; 817 814 gConsole = console; 818 gEventQ = &eventQ;815 gEventQ = com::EventQueue::getMainEventQueue(); 819 816 820 817 /* register a callback for machine events */ … … 919 916 920 917 Event *e; 921 922 while ( eventQ.waitForEvent (&e) && e)923 eventQ.handleEvent (e);918 919 while (gEventQ->waitForEvent (&e) && e) 920 gEventQ->handleEvent (e); 924 921 925 922 Log (("VBoxHeadless: event loop has terminated...\n")); -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r22686 r22911 1825 1825 } 1826 1826 1827 /* create the event queue1828 * (here it is necessary only to process remaining XPCOM/IPC events1829 * after the session is closed) */1830 1831 #ifdef VBOX_WITH_XPCOM1832 nsCOMPtr<nsIEventQueue> eventQ;1833 NS_GetMainEventQ(getter_AddRefs(eventQ));1834 #endif1835 1836 #ifdef VBOX_WITH_XPCOM1837 HandlerArg handlerArg = { 0, NULL, eventQ, virtualBox, session };1838 #else1839 1827 HandlerArg handlerArg = { 0, NULL, virtualBox, session }; 1840 #endif1841 1828 1842 1829 /* … … 1917 1904 session->Close(); 1918 1905 1919 #ifdef VBOX_WITH_XPCOM 1920 eventQ->ProcessPendingEvents(); 1921 #endif 1922 1906 EventQueue::getMainEventQueue()->processEventQueue(0); 1923 1907 // end "all-stuff" scope 1924 1908 //////////////////////////////////////////////////////////////////////////// -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r22686 r22911 27 27 #include <VBox/com/ptr.h> 28 28 #include <VBox/com/VirtualBox.h> 29 #include <VBox/com/EventQueue.h>30 29 #include <VBox/com/string.h> 31 30 #endif /* !VBOX_ONLY_DOCS */ 32 31 33 32 #include <iprt/types.h> 34 35 #if defined(VBOX_WITH_XPCOM) && !defined(RT_OS_DARWIN) && !defined(RT_OS_OS2)36 # define USE_XPCOM_QUEUE37 #endif38 33 39 34 //////////////////////////////////////////////////////////////////////////////// … … 108 103 char **argv; 109 104 110 #ifdef VBOX_WITH_XPCOM111 nsCOMPtr<nsIEventQueue> eventQ;112 #endif113 105 #ifndef VBOX_ONLY_DOCS 114 106 ComPtr<IVirtualBox> virtualBox; -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp
r22811 r22911 33 33 34 34 #include <VBox/com/VirtualBox.h> 35 #include <VBox/com/EventQueue.h> 35 36 36 37 #include <VBox/log.h> … … 393 394 394 395 /** 395 * Callback for processThreadEventQueue.396 *397 * @param pvUser Pointer to the callback object.398 *399 * @returns true if it should return or false if it should continue waiting for400 * events.401 */402 static bool eventExitCheck(void *pvUser)403 {404 GuestPropertyCallback const *pCallbacks = (GuestPropertyCallback const *)pvUser;405 return pCallbacks->Signalled();406 }407 408 /**409 396 * Enumerates the properties in the guest property store. 410 397 * … … 473 460 a->virtualBox->RegisterCallback(callback); 474 461 475 int vrc = com::EventQueue::processThreadEventQueue(cMsTimeout, eventExitCheck, (void *)cbImpl, 476 1000 /*cMsPollInterval*/, false /*fReturnOnEvent*/); 477 if ( RT_FAILURE(vrc) 478 && vrc != VERR_CALLBACK_RETURN 479 && vrc != VERR_TIMEOUT) 480 { 481 RTPrintf("Error waiting for event: %Rrc\n", vrc); 482 return 1; 483 } 462 do { 463 int vrc = com::EventQueue::getMainEventQueue()->processEventQueue(1000); 464 if (RT_FAILURE(vrc) && vrc != VERR_TIMEOUT) 465 { 466 RTPrintf("Error waiting for event: %Rrc\n", vrc); 467 return 1; 468 } 469 } while (!cbImpl->Signalled()); 484 470 485 471 a->virtualBox->UnregisterCallback(callback); -
trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
r21394 r22911 52 52 53 53 #if defined(VBOX_WITH_XPCOM) 54 NS_IMPL_ ISUPPORTS1_CI(VBoxSDLFB, IFramebuffer)54 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VBoxSDLFB, IFramebuffer) 55 55 NS_DECL_CLASSINFO(VBoxSDLFB) 56 NS_IMPL_ ISUPPORTS1_CI(VBoxSDLFBOverlay, IFramebufferOverlay)56 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VBoxSDLFBOverlay, IFramebufferOverlay) 57 57 NS_DECL_CLASSINFO(VBoxSDLFBOverlay) 58 58 #endif -
trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp
r22810 r22911 1012 1012 } 1013 1013 1014 // create the event queue 1015 // (here it is necessary only to process remaining XPCOM/IPC events 1016 // after the session is closed) 1017 /// @todo 1018 // EventQueue eventQ; 1019 1020 #ifdef USE_XPCOM_QUEUE_THREAD 1021 nsCOMPtr<nsIEventQueue> eventQ; 1022 NS_GetMainEventQ(getter_AddRefs(eventQ)); 1023 #endif /* USE_XPCOM_QUEUE_THREAD */ 1014 EventQueue* eventQ = com::EventQueue::getMainEventQueue(); 1024 1015 1025 1016 /* Get the number of network adapters */ … … 2043 2034 * event queue buffer! 2044 2035 */ 2045 startXPCOMEventQueueThread(eventQ-> GetEventQueueSelectFD());2036 startXPCOMEventQueueThread(eventQ->getSelectFD()); 2046 2037 #endif /* USE_XPCOM_QUEUE_THREAD */ 2047 2038 … … 2124 2115 { 2125 2116 LogFlow(("SDL_USER_EVENT_XPCOM_EVENTQUEUE: processing XPCOM event queue...\n")); 2126 eventQ-> ProcessPendingEvents();2117 eventQ->processEventQueue(0); 2127 2118 signalXPCOMEventQueueThread(); 2128 2119 break; … … 2156 2147 } 2157 2148 } 2149 eventQ->processEventQueue(0); 2158 2150 } while ( rc == S_OK 2159 2151 && ( machineState == MachineState_Starting … … 2591 2583 { 2592 2584 LogFlow(("SDL_USER_EVENT_XPCOM_EVENTQUEUE: processing XPCOM event queue...\n")); 2593 eventQ-> ProcessPendingEvents();2585 eventQ->processEventQueue(0); 2594 2586 signalXPCOMEventQueueThread(); 2595 2587 break; -
trunk/src/VBox/Frontends/VBoxShell/vboxshell.py
r22068 r22911 218 218 sys.stdout.flush() 219 219 p.waitForCompletion(wait) 220 ctx['global'].waitForEvents(0) 220 221 except KeyboardInterrupt: 221 222 print "Interrupted." 223 222 224 223 225 def createVm(ctx,name,kind,base): … … 1079 1081 if g_verbose: 1080 1082 traceback.print_exc() 1081 1083 ctx['global'].waitForEvents(0) 1082 1084 try: 1083 1085 # There is no need to disable metric collection. This is just an example. -
trunk/src/VBox/Main/glue/EventQueue.cpp
r22849 r22911 179 179 timedWaitForEventsOnDarwin(nsIEventQueue *pQueue, PRInt32 cMsTimeout) 180 180 { 181 // This deals with the common case where the caller is the main182 // application thread and the queue is a native one.183 181 OSStatus orc = -1; 184 182 CFTimeInterval rdTimeout = (double)cMsTimeout / 1000; … … 200 198 #ifdef RT_OS_WINDOWS 201 199 static int 202 processPendingEvents OnWindows()200 processPendingEvents() 203 201 { 204 202 MSG Msg; … … 211 209 if (rc == VERR_INTERRUPTED) 212 210 break; 213 rc = VINF_SUCCESS; 211 rc = VINF_SUCCESS; 214 212 } 215 213 return rc; … … 239 237 } 240 238 }; 241 #endif 242 #include <stdio.h> 239 #else 240 static int 241 processPendingEvents(nsIEventQueue* pQueue) 242 { 243 /** @todo: rethink interruption events, current NULL event approach is bad */ 244 pQueue->ProcessPendingEvents(); 245 return VINF_SUCCESS; 246 } 247 #endif 243 248 int EventQueue::processEventQueue(uint32_t cMsTimeout) 244 249 { 245 250 int rc = VINF_SUCCESS; 251 /** @todo: check that current thread == one we were created on */ 246 252 #if defined (VBOX_WITH_XPCOM) 247 253 do { … … 249 255 nsresult rc; 250 256 251 rc = mEventQ->PendingEvents(&fHasEvents); 257 rc = mEventQ->PendingEvents(&fHasEvents); 252 258 if (NS_FAILED (rc)) 253 259 return VERR_INTERNAL_ERROR_3; … … 305 311 } while (0); 306 312 307 mEventQ->ProcessPendingEvents();313 rc = processPendingEvents(mEventQ); 308 314 #else /* Windows */ 309 315 do { … … 342 348 } while (0); 343 349 344 processPendingEventsOnWindows();350 rc = processPendingEvents(); 345 351 #endif 346 352 return rc; 347 348 353 } 349 354 350 355 int EventQueue::interruptEventQueueProcessing() 351 356 { 357 /** @todo: rethink me! */ 352 358 postEvent(NULL); 353 359 return VINF_SUCCESS; … … 469 475 } 470 476 471 477 int EventQueue::getSelectFD() 478 { 472 479 #ifdef VBOX_WITH_XPCOM 473 474 /** Wrapper around nsIEventQueue::PendingEvents. */ 475 DECLINLINE(bool) hasEventQueuePendingEvents(nsIEventQueue *pQueue) 476 { 477 PRBool fHasEvents = PR_FALSE; 478 nsresult rc = pQueue->PendingEvents(&fHasEvents); 479 return NS_SUCCEEDED(rc) && fHasEvents ? true : false; 480 } 481 482 /** Wrapper around nsIEventQueue::IsQueueNative. */ 483 DECLINLINE(bool) isEventQueueNative(nsIEventQueue *pQueue) 484 { 485 PRBool fIsNative = PR_FALSE; 486 nsresult rc = pQueue->IsQueueNative(&fIsNative); 487 return NS_SUCCEEDED(rc) && fIsNative ? true : false; 488 } 489 490 /** Wrapper around nsIEventQueue::ProcessPendingEvents. */ 491 DECLINLINE(void) processPendingEvents(nsIEventQueue *pQueue) 492 { 493 pQueue->ProcessPendingEvents(); 494 } 495 496 #else 497 498 /** COM version of nsIEventQueue::PendingEvents. */ 499 DECLINLINE(bool) hasEventQueuePendingEvents(MyThreadHandle &Handle) 500 { 501 DWORD rc = MsgWaitForMultipleObjects(1, &Handle.mh, TRUE /*fWaitAll*/, 0 /*ms*/, QS_ALLINPUT); 502 return rc == WAIT_OBJECT_0; 503 } 504 505 /** COM version of nsIEventQueue::IsQueueNative, the question doesn't make 506 * sense and we have to return false for the code below to work. */ 507 DECLINLINE(bool) isEventQueueNative(MyThreadHandle const &Handle) 508 { 509 return false; 510 } 511 512 /** COM version of nsIEventQueue::ProcessPendingEvents. */ 513 static void processPendingEvents(MyThreadHandle const &Handle) 514 { 515 /* 516 * Process pending thead messages. 517 */ 518 MSG Msg; 519 while (PeekMessage(&Msg, NULL /*hWnd*/, 0 /*wMsgFilterMin*/, 0 /*wMsgFilterMax*/, PM_REMOVE)) 520 { 521 if (Msg.message == WM_QUIT) 522 return /*VERR_INTERRUPTED*/; 523 DispatchMessage(&Msg); 524 } 525 } 526 527 #endif /* VBOX_WITH_XPCOM */ 528 529 /** 530 * Processes events for the current thread. 531 * 532 * @param cMsTimeout The timeout in milliseconds or RT_INDEFINITE_WAIT. 533 * @param pfnExitCheck Optional callback for checking for some exit condition 534 * while looping. Note that this may be called 535 * @param pvUser User argument for pfnExitCheck. 536 * @param cMsPollInterval The interval cMsTimeout should be called at. 0 means 537 * never default. 538 * @param fReturnOnEvent If true, return immediately after some events has 539 * been processed. If false, process events until we 540 * time out, pfnExitCheck returns true, interrupted or 541 * the queue receives some kind of quit message. 542 * 543 * @returns VBox status code. 544 * @retval VINF_SUCCESS if events were processed. 545 * @retval VERR_TIMEOUT if no events before cMsTimeout elapsed. 546 * @retval VERR_INTERRUPTED if the wait was interrupted by a signal or other 547 * async event. 548 * @retval VERR_NOT_FOUND if the thread has no event queue. 549 * @retval VERR_CALLBACK_RETURN if the callback indicates return. 550 * 551 * @todo This is just a quick approximation of what we need. Feel free to 552 * improve the interface and make it fit better in with the EventQueue 553 * class. 554 */ 555 /*static*/ int 556 EventQueue::processThreadEventQueue(uint32_t cMsTimeout, bool (*pfnExitCheck)(void *pvUser) /*= 0*/, 557 void *pvUser /*= 0*/, uint32_t cMsPollInterval /*= 1000*/, 558 bool fReturnOnEvent /*= true*/) 559 { 560 uint64_t const StartMsTS = RTTimeMilliTS(); 561 562 /* set default. */ 563 if (cMsPollInterval == 0) 564 cMsPollInterval = 1000; 565 566 /* 567 * Get the event queue / thread. 568 */ 569 #ifdef VBOX_WITH_XPCOM 570 nsCOMPtr<nsIEventQueue> q; 571 nsresult rv = NS_GetCurrentEventQ(getter_AddRefs(q)); 572 if (NS_FAILED(rv)) 573 return VERR_NOT_FOUND; 574 #else 575 MyThreadHandle q; 576 #endif 577 578 /* 579 * Check for pending before setting up the wait. 580 */ 581 if ( !hasEventQueuePendingEvents(q) 582 || !fReturnOnEvent) 583 { 584 bool fIsNative = isEventQueueNative(q); 585 if ( fIsNative 586 || cMsTimeout != RT_INDEFINITE_WAIT 587 || pfnExitCheck 588 || !fReturnOnEvent /** @todo !fReturnOnEvent and cMsTimeout RT_INDEFINITE_WAIT can be handled in else */) 589 { 590 #ifdef USE_XPCOM_QUEUE 591 int const fdQueue = fIsNative ? q->GetEventQueueSelectFD() : -1; 592 if (fIsNative && fdQueue == -1) 593 return VERR_INTERNAL_ERROR_4; 594 #endif 595 for (;;) 596 { 597 /* 598 * Check for events. 599 */ 600 if (hasEventQueuePendingEvents(q)) 601 { 602 if (fReturnOnEvent) 603 break; 604 processPendingEvents(q); 605 } 606 607 /* 608 * Check the user exit. 609 */ 610 if ( pfnExitCheck 611 && pfnExitCheck(pvUser)) 612 return VERR_CALLBACK_RETURN; 613 614 /* 615 * Figure out how much we have left to wait and if we've timed out already. 616 */ 617 uint32_t cMsLeft; 618 if (cMsTimeout == RT_INDEFINITE_WAIT) 619 cMsLeft = RT_INDEFINITE_WAIT; 620 else 621 { 622 uint64_t cMsElapsed = RTTimeMilliTS() - StartMsTS; 623 if (cMsElapsed >= cMsTimeout) 624 break; /* timeout */ 625 cMsLeft = cMsTimeout - (uint32_t)cMsElapsed; 626 } 627 628 /* 629 * Wait in a queue & platform specific manner. 630 */ 631 #ifdef VBOX_WITH_XPCOM 632 if (!fIsNative) 633 RTThreadSleep(250 /*ms*/); 634 else 635 { 636 # ifdef USE_XPCOM_QUEUE 637 fd_set fdset; 638 FD_ZERO(&fdset); 639 FD_SET(fdQueue, &fdset); 640 struct timeval tv; 641 if ( cMsLeft == RT_INDEFINITE_WAIT 642 || cMsLeft >= cMsPollInterval) 643 { 644 tv.tv_sec = cMsPollInterval / 1000; 645 tv.tv_usec = (cMsPollInterval % 1000) * 1000; 646 } 647 else 648 { 649 tv.tv_sec = cMsLeft / 1000; 650 tv.tv_usec = (cMsLeft % 1000) * 1000; 651 } 652 int prc = select(fdQueue + 1, &fdset, NULL, NULL, &tv); 653 if (prc == -1) 654 return RTErrConvertFromErrno(errno); 655 656 # elif defined(RT_OS_DARWIN) 657 CFTimeInterval rdTimeout = (double)RT_MIN(cMsLeft, cMsPollInterval) / 1000; 658 OSStatus orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, rdTimeout, true /*returnAfterSourceHandled*/); 659 if (orc == kCFRunLoopRunHandledSource) 660 orc = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, false /*returnAfterSourceHandled*/); 661 if ( orc != 0 662 && orc != kCFRunLoopRunHandledSource 663 && orc != kCFRunLoopRunTimedOut) 664 return orc == kCFRunLoopRunStopped || orc == kCFRunLoopRunFinished 665 ? VERR_INTERRUPTED 666 : RTErrConvertFromDarwin(orc); 667 # else 668 # warning "PORTME:" 669 RTThreadSleep(250); 670 # endif 671 } 672 673 #else /* !VBOX_WITH_XPCOM */ 674 DWORD rc = MsgWaitForMultipleObjects(1, &q.mh, TRUE /*fWaitAll*/, RT_MIN(cMsLeft, cMsPollInterval), QS_ALLINPUT); 675 if (rc == WAIT_OBJECT_0) 676 { 677 if (fReturnOnEvent) 678 break; 679 processPendingEvents(q); 680 } 681 else if (rc == WAIT_FAILED) 682 return RTErrConvertFromWin32(GetLastError()); 683 else if (rc != WAIT_TIMEOUT) 684 return VERR_INTERNAL_ERROR_4; 685 #endif /* !VBOX_WITH_XPCOM */ 686 } /* for (;;) */ 687 } 688 else 689 { 690 /* 691 * Indefinite wait without any complications. 692 */ 693 #ifdef VBOX_WITH_XPCOM 694 PLEvent *pEvent = NULL; 695 rv = q->WaitForEvent(&pEvent); 696 if (NS_FAILED(rv)) 697 return VERR_INTERRUPTED; 698 q->HandleEvent(pEvent); 699 #else 700 DWORD rc = MsgWaitForMultipleObjects(1, &q.mh, TRUE /*fWaitAll*/, INFINITE, QS_ALLINPUT); 701 if (rc != WAIT_OBJECT_0) 702 { 703 if (rc == WAIT_FAILED) 704 return RTErrConvertFromWin32(GetLastError()); 705 return VERR_INTERNAL_ERROR_3; 706 } 707 #endif 708 } 709 } 710 711 /* 712 * We have/had events in the queue. Process pending events and 713 * return successfully. 714 */ 715 processPendingEvents(q); 716 717 return VINF_SUCCESS; 480 return mEventQ->GetEventQueueSelectFD(); 481 #else 482 return -1; 483 #endif 718 484 } 719 485 } -
trunk/src/VBox/Main/webservice/vboxweb.cpp
r22725 r22911 465 465 soap_end(&soap); // clean up everything and close socket 466 466 467 // every COM thread needs to process its event queue, or memory leaks468 int vrc = com::EventQueue:: processThreadEventQueue(0);467 // we have to process main event queue 468 int vrc = com::EventQueue::getMainEventQueue()->processEventQueue(0); 469 469 } 470 470 }
Note:
See TracChangeset
for help on using the changeset viewer.

