STDMETHODIMP EventSource::FireEvent(IEvent * aEvent, LONG aTimeout, BOOL *aProcessed) { CheckComArgNotNull(aEvent); CheckComArgOutPointerValid(aProcessed); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); HRESULT hrc; BOOL aWaitable = FALSE; aEvent->COMGETTER(Waitable)(&aWaitable); do { AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); VBoxEventType_T evType; hrc = aEvent->COMGETTER(Type)(&evType); AssertComRCReturn(hrc, hrc); EventMapList &listeners = m->mEvMap[(int)evType - FirstEvent]; /* Anyone interested in this event? */ uint32_t cListeners = listeners.size(); if (cListeners == 0) { aEvent->SetProcessed(); break; // just leave the lock and update event object state } PendingEventsMap::iterator pit; if (aWaitable) { m->mPendingMap.insert(PendingEventsMap::value_type(aEvent, cListeners)); // we keep iterator here to allow processing active listeners without // pending events lookup pit = m->mPendingMap.find(aEvent); } for (EventMapList::iterator it = listeners.begin(); it != listeners.end(); ++it) { HRESULT cbRc; // keep listener record reference, in case someone will remove it while in callback RecordHolder<ListenerRecord> record(*it); /* * We pass lock here to allow modifying ops on EventSource inside callback * in active mode. Note that we expect list iterator stability as 'alock' * could be temporary released when calling event handler. */ cbRc = record.obj()->process(aEvent, aWaitable, pit, alock); /* Note that E_ABORT is used above to signal that a passive * listener was unregistered due to not picking up its event. * This overlaps with XPCOM specific use of E_ABORT to signal * death of an active listener, but that's irrelevant here. */ if (FAILED_DEAD_INTERFACE(cbRc) || cbRc == E_ABORT) { Listeners::iterator lit = m->mListeners.find(record.obj()->mListener); if (lit != m->mListeners.end()) m->mListeners.erase(lit); } // anything else to do with cbRc? } } while (0); /* We leave the lock here */ if (aWaitable) hrc = aEvent->WaitProcessed(aTimeout, aProcessed); else *aProcessed = TRUE; return hrc; }
/** * Start teleporter to the specified target. * * @returns COM status code. * * @param aHostname The name of the target host. * @param aPort The TCP port number. * @param aPassword The password. * @param aMaxDowntime Max allowed "downtime" in milliseconds. * @param aProgress Where to return the progress object. */ STDMETHODIMP Console::Teleport(IN_BSTR aHostname, ULONG aPort, IN_BSTR aPassword, ULONG aMaxDowntime, IProgress **aProgress) { /* * Validate parameters, check+hold object status, write lock the object * and validate the state. */ CheckComArgOutPointerValid(aProgress); CheckComArgStrNotEmptyOrNull(aHostname); CheckComArgStrNotEmptyOrNull(aPassword); CheckComArgExprMsg(aPort, aPort > 0 && aPort <= 65535, ("is %u", aPort)); CheckComArgExprMsg(aMaxDowntime, aMaxDowntime > 0, ("is %u", aMaxDowntime)); Utf8Str strPassword(aPassword); if (!strPassword.isEmpty()) { if (VBoxIsPasswordHashed(&strPassword)) return setError(E_INVALIDARG, tr("The specified password resembles a hashed password, expected plain text")); VBoxHashPassword(&strPassword); } AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS); LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); switch (mMachineState) { case MachineState_Running: case MachineState_Paused: break; default: return setError(VBOX_E_INVALID_VM_STATE, tr("Invalid machine state: %s (must be Running or Paused)"), Global::stringifyMachineState(mMachineState)); } /* * Create a progress object, spawn a worker thread and change the state. * Note! The thread won't start working until we release the lock. */ LogFlowThisFunc(("Initiating TELEPORT request...\n")); ComObjPtr<Progress> ptrProgress; HRESULT hrc = ptrProgress.createObject(); if (SUCCEEDED(hrc)) hrc = ptrProgress->init(static_cast<IConsole *>(this), Bstr(tr("Teleporter")).raw(), TRUE /*aCancelable*/); if (FAILED(hrc)) return hrc; TeleporterStateSrc *pState = new TeleporterStateSrc(this, mpUVM, ptrProgress, mMachineState); pState->mstrPassword = strPassword; pState->mstrHostname = aHostname; pState->muPort = aPort; pState->mcMsMaxDowntime = aMaxDowntime; void *pvUser = static_cast<void *>(static_cast<TeleporterState *>(pState)); ptrProgress->setCancelCallback(teleporterProgressCancelCallback, pvUser); int vrc = RTThreadCreate(NULL, Console::teleporterSrcThreadWrapper, (void *)pState, 0 /*cbStack*/, RTTHREADTYPE_EMULATION, 0 /*fFlags*/, "Teleport"); if (RT_SUCCESS(vrc)) { if (mMachineState == MachineState_Running) hrc = setMachineState(MachineState_Teleporting); else hrc = setMachineState(MachineState_TeleportingPausedVM); if (SUCCEEDED(hrc)) { ptrProgress.queryInterfaceTo(aProgress); mptrCancelableProgress = ptrProgress; } else ptrProgress->Cancel(); } else { ptrProgress->setCancelCallback(NULL, NULL); delete pState; hrc = setError(E_FAIL, tr("RTThreadCreate -> %Rrc"), vrc); } return hrc; }
STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, ULONG *aCpuIdle, ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared, ULONG *aMemCache, ULONG *aPageTotal, ULONG *aMemAllocTotal, ULONG *aMemFreeTotal, ULONG *aMemBalloonTotal, ULONG *aMemSharedTotal) { CheckComArgOutPointerValid(aCpuUser); CheckComArgOutPointerValid(aCpuKernel); CheckComArgOutPointerValid(aCpuIdle); CheckComArgOutPointerValid(aMemTotal); CheckComArgOutPointerValid(aMemFree); CheckComArgOutPointerValid(aMemBalloon); CheckComArgOutPointerValid(aMemShared); CheckComArgOutPointerValid(aMemCache); CheckComArgOutPointerValid(aPageTotal); CheckComArgOutPointerValid(aMemAllocTotal); CheckComArgOutPointerValid(aMemFreeTotal); CheckComArgOutPointerValid(aMemBalloonTotal); CheckComArgOutPointerValid(aMemSharedTotal); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); *aCpuUser = mCurrentGuestStat[GUESTSTATTYPE_CPUUSER]; *aCpuKernel = mCurrentGuestStat[GUESTSTATTYPE_CPUKERNEL]; *aCpuIdle = mCurrentGuestStat[GUESTSTATTYPE_CPUIDLE]; *aMemTotal = mCurrentGuestStat[GUESTSTATTYPE_MEMTOTAL] * (_4K/_1K); /* page (4K) -> 1KB units */ *aMemFree = mCurrentGuestStat[GUESTSTATTYPE_MEMFREE] * (_4K/_1K); /* page (4K) -> 1KB units */ *aMemBalloon = mCurrentGuestStat[GUESTSTATTYPE_MEMBALLOON] * (_4K/_1K); /* page (4K) -> 1KB units */ *aMemCache = mCurrentGuestStat[GUESTSTATTYPE_MEMCACHE] * (_4K/_1K); /* page (4K) -> 1KB units */ *aPageTotal = mCurrentGuestStat[GUESTSTATTYPE_PAGETOTAL] * (_4K/_1K); /* page (4K) -> 1KB units */ /* MUST release all locks before calling any PGM statistics queries, * as they are executed by EMT and that might deadlock us by VMM device * activity which waits for the Guest object lock. */ alock.release(); Console::SafeVMPtr pVM (mParent); if (pVM.isOk()) { uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal, uSharedTotal; *aMemFreeTotal = 0; int rc = PGMR3QueryGlobalMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal); AssertRC(rc); if (rc == VINF_SUCCESS) { *aMemAllocTotal = (ULONG)(uAllocTotal / _1K); /* bytes -> KB */ *aMemFreeTotal = (ULONG)(uFreeTotal / _1K); *aMemBalloonTotal = (ULONG)(uBalloonedTotal / _1K); *aMemSharedTotal = (ULONG)(uSharedTotal / _1K); } else return E_FAIL; /* Query the missing per-VM memory statistics. */ *aMemShared = 0; uint64_t uTotalMem, uPrivateMem, uSharedMem, uZeroMem; rc = PGMR3QueryMemoryStats(pVM.raw(), &uTotalMem, &uPrivateMem, &uSharedMem, &uZeroMem); if (rc == VINF_SUCCESS) { *aMemShared = (ULONG)(uSharedMem / _1K); } else return E_FAIL; } else { *aMemAllocTotal = 0; *aMemFreeTotal = 0; *aMemBalloonTotal = 0; *aMemSharedTotal = 0; *aMemShared = 0; return E_FAIL; } return S_OK; }
STDMETHODIMP USBDeviceFilters::RemoveDeviceFilter(ULONG aPosition, IUSBDeviceFilter **aFilter) { #ifdef VBOX_WITH_USB CheckComArgOutPointerValid(aFilter); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); /* the machine needs to be mutable */ AutoMutableStateDependency adep(m->pParent); if (FAILED(adep.rc())) return adep.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); if (!m->llDeviceFilters->size()) return setError(E_INVALIDARG, tr("The USB device pFilter list is empty")); if (aPosition >= m->llDeviceFilters->size()) return setError(E_INVALIDARG, tr("Invalid position: %lu (must be in range [0, %lu])"), aPosition, m->llDeviceFilters->size() - 1); /* backup the list before modification */ m->llDeviceFilters.backup(); ComObjPtr<USBDeviceFilter> pFilter; { /* iterate to the position... */ DeviceFilterList::iterator it = m->llDeviceFilters->begin(); std::advance(it, aPosition); /* ...get an element from there... */ pFilter = *it; /* ...and remove */ pFilter->mInList = false; m->llDeviceFilters->erase(it); } /* cancel sharing (make an independent copy of data) */ pFilter->unshare(); pFilter.queryInterfaceTo(aFilter); /* notify the proxy (only when it makes sense) */ if (pFilter->getData().mActive && Global::IsOnline(adep.machineState()) && pFilter->getData().mRemote.isMatch(false)) { USBProxyService *pProxySvc = m->pHost->usbProxyService(); ComAssertRet(pProxySvc, E_FAIL); ComAssertRet(pFilter->getId() != NULL, E_FAIL); pProxySvc->removeFilter(pFilter->getId()); pFilter->getId() = NULL; } alock.release(); AutoWriteLock mlock(m->pParent COMMA_LOCKVAL_SRC_POS); m->pParent->setModified(Machine::IsModified_USB); mlock.release(); return S_OK; #else /* VBOX_WITH_USB */ NOREF(aPosition); NOREF(aFilter); ReturnComNotImplemented(); #endif /* VBOX_WITH_USB */ }
STDMETHODIMP SystemProperties::COMGETTER(FreeDiskSpacePercentError)(ULONG *aFreeSpacePercent) { CheckComArgOutPointerValid(aFreeSpacePercent); ReturnComNotImplemented(); }
STDMETHODIMP SystemProperties::COMGETTER(FreeDiskSpaceWarning)(LONG64 *aFreeSpace) { CheckComArgOutPointerValid(aFreeSpace); ReturnComNotImplemented(); }