VirtualBox

Ignore:
Timestamp:
Apr 25, 2011 5:29:21 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71398
Message:

Main/Metrics: Locking revised to prevent lockups on VM shutdown (#5637)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/Performance.cpp

    r36527 r36839  
    110110
    111111CollectorGuest::CollectorGuest(Machine *machine, RTPROCESS process) :
    112     mEnabled(false), mValid(false), mMachine(machine), mProcess(process),
     112    mUnregistered(false), mEnabled(false), mValid(false), mMachine(machine), mProcess(process),
    113113    mCpuUser(0), mCpuKernel(0), mCpuIdle(0),
    114114    mMemTotal(0), mMemFree(0), mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0),
     
    202202void CollectorGuestManager::preCollect(CollectorHints& hints, uint64_t /* iTick */)
    203203{
     204    /*
     205     * Since we are running without a lock the value of mVMMStatsProvider
     206     * can change at any moment. In the worst case we won't collect any data.
     207     */
    204208    CollectorGuestList::iterator it;
    205209
     
    211215                    this, __PRETTY_FUNCTION__, *it, (*it)->getProcess(),
    212216                    hints.isGuestStatsCollected((*it)->getProcess())?"y":"n"));
     217        if ((*it)->isUnregistered())
     218            continue;
    213219        if (  (hints.isHostRamVmmCollected() && *it == mVMMStatsProvider)
    214220            || hints.isGuestStatsCollected((*it)->getProcess()))
     
    252258    LogAleksey(("{%p} " LOG_FN_FMT ": About to unregister guest=%p provider=%p\n",
    253259                this, __PRETTY_FUNCTION__, pGuest, mVMMStatsProvider));
    254     mGuests.remove(pGuest);
    255     LogAleksey(("{%p} " LOG_FN_FMT ": Number of guests after remove is %d\n",
    256                 this, __PRETTY_FUNCTION__, mGuests.size()));
     260    //mGuests.remove(pGuest); => destroyUnregistered()
     261    pGuest->unregister();
    257262    if (pGuest == mVMMStatsProvider)
    258263    {
    259264        /* This was our VMM stats provider, it is time to re-elect */
    260         if (mGuests.empty())
    261         {
    262             /* Nobody can provide VMM stats */
    263             mVMMStatsProvider = NULL;
    264         }
    265         else
    266         {
    267             /* First let's look for a guest already collecting stats */
    268             CollectorGuestList::iterator it;
    269 
    270             for (it = mGuests.begin(); it != mGuests.end(); it++)
    271                 if ((*it)->isEnabled())
    272                 {
    273                     /* Found one, elect it */
    274                     mVMMStatsProvider = *it;
    275                     LogAleksey(("{%p} " LOG_FN_FMT ": LEAVE new provider=%p\n",
    276                                 this, __PRETTY_FUNCTION__, mVMMStatsProvider));
    277                     return;
    278                 }
    279 
    280             /* Nobody collects stats, take the first one */
    281             mVMMStatsProvider = mGuests.front();
     265        CollectorGuestList::iterator it;
     266        /* Assume that nobody can provide VMM stats */
     267        mVMMStatsProvider = NULL;
     268
     269        for (it = mGuests.begin(); it != mGuests.end(); it++)
     270        {
     271            /* Skip unregistered as they are about to be destroyed */
     272            if ((*it)->isUnregistered())
     273                continue;
     274
     275            if ((*it)->isEnabled())
     276            {
     277                /* Found the guest already collecting stats, elect it */
     278                mVMMStatsProvider = *it;
     279                break;
     280            }
     281            else if (!mVMMStatsProvider)
     282            {
     283                /* If nobody collects stats, take the first registered */
     284                mVMMStatsProvider = *it;
     285            }
    282286        }
    283287    }
     
    286290}
    287291
     292void CollectorGuestManager::destroyUnregistered()
     293{
     294    CollectorGuestList::iterator it;
     295
     296    for (it = mGuests.begin(); it != mGuests.end();)
     297        if ((*it)->isUnregistered())
     298        {
     299            delete *it;
     300            it = mGuests.erase(it);
     301            LogAleksey(("{%p} " LOG_FN_FMT ": Number of guests after erasing unregistered is %d\n",
     302                        this, __PRETTY_FUNCTION__, mGuests.size()));
     303        }
     304        else
     305            ++it;
     306}
    288307
    289308#endif /* !VBOX_COLLECTOR_TEST_CASE */
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