コード例 #1
0
ファイル: GuestCtrlPrivate.cpp プロジェクト: bayasist/vbox
int GuestBase::registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID,
                                 const GuestEventTypes &lstEvents,
                                 GuestWaitEvent **ppEvent)
{
    AssertPtrReturn(ppEvent, VERR_INVALID_POINTER);

    uint32_t uContextID;
    int rc = generateContextID(uSessionID, uObjectID, &uContextID);
    if (RT_FAILURE(rc))
        return rc;

    rc = RTCritSectEnter(&mWaitEventCritSect);
    if (RT_SUCCESS(rc))
    {
        try
        {
            GuestWaitEvent *pEvent = new GuestWaitEvent(uContextID, lstEvents);
            AssertPtr(pEvent);

            LogFlowThisFunc(("New event=%p, CID=%RU32\n", pEvent, uContextID));

            /* Insert event into matching event group. This is for faster per-group
             * lookup of all events later. */
            for (GuestEventTypes::const_iterator itEvents = lstEvents.begin();
                 itEvents != lstEvents.end(); itEvents++)
            {
                mWaitEventGroups[(*itEvents)].insert(
                   std::pair<uint32_t, GuestWaitEvent*>(uContextID, pEvent));
                /** @todo Check for key collision. */
            }

            /* Register event in regular event list. */
            /** @todo Check for key collisions. */
            mWaitEvents[uContextID] = pEvent;

            *ppEvent = pEvent;
        }
        catch(std::bad_alloc &)
        {
            rc = VERR_NO_MEMORY;
        }

        int rc2 = RTCritSectLeave(&mWaitEventCritSect);
        if (RT_SUCCESS(rc))
            rc = rc2;
    }

    return rc;
}
コード例 #2
0
ファイル: GuestCtrlPrivate.cpp プロジェクト: bayasist/vbox
void GuestBase::unregisterWaitEvent(GuestWaitEvent *pEvent)
{
    if (!pEvent) /* Nothing to unregister. */
        return;

    int rc = RTCritSectEnter(&mWaitEventCritSect);
    if (RT_SUCCESS(rc))
    {
        LogFlowThisFunc(("pEvent=%p\n", pEvent));

        const GuestEventTypes lstTypes = pEvent->Types();
        for (GuestEventTypes::const_iterator itEvents = lstTypes.begin();
             itEvents != lstTypes.end(); itEvents++)
        {
            /** @todo Slow O(n) lookup. Optimize this. */
            GuestWaitEvents::iterator itCurEvent = mWaitEventGroups[(*itEvents)].begin();
            while (itCurEvent != mWaitEventGroups[(*itEvents)].end())
            {
                if (itCurEvent->second == pEvent)
                {
                    mWaitEventGroups[(*itEvents)].erase(itCurEvent++);
                    break;
                }
                else
                    itCurEvent++;
            }
        }

        delete pEvent;
        pEvent = NULL;

        int rc2 = RTCritSectLeave(&mWaitEventCritSect);
        if (RT_SUCCESS(rc))
            rc = rc2;
    }
}
コード例 #3
0
ファイル: GuestCtrlPrivate.cpp プロジェクト: bayasist/vbox
int GuestBase::signalWaitEvent(VBoxEventType_T aType, IEvent *aEvent)
{
    int rc = RTCritSectEnter(&mWaitEventCritSect);
#ifdef DEBUG
    uint32_t cEvents = 0;
#endif
    if (RT_SUCCESS(rc))
    {
        GuestEventGroup::iterator itGroup = mWaitEventGroups.find(aType);
        if (itGroup != mWaitEventGroups.end())
        {
            GuestWaitEvents::iterator itEvents = itGroup->second.begin();
            while (itEvents != itGroup->second.end())
            {
#ifdef DEBUG
                LogFlowThisFunc(("Signalling event=%p, type=%ld (CID %RU32: Session=%RU32, Object=%RU32, Count=%RU32) ...\n",
                                 itEvents->second, aType, itEvents->first,
                                 VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(itEvents->first),
                                 VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(itEvents->first),
                                 VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(itEvents->first)));
#endif
                ComPtr<IEvent> pThisEvent = aEvent;
                Assert(!pThisEvent.isNull());
                int rc2 = itEvents->second->SignalExternal(aEvent);
                if (RT_SUCCESS(rc))
                    rc = rc2;

                if (RT_SUCCESS(rc2))
                {
                    /* Remove the event from all other event groups (except the
                     * original one!) because it was signalled. */
                    AssertPtr(itEvents->second);
                    const GuestEventTypes evTypes = itEvents->second->Types();
                    for (GuestEventTypes::const_iterator itType = evTypes.begin();
                         itType != evTypes.end(); itType++)
                    {
                        if ((*itType) != aType) /* Only remove all other groups. */
                        {
                            /* Get current event group. */
                            GuestEventGroup::iterator evGroup = mWaitEventGroups.find((*itType));
                            Assert(evGroup != mWaitEventGroups.end());

                            /* Lookup event in event group. */
                            GuestWaitEvents::iterator evEvent = evGroup->second.find(itEvents->first /* Context ID */);
                            Assert(evEvent != evGroup->second.end());

                            LogFlowThisFunc(("Removing event=%p (type %ld)\n", evEvent->second, (*itType)));
                            evGroup->second.erase(evEvent);

                            LogFlowThisFunc(("%zu events for type=%ld left\n",
                                             evGroup->second.size(), aType));
                        }
                    }

                    /* Remove the event from the passed-in event group. */
                    itGroup->second.erase(itEvents++);
                }
                else
                    itEvents++;
#ifdef DEBUG
                cEvents++;
#endif
            }
        }

        int rc2 = RTCritSectLeave(&mWaitEventCritSect);
        if (RT_SUCCESS(rc))
            rc = rc2;
    }

#ifdef DEBUG
    LogFlowThisFunc(("Signalled %RU32 events, rc=%Rrc\n", cEvents, rc));
#endif
    return rc;
}