mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 22:32:58 +00:00
[SHELL32]
- Introduce a CComCreatorSingleton class and use it for CDesktopFolder. Multiple calls to SHGetDesktopFolder will now return the same instance, which provides a massive speedup in many shell operations. CORE-9839 svn path=/trunk/; revision=68210
This commit is contained in:
parent
6bb0bec44f
commit
cc47f60138
4 changed files with 60 additions and 2 deletions
|
@ -287,6 +287,7 @@ CDesktopFolder::CDesktopFolder() :
|
||||||
|
|
||||||
CDesktopFolder::~CDesktopFolder()
|
CDesktopFolder::~CDesktopFolder()
|
||||||
{
|
{
|
||||||
|
ASSERT(_CreatorClass::IsTerminated());
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI CDesktopFolder::FinalConstruct()
|
HRESULT WINAPI CDesktopFolder::FinalConstruct()
|
||||||
|
|
|
@ -79,7 +79,7 @@ class CDesktopFolder :
|
||||||
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy);
|
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy);
|
||||||
|
|
||||||
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLDESKTOP)
|
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLDESKTOP)
|
||||||
DECLARE_NOT_AGGREGATABLE(CDesktopFolder)
|
DECLARE_SINGLETON_NOT_AGGREGATABLE(CDesktopFolder)
|
||||||
|
|
||||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,11 @@ HRESULT WINAPI SHCreateDefClassObject(
|
||||||
class CShell32Module : public CComModule
|
class CShell32Module : public CComModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void Term()
|
||||||
|
{
|
||||||
|
CComCreatorSingleton< ATL::CComObject< CDesktopFolder > >::Term();
|
||||||
|
CComModule::Term();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,58 @@ extern "C" {
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif /* defined(__cplusplus) */
|
#endif /* defined(__cplusplus) */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
template <typename T>
|
||||||
|
class CComCreatorSingleton
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static IUnknown *s_pInstance;
|
||||||
|
static bool s_IsTerminated;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static HRESULT WINAPI CreateInstance(void *pv, REFIID riid, LPVOID *ppv)
|
||||||
|
{
|
||||||
|
*ppv = NULL;
|
||||||
|
if (pv != NULL)
|
||||||
|
return CLASS_E_NOAGGREGATION;
|
||||||
|
if (!s_pInstance)
|
||||||
|
{
|
||||||
|
PVOID pObj;
|
||||||
|
HRESULT hr;
|
||||||
|
hr = ATL::CComCreator< T >::CreateInstance(NULL, IID_IUnknown, &pObj);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
if (InterlockedCompareExchangePointer((PVOID *)&s_pInstance, pObj, NULL))
|
||||||
|
static_cast<IUnknown *>(pObj)->Release();
|
||||||
|
}
|
||||||
|
return s_pInstance->QueryInterface(riid, ppv);
|
||||||
|
}
|
||||||
|
static void Term()
|
||||||
|
{
|
||||||
|
ULONG ref;
|
||||||
|
ASSERT(!s_IsTerminated);
|
||||||
|
s_IsTerminated = true;
|
||||||
|
if (s_pInstance)
|
||||||
|
{
|
||||||
|
ref = s_pInstance->Release();
|
||||||
|
ASSERT(ref == 0);
|
||||||
|
s_pInstance = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static bool IsTerminated() { return s_IsTerminated; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
IUnknown *CComCreatorSingleton<T>::s_pInstance = NULL;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool CComCreatorSingleton<T>::s_IsTerminated = false;
|
||||||
|
|
||||||
|
#define DECLARE_SINGLETON_NOT_AGGREGATABLE(x) \
|
||||||
|
public: \
|
||||||
|
typedef CComCreatorSingleton< ATL::CComObject<x> > _CreatorClass;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
template <class Base>
|
template <class Base>
|
||||||
class CComDebugObject : public Base
|
class CComDebugObject : public Base
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue