VirtualBox

Changeset 30381 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 22, 2010 10:06:00 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
62988
Message:

Main: generic events (disabled)

Location:
trunk/src/VBox
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxShell/vboxshell.py

    r30345 r30381  
    429429def monitorVBox2(ctx, dur):
    430430    vbox = ctx['vb']
    431     print vbox.eventSource
    432431    listener = vbox.eventSource.createListener()
     432    registered = False
    433433    if dur == -1:
    434434        # not infinity, but close enough
    435435        dur = 100000
    436436    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
    438439        end = time.time() + dur
    439440        while  time.time() < end:
    440             ev = vbox.eventSource.getEvent(500)
     441            ev = vbox.eventSource.getEvent(listener, 500)
    441442            if ev:
    442443                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)
    443448    # We need to catch all exceptions here, otherwise callback will never be unregistered
    444     except:
     449    except Exception, e:
     450        printErr(ctx,e)
    445451        traceback.print_exc()
    446452        pass
    447     vbox.eventSource.unregisterListener(listener)
     453    if listener and registered:
     454        vbox.eventSource.unregisterListener(listener)
    448455
    449456
  • trunk/src/VBox/Main/EventImpl.cpp

    r30345 r30381  
    2626#include <iprt/semaphore.h>
    2727#include <iprt/critsect.h>
     28#include <iprt/asm.h>
     29
    2830#include <VBox/com/array.h>
    2931
     
    3739        mProcessed(FALSE)
    3840    {}
    39     ComPtr<IEventSource>    mSource;
    4041    VBoxEventType_T         mType;
    4142    RTSEMEVENT              mWaitEvent;
    4243    BOOL                    mWaitable;
    4344    BOOL                    mProcessed;
     45    ComPtr<IEventSource>    mSource;
    4446};
    4547
     
    5254void VBoxEvent::FinalRelease()
    5355{
    54     uninit();
    55     delete m;
     56    if (m)
     57    {
     58        uninit();
     59        delete m;
     60        m = 0;
     61    }
    5662}
    5763
     
    6268
    6369    AssertReturn(aSource != NULL, E_INVALIDARG);
    64      
     70
    6571    AutoInitSpan autoInitSpan(this);
    6672    AssertReturn(autoInitSpan.isOk(), E_FAIL);
     
    9399void VBoxEvent::uninit()
    94100{
     101    if (!m)
     102        return;
     103
    95104    m->mProcessed = TRUE;
    96105    m->mType = VBoxEventType_Invalid;
     
    99108    if (m->mWaitEvent != NIL_RTSEMEVENT)
    100109    {
     110        Assert(m->mWaitable);
    101111        ::RTSemEventDestroy(m->mWaitEvent);
     112        m->mWaitEvent = NIL_RTSEMEVENT;
    102113    }
    103114}
     
    168179
    169180        if (m->mProcessed)
     181        {
     182            *aResult = TRUE;
    170183            return S_OK;
     184        }
     185
     186        if (aTimeout == 0)
     187        {
     188            *aResult = m->mProcessed;
     189            return S_OK;
     190        }
    171191    }
    172192
     
    175195              ("RTSemEventWait returned %Rrc\n", vrc));
    176196
    177 
    178197    if (RT_SUCCESS(vrc))
    179198    {
     
    194213static const int NumEvents  = LastEvent - FirstEvent;
    195214
    196 struct ListenerRecord;
     215class ListenerRecord;
    197216typedef std::list<ListenerRecord*> EventMap[NumEvents];
    198217typedef std::map<IEvent*, int32_t> PendingEventsMap;
    199218typedef std::deque<ComPtr<IEvent> > PassiveQueue;
    200219
    201 struct ListenerRecord
    202 {
     220class ListenerRecord
     221{
     222private:
    203223    ComPtr<IEventListener>        mListener;
    204224    BOOL                          mActive;
     
    208228    RTCRITSECT                    mcsQLock;
    209229    PassiveQueue                  mQueue;
    210 
     230    int32_t                       mRefCnt;
     231
     232public:
    211233    ListenerRecord(IEventListener*                    aListener,
    212234                   com::SafeArray<VBoxEventType_T>&   aInterested,
     
    219241    HRESULT dequeue(IEvent* *aEvent, LONG aTimeout);
    220242    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    }
    221255};
    222256
    223 typedef std::map<IEventListener*, ListenerRecord>  Listeners;
     257/* Handy class with semantics close to ComPtr, but for ListenerRecord */
     258class ListenerRecordHolder
     259{
     260public:
     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    }
     293private:
     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
     315typedef std::map<IEventListener*, ListenerRecordHolder>  Listeners;
    224316
    225317struct EventSource::Data
     
    231323};
    232324
     325/**
     326 * This function defines what wildcard expands to.
     327 */
    233328static BOOL implies(VBoxEventType_T who, VBoxEventType_T what)
    234329{
     
    240335            return     (what == VBoxEventType_OnMachineStateChange)
    241336                    || (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                    ;
    243345        case VBoxEventType_Invalid:
    244346            return FALSE;
     
    253355    :
    254356    mActive(aActive),
    255     mOwner(aOwner)
     357    mOwner(aOwner),
     358    mRefCnt(0)
    256359{
    257360    mListener = aListener;
     
    273376    if (!mActive)
    274377    {
    275         ::RTCritSectInitEx(&mcsQLock, 0, NIL_RTLOCKVALCLASS, RTLOCKVAL_SUB_CLASS_ANY, NULL);
     378        ::RTCritSectInit(&mcsQLock);
    276379        ::RTSemEventCreate (&mQEvent);
    277380    }
     
    311414{
    312415    AssertMsg(!mActive, ("must be passive\n"));
     416    // put an event the queue
    313417    ::RTCritSectEnter(&mcsQLock);
    314 
    315418    mQueue.push_back(aEvent);
    316     // notify waiters
     419    ::RTCritSectLeave(&mcsQLock);
     420
     421     // notify waiters
    317422    ::RTSemEventSignal(mQEvent);
    318 
    319     ::RTCritSectLeave(&mcsQLock);
    320423
    321424    return S_OK;
     
    330433    {
    331434        ::RTCritSectLeave(&mcsQLock);
     435        // Speed up common case
     436        if (aTimeout == 0)
     437        {
     438            *aEvent = NULL;
     439            return S_OK;
     440        }
    332441        ::RTSemEventWait(mQEvent, aTimeout);
    333442        ::RTCritSectEnter(&mcsQLock);
     
    350459    if (--pit->second == 0)
    351460    {
     461        Assert(pit->first == aEvent);
    352462        aEvent->SetProcessed();
    353463        mOwner->m->mPendingMap.erase(pit);
     
    358468}
    359469
    360 
    361470EventSource::EventSource()
    362471{}
     
    377486}
    378487
    379 HRESULT EventSource::init(IUnknown * aParent)
     488HRESULT EventSource::init(IUnknown *)
    380489{
    381490    HRESULT rc = S_OK;
     
    393502    m->mListeners.clear();
    394503    // 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;
    412504}
    413505
     
    430522
    431523    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));
    436526
    437527    return S_OK;
     
    475565    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    476566
    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;
    483568    BOOL aWaitable = FALSE;
    484569    aEvent->COMGETTER(Waitable)(&aWaitable);
    485570
    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 */
    507605
    508606    if (aWaitable)
     
    516614
    517615STDMETHODIMP EventSource::GetEvent(IEventListener * aListener,
    518                                    LONG      aTimeout,
    519                                    IEvent  * *aEvent)
     616                                   LONG             aTimeout,
     617                                   IEvent  **       aEvent)
    520618{
    521619
     
    525623    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    526624
     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     */
    527632    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    528633
     
    531636
    532637    if (it != m->mListeners.end())
    533         rc = it->second.dequeue(aEvent, aTimeout);
     638        rc = it->second.obj()->dequeue(aEvent, aTimeout);
    534639    else
    535640        rc = setError(VBOX_E_OBJECT_NOT_FOUND,
     
    558663    if (it != m->mListeners.end())
    559664    {
    560         ListenerRecord& aRecord = it->second;
    561 
    562         if (aRecord.mActive)
     665        ListenerRecord* aRecord = it->second.obj();
     666
     667        if (aRecord->isActive())
    563668            return setError(E_INVALIDARG,
    564669                        tr("Only applicable to passive listeners"));
     
    575680            }
    576681            else
    577                 rc = aRecord.eventProcessed(aEvent, pit);
     682                rc = aRecord->eventProcessed(aEvent, pit);
    578683        }
    579684        else
     
    591696    return rc;
    592697}
     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 */
     705class ATL_NO_VTABLE PassiveEventListener :
     706    public VirtualBoxBase,
     707    public VirtualBoxSupportErrorInfoImpl<PassiveEventListener, IEventListener>,
     708    public VirtualBoxSupportTranslation<PassiveEventListener>,
     709    VBOX_SCRIPTABLE_IMPL(IEventListener)
     710{
     711public:
     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
     748NS_DECL_CLASSINFO(PassiveEventListener)
     749NS_IMPL_THREADSAFE_ISUPPORTS1_CI(PassiveEventListener, IEventListener)
     750#endif
     751
     752STDMETHODIMP 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  
    320320        HostPower.cpp \
    321321        EventImpl.cpp \
     322        VBoxEvents.cpp \
    322323        $(if $(VBOX_WITH_VRDP),VRDPServerImpl.cpp,) \
    323324        $(if $(VBOX_WITH_XPCOM),xpcom/server.cpp,) \
     
    647648        VMMDevInterface.cpp \
    648649        EventImpl.cpp \
     650        VBoxEvents.cpp \
    649651        $(VBOX_XML_SCHEMADEFS_CPP)
    650652VBoxC_SOURCES.win = \
  • trunk/src/VBox/Main/VirtualBoxCallbackImpl.cpp

    r30345 r30381  
    322322}
    323323
    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  
    205205
    206206    virtual HRESULT handleCallback(const ComPtr<IVirtualBoxCallback> &aCallback) = 0;
     207    virtual HRESULT prepareEventDesc(IEventSource* aSource, VBoxEventDesc& aEvDesc) = 0;
     208
    207209#ifdef RT_OS_WINDOWS
    208     virtual HRESULT prepareEventDesc(ComEventDesc& aEvDesc) = 0;
     210    virtual HRESULT prepareComEventDesc(ComEventDesc& aEvDesc) = 0;
    209211#endif
    210212
     
    536538
    537539        /* events */
    538 #if 0
    539         // disabled for now
    540540        if (SUCCEEDED(rc = unconst(m->pEventSource).createObject()))
    541             rc = m->pEventSource->init(this);
     541            rc = m->pEventSource->init(static_cast<IVirtualBox*>(this));
    542542        if (FAILED(rc)) throw rc;
    543 #endif
    544 
    545543    }
    546544    catch (HRESULT err)
     
    748746    }
    749747
    750     LogFlowThisFunc(("Releasing event source...\n"));
    751     if (m->pEventSource)
    752     {
    753         m->pEventSource->uninit();
    754         unconst(m->pEventSource).setNull();
    755     }
    756 
    757748#ifdef VBOX_WITH_RESOURCE_USAGE_API
    758749    if (m->pPerformanceCollector)
     
    795786        unconst(m->threadAsyncEvent) = NIL_RTTHREAD;
    796787        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();
    797795    }
    798796
     
    25932591{
    25942592    MachineEvent(VirtualBox *aVB, const Guid &aId)
    2595         : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineDataChange), id(aId)
     2593        : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineDataChange), id(aId.toUtf16())
    25962594        {}
    25972595
    25982596    MachineEvent(VirtualBox *aVB, const Guid &aId, MachineState_T aState)
    2599         : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineStateChange), id(aId)
     2597        : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineStateChange), id(aId.toUtf16())
    26002598        , state(aState)
    26012599        {}
    26022600
    26032601    MachineEvent(VirtualBox *aVB, const Guid &aId, BOOL aRegistered)
    2604         : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineRegistered), id(aId)
     2602        : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnMachineRegistered), id(aId.toUtf16())
    26052603        , registered(aRegistered)
    26062604        {}
     
    26112609        {
    26122610            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);
    26152613
    26162614            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);
    26202618
    26212619            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);
    26252623
    26262624            default:
     
    26292627    }
    26302628#ifdef RT_OS_WINDOWS
    2631     HRESULT prepareEventDesc(ComEventDesc& aEvDesc)
     2629    HRESULT prepareComEventDesc(ComEventDesc& aEvDesc)
    26322630    {
    26332631        switch (mWhat)
     
    26352633            case VirtualBoxCallbackRegistration::kOnMachineDataChange:
    26362634                aEvDesc.init("OnMachineDataChange", 1);
    2637                 aEvDesc.add(id.toUtf16());
     2635                aEvDesc.add(id);
    26382636                break;
    26392637
    26402638            case VirtualBoxCallbackRegistration::kOnMachineStateChange:
    26412639                aEvDesc.init("OnMachineStateChange", 2);
    2642                 aEvDesc.add(id.toUtf16()).add((int)state);
     2640                aEvDesc.add(id).add((int)state);
    26432641                break;
    26442642
    26452643            case VirtualBoxCallbackRegistration::kOnMachineRegistered:
    26462644                aEvDesc.init("OnMachineRegistered", 2);
    2647                 aEvDesc.add(id.toUtf16()).add((BOOL)registered);
     2645                aEvDesc.add(id).add(registered);
    26482646                break;
    26492647
     
    26542652    }
    26552653#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;
    26582677    MachineState_T state;
    26592678    BOOL registered;
     
    27412760                   IN_BSTR aKey, IN_BSTR aVal)
    27422761        : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnExtraDataChange)
    2743         , machineId(aMachineId), key(aKey), val(aVal)
     2762        , machineId(aMachineId.toUtf16()), key(aKey), val(aVal)
    27442763    {}
    27452764
    27462765    HRESULT handleCallback(const ComPtr<IVirtualBoxCallback> &aCallback)
    27472766    {
    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);
    27512770    }
    27522771#ifdef RT_OS_WINDOWS
    2753     HRESULT prepareEventDesc(ComEventDesc& aEvDesc)
     2772    HRESULT prepareComEventDesc(ComEventDesc& aEvDesc)
    27542773    {
    27552774       aEvDesc.init("OnExtraDataChange", 3);
    2756        aEvDesc.add(machineId.toUtf16()).add(key).add(val);
     2775       aEvDesc.add(machineId).add(key).add(val);
    27572776       return S_OK;
    27582777    }
    27592778#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;
    27632785};
    27642786
     
    27842806    SessionEvent(VirtualBox *aVB, const Guid &aMachineId, SessionState_T aState)
    27852807        : CallbackEvent(aVB, VirtualBoxCallbackRegistration::kOnSessionStateChange)
    2786         , machineId(aMachineId), sessionState(aState)
     2808        , machineId(aMachineId.toUtf16()), sessionState(aState)
    27872809    {}
    27882810
    27892811    HRESULT handleCallback(const ComPtr<IVirtualBoxCallback> &aCallback)
    27902812    {
    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);
    27942816    }
    27952817
    27962818#ifdef RT_OS_WINDOWS
    2797     HRESULT prepareEventDesc(ComEventDesc& aEvDesc)
     2819    HRESULT prepareComEventDesc(ComEventDesc& aEvDesc)
    27982820    {
    27992821       aEvDesc.init("OnSessionStateChange", 2);
    2800        aEvDesc.add(machineId.toUtf16()).add((int)sessionState);
     2822       aEvDesc.add(machineId).add((int)sessionState);
    28012823       return S_OK;
    28022824    }
    28032825#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;
    28062831    SessionState_T sessionState;
    28072832};
     
    28522877
    28532878#ifdef RT_OS_WINDOWS
    2854     HRESULT prepareEventDesc(ComEventDesc& aEvDesc)
     2879    HRESULT prepareComEventDesc(ComEventDesc& aEvDesc)
    28552880    {
    28562881       aEvDesc.init("OnSnapshotTaken", 2);
     
    28592884    }
    28602885#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    }
    28622891
    28632892    Guid machineId;
     
    29122941
    29132942#ifdef RT_OS_WINDOWS
    2914     HRESULT prepareEventDesc(ComEventDesc& aEvDesc)
     2943    HRESULT prepareComEventDesc(ComEventDesc& aEvDesc)
    29152944    {
    29162945       aEvDesc.init("OnGuestPropertyChange", 4);
     
    29192948    }
    29202949#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    }
    29212955
    29222956    Guid machineId;
     
    46234657
    46244658#ifdef RT_OS_WINDOWS
    4625     // WIP
    46264659    {
    46274660     ComEventDesc evDesc;
     
    46304663     /* Only prepare args if someone really needs them */
    46314664     if (nConnections)
    4632         prepareEventDesc(evDesc);
     4665        prepareComEventDesc(evDesc);
    46334666
    46344667     for (int i=0; i<nConnections; i++)
     
    46524685        }
    46534686     }
     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);
    46544701    }
    46554702#endif
  • trunk/src/VBox/Main/glue/vboxapi.py

    r30207 r30381  
    217217            win32com.client.gencache.EnsureDispatch('VirtualBox.Session')
    218218            win32com.client.gencache.EnsureDispatch('VirtualBox.VirtualBox')
    219             win32com.client.gencache.EnsureDispatch('VirtualBox.Console')
    220219            win32com.client.gencache.EnsureDispatch('VirtualBox.CallbackWrapper')
    221220
     
    312311        pass
    313312
     313    def queryInterface(self, obj, klazzName):
     314        from win32com.client import CastTo
     315        return CastTo(obj, klazzName)
    314316
    315317class PlatformXPCOM:
     
    370372        import xpcom
    371373        xpcom._xpcom.DeinitCOM()
     374
     375    def queryInterface(self, obj, klazzName):
     376        import xpcom.components
     377        return obj.queryInterface(getattr(xpcom.components.interfaces, klazzName))
    372378
    373379class PlatformWEBSERVICE:
     
    452458           pass
    453459
     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
    454464class SessionManager:
    455465    def __init__(self, mgr):
     
    544554        global VboxSdkDir
    545555        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  
    1458014580      </desc>
    1458114581    </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
    1458214590
    1458314591    <const name="LastWildcard" value="31">
     
    1496614974
    1496714975   <interface
    14968      name="ISnapshotChangedEvent" extends="ISnapshotEvent"
     14976     name="ISnapshotChangeEvent" extends="ISnapshotEvent"
    1496914977     uuid="07541941-8079-447a-a33e-47a69c7980db"
    1497014978     wsmap="managed"
     
    1502315031    </class>
    1502415032
    15025     <class name="CallbackWrapper" uuid="bcacd681-7f53-4409-a2a5-8534911f9358"
     15033    <class name="CallbackWrapper" uuid="0AD9C4CE-3C33-4C2D-AC7B-B008196787A0"
    1502615034           namespace="virtualbox.org">
    1502715035      <interface name="ILocalOwner" default="yes"/>
    1502815036      <interface name="IVirtualBoxCallback"/>
    1502915037      <interface name="IConsoleCallback"/>
    15030       <interface name="IEventListener"/>
    1503115038    </class>
    1503215039  </module>
  • trunk/src/VBox/Main/include/EventImpl.h

    r30345 r30381  
    2222
    2323class ATL_NO_VTABLE VBoxEvent :
     24    public VirtualBoxBase,
    2425    public VirtualBoxSupportErrorInfoImpl<VBoxEvent, IEvent>,
    2526    public VirtualBoxSupportTranslation<VBoxEvent>,
    26     public VirtualBoxBase,
    2727    VBOX_SCRIPTABLE_IMPL(IEvent)
    2828{
     
    5454    STDMETHOD(COMGETTER(Source)) (IEventSource * *aSource);
    5555    STDMETHOD(COMGETTER(Waitable)) (BOOL *aWaitable);
    56    
     56
    5757    // IEvent methods
    5858    STDMETHOD(SetProcessed)();
     
    9999    // IEventSource methods
    100100    STDMETHOD(CreateListener)(IEventListener ** aListener);
    101     STDMETHOD(RegisterListener)(IEventListener * aListener, 
     101    STDMETHOD(RegisterListener)(IEventListener * aListener,
    102102                                ComSafeArrayIn(VBoxEventType_T, aInterested),
    103103                                BOOL             aActive);
     
    123123};
    124124
     125class VBoxEventDesc
     126{
     127public:
     128 VBoxEventDesc()
     129 : mEvent(0)
     130 {}
     131 ~VBoxEventDesc()
     132 {}
     133
     134 HRESULT init(IEventSource* aSource, VBoxEventType_T aType, ...);
     135 void getEvent(IEvent ** aEvent);
     136
     137private:
     138 ComPtr<IEvent>  mEvent;
     139};
     140
    125141#endif // ____H_EVENTIMPL
  • trunk/src/VBox/Main/include/VirtualBoxCallbackImpl.h

    r30345 r30381  
    2525    VBOX_SCRIPTABLE_IMPL(ILocalOwner),
    2626    VBOX_SCRIPTABLE_IMPL(IConsoleCallback),
    27     VBOX_SCRIPTABLE_IMPL(IVirtualBoxCallback),
    28     VBOX_SCRIPTABLE_IMPL(IEventListener)
     27    VBOX_SCRIPTABLE_IMPL(IVirtualBoxCallback)
    2928#ifdef RT_OS_WINDOWS
    3029    , public CComCoClass<CallbackWrapper, &CLSID_CallbackWrapper>
     
    4645        COM_INTERFACE_ENTRY(IVirtualBoxCallback)
    4746        COM_INTERFACE_ENTRY(IConsoleCallback)
    48         COM_INTERFACE_ENTRY(IEventListener)
    4947    END_COM_MAP()
    5048
     
    9795    STDMETHOD(OnShowWindow)(ULONG64 *winId);
    9896
    99     // IEventListener
    100     STDMETHOD(HandleEvent)(IEvent *aEvent);
    101 
    10297    // for VirtualBoxSupportErrorInfoImpl
    10398    static const wchar_t *getComponentName() { return L"CallbackWrapper"; }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette