diff options
author | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2016-05-13 13:06:26 +0000 |
---|---|---|
committer | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2016-05-13 13:06:26 +0000 |
commit | 17ba8669ca62d48fb05976f28fe6a4dad5ad7c51 (patch) | |
tree | 501745ab7a3fda8bd1b43c4608398214b1413184 /src/VBox/Main/src-all/VirtualBoxBase.cpp | |
parent | cbb8f9ce8d6c19b65a6f1fbd49d18c4fbabac81e (diff) | |
download | VirtualBox-svn-17ba8669ca62d48fb05976f28fe6a4dad5ad7c51.tar.gz |
Main/VirtualBoxBase: Add code for collecting information about how many API objects of each component type are currently around and how many have been created ever. While working on this the tiny bug in the event code was found (harmless, as before VirtualBoxBase::BaseFinalRelease was idempotent, but now no longer acceptable)
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@60977 cfe28804-0f27-0410-a406-dd0f0b0b656f
Diffstat (limited to 'src/VBox/Main/src-all/VirtualBoxBase.cpp')
-rw-r--r-- | src/VBox/Main/src-all/VirtualBoxBase.cpp | 108 |
1 files changed, 106 insertions, 2 deletions
diff --git a/src/VBox/Main/src-all/VirtualBoxBase.cpp b/src/VBox/Main/src-all/VirtualBoxBase.cpp index 18d49138586..dc8d937f1dc 100644 --- a/src/VBox/Main/src-all/VirtualBoxBase.cpp +++ b/src/VBox/Main/src-all/VirtualBoxBase.cpp @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2006-2014 Oracle Corporation + * Copyright (C) 2006-2016 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -47,17 +47,121 @@ // //////////////////////////////////////////////////////////////////////////////// -VirtualBoxBase::VirtualBoxBase() : mState(this) +CLASSFACTORY_STAT g_aClassFactoryStats[CLASSFACTORYSTATS_MAX] = +{ + { "--- totals ---", 0 }, + { NULL, 0 } +}; + +RWLockHandle *g_pClassFactoryStatsLock = NULL; + + +VirtualBoxBase::VirtualBoxBase() : + mState(this), + iFactoryStat(~0U) { mObjectLock = NULL; + + if (!g_pClassFactoryStatsLock) + { + RWLockHandle *lock = new RWLockHandle(LOCKCLASS_OBJECTSTATE); + if (!ASMAtomicCmpXchgPtr(&g_pClassFactoryStatsLock, lock, NULL)) + delete lock; + } + Assert(g_pClassFactoryStatsLock); } VirtualBoxBase::~VirtualBoxBase() { + Assert(iFactoryStat == ~0U); if (mObjectLock) delete mObjectLock; } +HRESULT VirtualBoxBase::BaseFinalConstruct() +{ + Assert(iFactoryStat == ~0U); + if (g_pClassFactoryStatsLock) + { + AutoWriteLock alock(g_pClassFactoryStatsLock COMMA_LOCKVAL_SRC_POS); + g_aClassFactoryStats[0].current++; + g_aClassFactoryStats[0].overall++; + const char *pszName = getComponentName(); + uint32_t i = 1; + while (i < CLASSFACTORYSTATS_MAX && g_aClassFactoryStats[i].psz) + { + if (g_aClassFactoryStats[i].psz == pszName) + break; + i++; + } + if (i < CLASSFACTORYSTATS_MAX) + { + if (!g_aClassFactoryStats[i].psz) + { + g_aClassFactoryStats[i].psz = pszName; + g_aClassFactoryStats[i].current = 0; + g_aClassFactoryStats[i].overall = 0; + } + iFactoryStat = i; + g_aClassFactoryStats[i].current++; + g_aClassFactoryStats[i].overall++; + } + else + AssertMsg(i < CLASSFACTORYSTATS_MAX, ("%u exhausts size of factory housekeeping array\n", i)); + } + else + Assert(g_pClassFactoryStatsLock); + +#ifdef RT_OS_WINDOWS + return CoCreateFreeThreadedMarshaler(this, //GetControllingUnknown(), + m_pUnkMarshaler.asOutParam()); +#else + return S_OK; +#endif +} + +void VirtualBoxBase::BaseFinalRelease() +{ + if (g_pClassFactoryStatsLock) + { + AutoWriteLock alock(g_pClassFactoryStatsLock COMMA_LOCKVAL_SRC_POS); + g_aClassFactoryStats[0].current--; + const char *pszName = getComponentName(); + if (iFactoryStat < CLASSFACTORYSTATS_MAX) + { + if (g_aClassFactoryStats[iFactoryStat].psz == pszName) + { + g_aClassFactoryStats[iFactoryStat].current--; + iFactoryStat = ~0U; + } + else + AssertMsgFailed(("could not find factory housekeeping array entry for %s (index %u contains %s)\n", pszName, iFactoryStat, g_aClassFactoryStats[iFactoryStat].psz)); + } + else + AssertMsgFailed(("factory housekeeping array corruption, index %u is too large\n", iFactoryStat)); + } + else + Assert(g_pClassFactoryStatsLock); + +#ifdef RT_OS_WINDOWS + m_pUnkMarshaler.setNull(); +#endif +} + +void APIDumpComponentFactoryStats() +{ + if (g_pClassFactoryStatsLock) + { + AutoReadLock alock(g_pClassFactoryStatsLock COMMA_LOCKVAL_SRC_POS); + for (uint32_t i = 0; i < CLASSFACTORYSTATS_MAX && g_aClassFactoryStats[i].psz; i++) + LogRel(("CFS: component %-30s current %-10u total %-10u\n", + g_aClassFactoryStats[i].psz, g_aClassFactoryStats[i].current, + g_aClassFactoryStats[i].overall)); + } + else + Assert(g_pClassFactoryStatsLock); +} + /** * This virtual method returns an RWLockHandle that can be used to * protect instance data. This RWLockHandle is generally referred to |