Author: tfaber
Date: Sat Jun 20 16:54:52 2015
New Revision: 68210
URL:
http://svn.reactos.org/svn/reactos?rev=68210&view=rev
Log:
[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
Modified:
trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.h
trunk/reactos/dll/win32/shell32/shell32.cpp
trunk/reactos/include/reactos/shellutils.h
Modified: trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp [iso-8859-1] Sat Jun 20
16:54:52 2015
@@ -287,6 +287,7 @@
CDesktopFolder::~CDesktopFolder()
{
+ ASSERT(_CreatorClass::IsTerminated());
}
HRESULT WINAPI CDesktopFolder::FinalConstruct()
Modified: trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CDesktopFolder.h [iso-8859-1] Sat Jun 20
16:54:52 2015
@@ -34,7 +34,7 @@
/* both paths are parsible from the desktop */
LPWSTR sPathTarget; /* complete path to target used for enumeration and
ChangeNotify */
LPITEMIDLIST pidlRoot; /* absolute pidl */
-
+
virtual HRESULT WINAPI _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut);
public:
@@ -79,7 +79,7 @@
virtual HRESULT WINAPI CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST
*apidl, BOOL bCopy);
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLDESKTOP)
- DECLARE_NOT_AGGREGATABLE(CDesktopFolder)
+ DECLARE_SINGLETON_NOT_AGGREGATABLE(CDesktopFolder)
DECLARE_PROTECT_FINAL_CONSTRUCT()
Modified: trunk/reactos/dll/win32/shell32/shell32.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shell32.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shell32.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/shell32.cpp [iso-8859-1] Sat Jun 20 16:54:52 2015
@@ -149,6 +149,11 @@
class CShell32Module : public CComModule
{
public:
+ void Term()
+ {
+ CComCreatorSingleton< ATL::CComObject< CDesktopFolder > >::Term();
+ CComModule::Term();
+ }
};
Modified: trunk/reactos/include/reactos/shellutils.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/shellutils…
==============================================================================
--- trunk/reactos/include/reactos/shellutils.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/shellutils.h [iso-8859-1] Sat Jun 20 16:54:52 2015
@@ -40,6 +40,58 @@
#ifdef __cplusplus
} /* extern "C" */
#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
template <class Base>