Changeset 30381 in vbox for trunk/src/VBox
- Timestamp:
- Jun 22, 2010 10:06:00 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 62988
- Location:
- trunk/src/VBox
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxShell/vboxshell.py
r30345 r30381 429 429 def monitorVBox2(ctx, dur): 430 430 vbox = ctx['vb'] 431 print vbox.eventSource432 431 listener = vbox.eventSource.createListener() 432 registered = False 433 433 if dur == -1: 434 434 # not infinity, but close enough 435 435 dur = 100000 436 436 try: 437 vbox.eventSource.registerListener(listener, [ctx['global'].constants.VBoxEventType_All], False) 437 vbox.eventSource.registerListener(listener, [ctx['global'].constants.VBoxEventType_Any], False) 438 registered = True 438 439 end = time.time() + dur 439 440 while time.time() < end: 440 ev = vbox.eventSource.getEvent( 500)441 ev = vbox.eventSource.getEvent(listener, 500) 441 442 if ev: 442 443 print "got event: %s %s" %(ev, str(ev.type)) 444 if ev.type == ctx['global'].constants.VBoxEventType_OnMachineStateChange: 445 scev = ctx['global'].queryInterface(ev, 'IMachineStateChangeEvent') 446 if scev: 447 print "state event: mach=%s state=%s" %(scev.machineId, scev.state) 443 448 # We need to catch all exceptions here, otherwise callback will never be unregistered 444 except: 449 except Exception, e: 450 printErr(ctx,e) 445 451 traceback.print_exc() 446 452 pass 447 vbox.eventSource.unregisterListener(listener) 453 if listener and registered: 454 vbox.eventSource.unregisterListener(listener) 448 455 449 456 -
trunk/src/VBox/Main/EventImpl.cpp
r30345 r30381 26 26 #include <iprt/semaphore.h> 27 27 #include <iprt/critsect.h> 28 #include <iprt/asm.h> 29 28 30 #include <VBox/com/array.h> 29 31 … … 37 39 mProcessed(FALSE) 38 40 {} 39 ComPtr<IEventSource> mSource;40 41 VBoxEventType_T mType; 41 42 RTSEMEVENT mWaitEvent; 42 43 BOOL mWaitable; 43 44 BOOL mProcessed; 45 ComPtr<IEventSource> mSource; 44 46 }; 45 47 … … 52 54 void VBoxEvent::FinalRelease() 53 55 { 54 uninit(); 55 delete m; 56 if (m) 57 { 58 uninit(); 59 delete m; 60 m = 0; 61 } 56 62 } 57 63 … … 62 68 63 69 AssertReturn(aSource != NULL, E_INVALIDARG); 64 70 65 71 AutoInitSpan autoInitSpan(this); 66 72 AssertReturn(autoInitSpan.isOk(), E_FAIL); … … 93 99 void VBoxEvent::uninit() 94 100 { 101 if (!m) 102 return; 103 95 104 m->mProcessed = TRUE; 96 105 m->mType = VBoxEventType_Invalid; … … 99 108 if (m->mWaitEvent != NIL_RTSEMEVENT) 100 109 { 110 Assert(m->mWaitable); 101 111 ::RTSemEventDestroy(m->mWaitEvent); 112 m->mWaitEvent = NIL_RTSEMEVENT; 102 113 } 103 114 } … … 168 179 169 180 if (m->mProcessed) 181 { 182 *aResult = TRUE; 170 183 return S_OK; 184 } 185 186 if (aTimeout == 0) 187 { 188 *aResult = m->mProcessed; 189 return S_OK; 190 } 171 191 } 172 192 … … 175 195 ("RTSemEventWait returned %Rrc\n", vrc)); 176 196 177 178 197 if (RT_SUCCESS(vrc)) 179 198 { … … 194 213 static const int NumEvents = LastEvent - FirstEvent; 195 214 196 structListenerRecord;215 class ListenerRecord; 197 216 typedef std::list<ListenerRecord*> EventMap[NumEvents]; 198 217 typedef std::map<IEvent*, int32_t> PendingEventsMap; 199 218 typedef std::deque<ComPtr<IEvent> > PassiveQueue; 200 219 201 struct ListenerRecord 202 { 220 class ListenerRecord 221 { 222 private: 203 223 ComPtr<IEventListener> mListener; 204 224 BOOL mActive; … … 208 228 RTCRITSECT mcsQLock; 209 229 PassiveQueue mQueue; 210 230 int32_t mRefCnt; 231 232 public: 211 233 ListenerRecord(IEventListener* aListener, 212 234 com::SafeArray<VBoxEventType_T>& aInterested, … … 219 241 HRESULT dequeue(IEvent* *aEvent, LONG aTimeout); 220 242 HRESULT eventProcessed(IEvent * aEvent, PendingEventsMap::iterator& pit); 243 void addRef() 244 { 245 ASMAtomicIncS32(&mRefCnt); 246 } 247 void release() 248 { 249 if (ASMAtomicDecS32(&mRefCnt) <= 0) delete this; 250 } 251 BOOL isActive() 252 { 253 return mActive; 254 } 221 255 }; 222 256 223 typedef std::map<IEventListener*, ListenerRecord> Listeners; 257 /* Handy class with semantics close to ComPtr, but for ListenerRecord */ 258 class ListenerRecordHolder 259 { 260 public: 261 ListenerRecordHolder(ListenerRecord* lr) 262 : 263 held(lr) 264 { 265 addref(); 266 } 267 ListenerRecordHolder(const ListenerRecordHolder& that) 268 : 269 held(that.held) 270 { 271 addref(); 272 } 273 ListenerRecordHolder() 274 : 275 held(0) 276 { 277 } 278 ~ListenerRecordHolder() 279 { 280 release(); 281 } 282 283 ListenerRecord* obj() 284 { 285 return held; 286 } 287 288 ListenerRecordHolder &operator=(const ListenerRecordHolder &that) 289 { 290 safe_assign(that.held); 291 return *this; 292 } 293 private: 294 ListenerRecord* held; 295 296 void addref() 297 { 298 if (held) 299 held->addRef(); 300 } 301 void release() 302 { 303 if (held) 304 held->release(); 305 } 306 void safe_assign (ListenerRecord *that_p) 307 { 308 if (that_p) 309 that_p->addRef(); 310 release(); 311 held = that_p; 312 } 313 }; 314 315 typedef std::map<IEventListener*, ListenerRecordHolder> Listeners; 224 316 225 317 struct EventSource::Data … … 231 323 }; 232 324 325 /** 326 * This function defines what wildcard expands to. 327 */ 233 328 static BOOL implies(VBoxEventType_T who, VBoxEventType_T what) 234 329 { … … 240 335 return (what == VBoxEventType_OnMachineStateChange) 241 336 || (what == VBoxEventType_OnMachineDataChange) 242 || (what == VBoxEventType_OnMachineRegistered); 337 || (what == VBoxEventType_OnMachineRegistered) 338 || (what == VBoxEventType_OnSessionStateChange) 339 || (what == VBoxEventType_OnGuestPropertyChange); 340 case VBoxEventType_SnapshotEvent: 341 return (what == VBoxEventType_OnSnapshotTaken) 342 || (what == VBoxEventType_OnSnapshotDeleted) 343 || (what == VBoxEventType_OnSnapshotChange) 344 ; 243 345 case VBoxEventType_Invalid: 244 346 return FALSE; … … 253 355 : 254 356 mActive(aActive), 255 mOwner(aOwner) 357 mOwner(aOwner), 358 mRefCnt(0) 256 359 { 257 360 mListener = aListener; … … 273 376 if (!mActive) 274 377 { 275 ::RTCritSectInit Ex(&mcsQLock, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL);378 ::RTCritSectInit(&mcsQLock); 276 379 ::RTSemEventCreate (&mQEvent); 277 380 } … … 311 414 { 312 415 AssertMsg(!mActive, ("must be passive\n")); 416 // put an event the queue 313 417 ::RTCritSectEnter(&mcsQLock); 314 315 418 mQueue.push_back(aEvent); 316 // notify waiters 419 ::RTCritSectLeave(&mcsQLock); 420 421 // notify waiters 317 422 ::RTSemEventSignal(mQEvent); 318 319 ::RTCritSectLeave(&mcsQLock);320 423 321 424 return S_OK; … … 330 433 { 331 434 ::RTCritSectLeave(&mcsQLock); 435 // Speed up common case 436 if (aTimeout == 0) 437 { 438 *aEvent = NULL; 439 return S_OK; 440 } 332 441 ::RTSemEventWait(mQEvent, aTimeout); 333 442 ::RTCritSectEnter(&mcsQLock); … … 350 459 if (--pit->second == 0) 351 460 { 461 Assert(pit->first == aEvent); 352 462 aEvent->SetProcessed(); 353 463 mOwner->m->mPendingMap.erase(pit); … … 358 468 } 359 469 360 361 470 EventSource::EventSource() 362 471 {} … … 377 486 } 378 487 379 HRESULT EventSource::init(IUnknown * aParent)488 HRESULT EventSource::init(IUnknown *) 380 489 { 381 490 HRESULT rc = S_OK; … … 393 502 m->mListeners.clear(); 394 503 // m->mEvMap shall be cleared at this point too by destructors 395 }396 397 STDMETHODIMP EventSource::CreateListener(IEventListener ** aListener)398 {399 CheckComArgOutPointerValid(aListener);400 401 AutoCaller autoCaller(this);402 if (FAILED(autoCaller.rc())) return autoCaller.rc();403 404 ComPtr<IEventListener> listener;405 406 HRESULT rc = listener.createLocalObject(CLSID_CallbackWrapper);407 ComAssertMsgRet(SUCCEEDED(rc), ("Could not create wrapper object (%Rrc)", rc),408 E_FAIL);409 410 listener.queryInterfaceTo(aListener);411 return S_OK;412 504 } 413 505 … … 430 522 431 523 com::SafeArray<VBoxEventType_T> interested(ComSafeArrayInArg (aInterested)); 432 m->mListeners.insert( 433 Listeners::value_type(aListener, 434 ListenerRecord(aListener, interested, aActive, this)) 435 ); 524 ListenerRecordHolder lrh(new ListenerRecord(aListener, interested, aActive, this)); 525 m->mListeners.insert(Listeners::value_type(aListener, lrh)); 436 526 437 527 return S_OK; … … 475 565 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 476 566 477 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 478 479 VBoxEventType_T evType; 480 HRESULT hrc = aEvent->COMGETTER(Type)(&evType); 481 AssertComRCReturn(hrc, VERR_ACCESS_DENIED); 482 567 HRESULT hrc; 483 568 BOOL aWaitable = FALSE; 484 569 aEvent->COMGETTER(Waitable)(&aWaitable); 485 570 486 std::list<ListenerRecord*>& listeners = m->mEvMap[(int)evType-FirstEvent]; 487 488 uint32_t cListeners = listeners.size(); 489 PendingEventsMap::iterator pit; 490 491 if (cListeners > 0 && aWaitable) 492 { 493 m->mPendingMap.insert(PendingEventsMap::value_type(aEvent, cListeners)); 494 // we keep it here to allow processing active listeners without pending events lookup 495 pit = m->mPendingMap.find(aEvent); 496 } 497 for(std::list<ListenerRecord*>::const_iterator it = listeners.begin(); 498 it != listeners.end(); ++it) 499 { 500 ListenerRecord* record = *it; 501 HRESULT cbRc; 502 503 // @todo: callback under (read) lock, is it good? 504 cbRc = record->process(aEvent, aWaitable, pit); 505 // what to do with cbRc? 506 } 571 { 572 /* See comment in EventSource::GetEvent() */ 573 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 574 575 VBoxEventType_T evType; 576 hrc = aEvent->COMGETTER(Type)(&evType); 577 AssertComRCReturn(hrc, VERR_ACCESS_DENIED); 578 579 std::list<ListenerRecord*>& listeners = m->mEvMap[(int)evType-FirstEvent]; 580 581 uint32_t cListeners = listeners.size(); 582 PendingEventsMap::iterator pit; 583 584 if (cListeners > 0 && aWaitable) 585 { 586 m->mPendingMap.insert(PendingEventsMap::value_type(aEvent, cListeners)); 587 // we keep iterator here to allow processing active listeners without 588 // pending events lookup 589 pit = m->mPendingMap.find(aEvent); 590 } 591 for(std::list<ListenerRecord*>::const_iterator it = listeners.begin(); 592 it != listeners.end(); ++it) 593 { 594 ListenerRecord* record = *it; 595 HRESULT cbRc; 596 597 // @todo: callback under (read) lock, is it good? 598 // We could make copy of per-event listener's list, but real issue 599 // is that we don't want to allow removal of a listener while iterating 600 cbRc = record->process(aEvent, aWaitable, pit); 601 // what to do with cbRc? 602 } 603 } 604 /* We leave the lock here */ 507 605 508 606 if (aWaitable) … … 516 614 517 615 STDMETHODIMP EventSource::GetEvent(IEventListener * aListener, 518 LONG aTimeout,519 IEvent * *aEvent)616 LONG aTimeout, 617 IEvent ** aEvent) 520 618 { 521 619 … … 525 623 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 526 624 625 /** 626 * There's subtle dependency between this lock and one in FireEvent(): 627 * we need to be able to access event queue in FireEvent() while waiting 628 * here, to make this wait preemptible, thus both take read lock (write 629 * lock in FireEvent() would do too, and probably is a bit stricter), 630 * but will interfere with . 631 */ 527 632 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 528 633 … … 531 636 532 637 if (it != m->mListeners.end()) 533 rc = it->second. dequeue(aEvent, aTimeout);638 rc = it->second.obj()->dequeue(aEvent, aTimeout); 534 639 else 535 640 rc = setError(VBOX_E_OBJECT_NOT_FOUND, … … 558 663 if (it != m->mListeners.end()) 559 664 { 560 ListenerRecord & aRecord = it->second;561 562 if (aRecord .mActive)665 ListenerRecord* aRecord = it->second.obj(); 666 667 if (aRecord->isActive()) 563 668 return setError(E_INVALIDARG, 564 669 tr("Only applicable to passive listeners")); … … 575 680 } 576 681 else 577 rc = aRecord .eventProcessed(aEvent, pit);682 rc = aRecord->eventProcessed(aEvent, pit); 578 683 } 579 684 else … … 591 696 return rc; 592 697 } 698 699 /** 700 * This class serves as feasible listener implementation 701 * which could be used by clients not able to create local 702 * COM objects, but still willing to recieve event 703 * notifications in passive mode, such as webservices. 704 */ 705 class ATL_NO_VTABLE PassiveEventListener : 706 public VirtualBoxBase, 707 public VirtualBoxSupportErrorInfoImpl<PassiveEventListener, IEventListener>, 708 public VirtualBoxSupportTranslation<PassiveEventListener>, 709 VBOX_SCRIPTABLE_IMPL(IEventListener) 710 { 711 public: 712 713 VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(PassiveEventListener) 714 715 DECLARE_NOT_AGGREGATABLE(PassiveEventListener) 716 717 DECLARE_PROTECT_FINAL_CONSTRUCT() 718 719 BEGIN_COM_MAP(PassiveEventListener) 720 COM_INTERFACE_ENTRY(ISupportErrorInfo) 721 COM_INTERFACE_ENTRY(IEventListener) 722 COM_INTERFACE_ENTRY(IDispatch) 723 END_COM_MAP() 724 725 PassiveEventListener() 726 {} 727 ~PassiveEventListener() 728 {} 729 730 HRESULT FinalConstruct() 731 { 732 return S_OK; 733 } 734 void FinalRelease() 735 {} 736 737 // IEventListener methods 738 STDMETHOD(HandleEvent)(IEvent *) 739 { 740 ComAssertMsgRet(false, ("HandleEvent() of wrapper shall never be called"), 741 E_FAIL); 742 } 743 // for VirtualBoxSupportErrorInfoImpl 744 static const wchar_t *getComponentName() { return L"PassiveEventListener"; } 745 }; 746 747 #ifdef VBOX_WITH_XPCOM 748 NS_DECL_CLASSINFO(PassiveEventListener) 749 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(PassiveEventListener, IEventListener) 750 #endif 751 752 STDMETHODIMP EventSource::CreateListener(IEventListener ** aListener) 753 { 754 CheckComArgOutPointerValid(aListener); 755 756 AutoCaller autoCaller(this); 757 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 758 759 ComObjPtr<PassiveEventListener> listener; 760 761 HRESULT rc = listener.createObject(); 762 ComAssertMsgRet(SUCCEEDED(rc), ("Could not create wrapper object (%Rrc)", rc), 763 E_FAIL); 764 listener.queryInterfaceTo(aListener); 765 return S_OK; 766 } -
trunk/src/VBox/Main/Makefile.kmk
r30310 r30381 320 320 HostPower.cpp \ 321 321 EventImpl.cpp \ 322 VBoxEvents.cpp \ 322 323 $(if $(VBOX_WITH_VRDP),VRDPServerImpl.cpp,) \ 323 324 $(if $(VBOX_WITH_XPCOM),xpcom/server.cpp,) \ … … 647 648 VMMDevInterface.cpp \ 648 649 EventImpl.cpp \ 650 VBoxEvents.cpp \ 649 651 $(VBOX_XML_SCHEMADEFS_CPP) 650 652 VBoxC_SOURCES.win = \ -
trunk/src/VBox/Main/VirtualBoxCallbackImpl.cpp
r30345 r30381 322 322 } 323 323 324 STDMETHODIMP CallbackWrapper::HandleEvent(IEvent * aEvent)325 {326 ComAssertMsgRet(false, ("HandleEvent() of wrapper shall never be called"),327 E_FAIL);328 } -
trunk/src/VBox/Main/VirtualBoxImpl.cpp
r30380 r30381 205 205 206 206 virtual HRESULT handleCallback(const ComPtr<IVirtualBoxCallback> &aCallback) = 0; 207 virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) = 0; 208 207 209 #ifdef RT_OS_WINDOWS 208 virtual HRESULT prepare EventDesc(ComEventDesc& aEvDesc) = 0;210 virtual HRESULT prepareComEventDesc(ComEventDesc& aEvDesc) = 0; 209 211 #endif 210 212 … … 536 538 537 539 /* events */ 538 #if 0539 // disabled for now540 540 if (SUCCEEDED(rc = unconst(m->pEventSource).createObject())) 541 rc = m->pEventSource->init( this);541 rc = m->pEventSource->init(static_cast<IVirtualBox*>(this)); 542 542 if (FAILED(rc)) throw rc; 543 #endif544 545 543 } 546 544 catch (HRESULT err) … … 748 746 } 749 747 750 LogFlowThisFunc(("Releasing event source...\n"));751 if (m->pEventSource)752 {753 m->pEventSource->uninit();754 unconst(m->pEventSource).setNull();755 }756 757 748 #ifdef VBOX_WITH_RESOURCE_USAGE_API 758 749 if (m->pPerformanceCollector) … … 795 786 unconst(m->threadAsyncEvent) = NIL_RTTHREAD; 796 787 unconst(m->pAsyncEventQ) = NULL; 788 } 789 790 LogFlowThisFunc(("Releasing event source...\n")); 791 if (m->pEventSource) 792 { 793 // we don't perform uninit() as it's possible that some pending event refers to this source 794 unconst(m->pEventSource).setNull(); 797 795 } 798 796 … … 2593 2591 { 2594 2592 MachineEvent(VirtualBox *aVB, const Guid &aId) 2595 : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineDataChange), id(aId )2593 : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineDataChange), id(aId.toUtf16()) 2596 2594 {} 2597 2595 2598 2596 MachineEvent(VirtualBox *aVB, const Guid &aId, MachineState_T aState) 2599 : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineStateChange), id(aId )2597 : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineStateChange), id(aId.toUtf16()) 2600 2598 , state(aState) 2601 2599 {} 2602 2600 2603 2601 MachineEvent(VirtualBox *aVB, const Guid &aId, BOOL aRegistered) 2604 : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineRegistered), id(aId )2602 : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineRegistered), id(aId.toUtf16()) 2605 2603 , registered(aRegistered) 2606 2604 {} … … 2611 2609 { 2612 2610 case VirtualBoxCallbackRegistration::kOnMachineDataChange: 2613 LogFlow(("OnMachineDataChange: id={% RTuuid}\n", id.ptr()));2614 return aCallback->OnMachineDataChange(id .toUtf16());2611 LogFlow(("OnMachineDataChange: id={%ls}\n", id.raw())); 2612 return aCallback->OnMachineDataChange(id); 2615 2613 2616 2614 case VirtualBoxCallbackRegistration::kOnMachineStateChange: 2617 LogFlow(("OnMachineStateChange: id={% RTuuid}, state=%d\n",2618 id.ptr(), state));2619 return aCallback->OnMachineStateChange(id .toUtf16(), state);2615 LogFlow(("OnMachineStateChange: id={%ls}, state=%d\n", 2616 id.raw(), state)); 2617 return aCallback->OnMachineStateChange(id, state); 2620 2618 2621 2619 case VirtualBoxCallbackRegistration::kOnMachineRegistered: 2622 LogFlow(("OnMachineRegistered: id={% RTuuid}, registered=%d\n",2623 id.ptr(), registered));2624 return aCallback->OnMachineRegistered(id .toUtf16(), registered);2620 LogFlow(("OnMachineRegistered: id={%ls}, registered=%d\n", 2621 id.raw(), registered)); 2622 return aCallback->OnMachineRegistered(id, registered); 2625 2623 2626 2624 default: … … 2629 2627 } 2630 2628 #ifdef RT_OS_WINDOWS 2631 HRESULT prepare EventDesc(ComEventDesc& aEvDesc)2629 HRESULT prepareComEventDesc(ComEventDesc& aEvDesc) 2632 2630 { 2633 2631 switch (mWhat) … … 2635 2633 case VirtualBoxCallbackRegistration::kOnMachineDataChange: 2636 2634 aEvDesc.init("OnMachineDataChange", 1); 2637 aEvDesc.add(id .toUtf16());2635 aEvDesc.add(id); 2638 2636 break; 2639 2637 2640 2638 case VirtualBoxCallbackRegistration::kOnMachineStateChange: 2641 2639 aEvDesc.init("OnMachineStateChange", 2); 2642 aEvDesc.add(id .toUtf16()).add((int)state);2640 aEvDesc.add(id).add((int)state); 2643 2641 break; 2644 2642 2645 2643 case VirtualBoxCallbackRegistration::kOnMachineRegistered: 2646 2644 aEvDesc.init("OnMachineRegistered", 2); 2647 aEvDesc.add(id .toUtf16()).add((BOOL)registered);2645 aEvDesc.add(id).add(registered); 2648 2646 break; 2649 2647 … … 2654 2652 } 2655 2653 #endif 2656 2657 Guid id; 2654 virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) 2655 { 2656 switch (mWhat) 2657 { 2658 case VirtualBoxCallbackRegistration::kOnMachineDataChange: 2659 aEvDesc.init(aSource, VBoxEventType_OnMachineDataChange, id.raw()); 2660 break; 2661 2662 case VirtualBoxCallbackRegistration::kOnMachineStateChange: 2663 aEvDesc.init(aSource, VBoxEventType_OnMachineStateChange, id.raw(), state); 2664 break; 2665 2666 case VirtualBoxCallbackRegistration::kOnMachineRegistered: 2667 aEvDesc.init(aSource, VBoxEventType_OnMachineRegistered, id.raw(), registered); 2668 break; 2669 2670 default: 2671 AssertFailedReturn(S_OK); 2672 } 2673 return S_OK; 2674 } 2675 2676 Bstr id; 2658 2677 MachineState_T state; 2659 2678 BOOL registered; … … 2741 2760 IN_BSTR aKey, IN_BSTR aVal) 2742 2761 : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnExtraDataChange) 2743 , machineId(aMachineId ), key(aKey), val(aVal)2762 , machineId(aMachineId.toUtf16()), key(aKey), val(aVal) 2744 2763 {} 2745 2764 2746 2765 HRESULT handleCallback(const ComPtr<IVirtualBoxCallback> &aCallback) 2747 2766 { 2748 LogFlow(("OnExtraDataChange: machineId={% RTuuid}, key='%ls', val='%ls'\n",2749 machineId. ptr(), key.raw(), val.raw()));2750 return aCallback->OnExtraDataChange(machineId .toUtf16(), key, val);2767 LogFlow(("OnExtraDataChange: machineId={%ls}, key='%ls', val='%ls'\n", 2768 machineId.raw(), key.raw(), val.raw())); 2769 return aCallback->OnExtraDataChange(machineId, key, val); 2751 2770 } 2752 2771 #ifdef RT_OS_WINDOWS 2753 HRESULT prepare EventDesc(ComEventDesc& aEvDesc)2772 HRESULT prepareComEventDesc(ComEventDesc& aEvDesc) 2754 2773 { 2755 2774 aEvDesc.init("OnExtraDataChange", 3); 2756 aEvDesc.add(machineId .toUtf16()).add(key).add(val);2775 aEvDesc.add(machineId).add(key).add(val); 2757 2776 return S_OK; 2758 2777 } 2759 2778 #endif 2760 2761 Guid machineId; 2762 Bstr key, val; 2779 virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) 2780 { 2781 return aEvDesc.init(aSource, VBoxEventType_OnExtraDataChange, machineId.raw(), key.raw(), val.raw()); 2782 } 2783 2784 Bstr machineId, key, val; 2763 2785 }; 2764 2786 … … 2784 2806 SessionEvent(VirtualBox *aVB, const Guid &aMachineId, SessionState_T aState) 2785 2807 : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnSessionStateChange) 2786 , machineId(aMachineId ), sessionState(aState)2808 , machineId(aMachineId.toUtf16()), sessionState(aState) 2787 2809 {} 2788 2810 2789 2811 HRESULT handleCallback(const ComPtr<IVirtualBoxCallback> &aCallback) 2790 2812 { 2791 LogFlow(("OnSessionStateChange: machineId={% RTuuid}, sessionState=%d\n",2792 machineId. ptr(), sessionState));2793 return aCallback->OnSessionStateChange(machineId .toUtf16(), sessionState);2813 LogFlow(("OnSessionStateChange: machineId={%ls}, sessionState=%d\n", 2814 machineId.raw(), sessionState)); 2815 return aCallback->OnSessionStateChange(machineId, sessionState); 2794 2816 } 2795 2817 2796 2818 #ifdef RT_OS_WINDOWS 2797 HRESULT prepare EventDesc(ComEventDesc& aEvDesc)2819 HRESULT prepareComEventDesc(ComEventDesc& aEvDesc) 2798 2820 { 2799 2821 aEvDesc.init("OnSessionStateChange", 2); 2800 aEvDesc.add(machineId .toUtf16()).add((int)sessionState);2822 aEvDesc.add(machineId).add((int)sessionState); 2801 2823 return S_OK; 2802 2824 } 2803 2825 #endif 2804 2805 Guid machineId; 2826 virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) 2827 { 2828 return aEvDesc.init(aSource, VBoxEventType_OnSessionStateChange, machineId.raw(), sessionState); 2829 } 2830 Bstr machineId; 2806 2831 SessionState_T sessionState; 2807 2832 }; … … 2852 2877 2853 2878 #ifdef RT_OS_WINDOWS 2854 HRESULT prepare EventDesc(ComEventDesc& aEvDesc)2879 HRESULT prepareComEventDesc(ComEventDesc& aEvDesc) 2855 2880 { 2856 2881 aEvDesc.init("OnSnapshotTaken", 2); … … 2859 2884 } 2860 2885 #endif 2861 2886 virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) 2887 { 2888 return aEvDesc.init(aSource, VBoxEventType_OnSnapshotTaken, 2889 machineId.toUtf16().raw(), snapshotId.toUtf16().raw()); 2890 } 2862 2891 2863 2892 Guid machineId; … … 2912 2941 2913 2942 #ifdef RT_OS_WINDOWS 2914 HRESULT prepare EventDesc(ComEventDesc& aEvDesc)2943 HRESULT prepareComEventDesc(ComEventDesc& aEvDesc) 2915 2944 { 2916 2945 aEvDesc.init("OnGuestPropertyChange", 4); … … 2919 2948 } 2920 2949 #endif 2950 virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) 2951 { 2952 return aEvDesc.init(aSource, VBoxEventType_OnGuestPropertyChange, 2953 machineId.toUtf16().raw(), name.raw(), value.raw(), flags.raw()); 2954 } 2921 2955 2922 2956 Guid machineId; … … 4623 4657 4624 4658 #ifdef RT_OS_WINDOWS 4625 // WIP4626 4659 { 4627 4660 ComEventDesc evDesc; … … 4630 4663 /* Only prepare args if someone really needs them */ 4631 4664 if (nConnections) 4632 prepare EventDesc(evDesc);4665 prepareComEventDesc(evDesc); 4633 4666 4634 4667 for (int i=0; i<nConnections; i++) … … 4652 4685 } 4653 4686 } 4687 } 4688 #endif 4689 4690 #if 0 4691 // We disable generic events firing for now to not harm performance, but it is already functional 4692 { 4693 VBoxEventDesc evDesc; 4694 prepareEventDesc(mVirtualBox->m->pEventSource, evDesc); 4695 ComPtr<IEvent> aEvent; 4696 BOOL fDelivered; 4697 4698 evDesc.getEvent(aEvent.asOutParam()); 4699 if (aEvent && mVirtualBox && mVirtualBox->m->pEventSource) 4700 mVirtualBox->m->pEventSource->FireEvent(aEvent, /* don't wait for delivery */ 0, &fDelivered); 4654 4701 } 4655 4702 #endif -
trunk/src/VBox/Main/glue/vboxapi.py
r30207 r30381 217 217 win32com.client.gencache.EnsureDispatch('VirtualBox.Session') 218 218 win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox') 219 win32com.client.gencache.EnsureDispatch('VirtualBox.Console')220 219 win32com.client.gencache.EnsureDispatch('VirtualBox.CallbackWrapper') 221 220 … … 312 311 pass 313 312 313 def queryInterface(self, obj, klazzName): 314 from win32com.client import CastTo 315 return CastTo(obj, klazzName) 314 316 315 317 class PlatformXPCOM: … … 370 372 import xpcom 371 373 xpcom._xpcom.DeinitCOM() 374 375 def queryInterface(self, obj, klazzName): 376 import xpcom.components 377 return obj.queryInterface(getattr(xpcom.components.interfaces, klazzName)) 372 378 373 379 class PlatformWEBSERVICE: … … 452 458 pass 453 459 460 def queryInterface(self, obj, klazzName): 461 # wrong, need to test if class indeed implements this interface 462 return globals()[klazzName](obj.mgr, obj.handle) 463 454 464 class SessionManager: 455 465 def __init__(self, mgr): … … 544 554 global VboxSdkDir 545 555 return VboxSdkDir 556 557 def queryInterface(self, obj, klazzName): 558 return self.platform.queryInterface(obj, klazzName) -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r30345 r30381 14580 14580 </desc> 14581 14581 </const> 14582 14583 <const name="SnapshotEvent" value="3"> 14584 <desc> 14585 Wildcard for all snapshot events. Events of this type are never delivered, and only used in 14586 registerListener() call to simplify registration. 14587 </desc> 14588 </const> 14589 14582 14590 14583 14591 <const name="LastWildcard" value="31"> … … 14966 14974 14967 14975 <interface 14968 name="ISnapshotChange dEvent" extends="ISnapshotEvent"14976 name="ISnapshotChangeEvent" extends="ISnapshotEvent" 14969 14977 uuid="07541941-8079-447a-a33e-47a69c7980db" 14970 14978 wsmap="managed" … … 15023 15031 </class> 15024 15032 15025 <class name="CallbackWrapper" uuid=" bcacd681-7f53-4409-a2a5-8534911f9358"15033 <class name="CallbackWrapper" uuid="0AD9C4CE-3C33-4C2D-AC7B-B008196787A0" 15026 15034 namespace="virtualbox.org"> 15027 15035 <interface name="ILocalOwner" default="yes"/> 15028 15036 <interface name="IVirtualBoxCallback"/> 15029 15037 <interface name="IConsoleCallback"/> 15030 <interface name="IEventListener"/>15031 15038 </class> 15032 15039 </module> -
trunk/src/VBox/Main/include/EventImpl.h
r30345 r30381 22 22 23 23 class ATL_NO_VTABLE VBoxEvent : 24 public VirtualBoxBase, 24 25 public VirtualBoxSupportErrorInfoImpl<VBoxEvent, IEvent>, 25 26 public VirtualBoxSupportTranslation<VBoxEvent>, 26 public VirtualBoxBase,27 27 VBOX_SCRIPTABLE_IMPL(IEvent) 28 28 { … … 54 54 STDMETHOD(COMGETTER(Source)) (IEventSource * *aSource); 55 55 STDMETHOD(COMGETTER(Waitable)) (BOOL *aWaitable); 56 56 57 57 // IEvent methods 58 58 STDMETHOD(SetProcessed)(); … … 99 99 // IEventSource methods 100 100 STDMETHOD(CreateListener)(IEventListener ** aListener); 101 STDMETHOD(RegisterListener)(IEventListener * aListener, 101 STDMETHOD(RegisterListener)(IEventListener * aListener, 102 102 ComSafeArrayIn(VBoxEventType_T, aInterested), 103 103 BOOL aActive); … … 123 123 }; 124 124 125 class VBoxEventDesc 126 { 127 public: 128 VBoxEventDesc() 129 : mEvent(0) 130 {} 131 ~VBoxEventDesc() 132 {} 133 134 HRESULT init(IEventSource* aSource, VBoxEventType_T aType, ...); 135 void getEvent(IEvent ** aEvent); 136 137 private: 138 ComPtr<IEvent> mEvent; 139 }; 140 125 141 #endif // ____H_EVENTIMPL -
trunk/src/VBox/Main/include/VirtualBoxCallbackImpl.h
r30345 r30381 25 25 VBOX_SCRIPTABLE_IMPL(ILocalOwner), 26 26 VBOX_SCRIPTABLE_IMPL(IConsoleCallback), 27 VBOX_SCRIPTABLE_IMPL(IVirtualBoxCallback), 28 VBOX_SCRIPTABLE_IMPL(IEventListener) 27 VBOX_SCRIPTABLE_IMPL(IVirtualBoxCallback) 29 28 #ifdef RT_OS_WINDOWS 30 29 , public CComCoClass<CallbackWrapper, &CLSID_CallbackWrapper> … … 46 45 COM_INTERFACE_ENTRY(IVirtualBoxCallback) 47 46 COM_INTERFACE_ENTRY(IConsoleCallback) 48 COM_INTERFACE_ENTRY(IEventListener)49 47 END_COM_MAP() 50 48 … … 97 95 STDMETHOD(OnShowWindow)(ULONG64 *winId); 98 96 99 // IEventListener100 STDMETHOD(HandleEvent)(IEvent *aEvent);101 102 97 // for VirtualBoxSupportErrorInfoImpl 103 98 static const wchar_t *getComponentName() { return L"CallbackWrapper"; }
Note:
See TracChangeset
for help on using the changeset viewer.