Dmitry Timoshkov : shell32:
Make SHGetDesktopFolder use a cached instance of IShellFolder.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jun 22 07:35:38 CDT 2007
Module: wine
Branch: master
Commit: 013652feeef3a69d43cedb7ad431010f1e4dbcdc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=013652feeef3a69d43cedb7ad431010f1e4dbcdc
Author: Dmitry Timoshkov <dmitry at codeweavers.com>
Date: Thu Jun 21 23:50:55 2007 +0900
shell32: Make SHGetDesktopFolder use a cached instance of IShellFolder.
---
dlls/shell32/shfldr_desktop.c | 64 ++++++++++++++++-------------------------
1 files changed, 25 insertions(+), 39 deletions(-)
diff --git a/dlls/shell32/shfldr_desktop.c b/dlls/shell32/shfldr_desktop.c
index 3fee311..14571b1 100644
--- a/dlls/shell32/shfldr_desktop.c
+++ b/dlls/shell32/shfldr_desktop.c
@@ -117,30 +117,12 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
static ULONG WINAPI ISF_Desktop_fnAddRef (IShellFolder2 * iface)
{
- IGenericSFImpl *This = (IGenericSFImpl *)iface;
- ULONG refCount = InterlockedIncrement(&This->ref);
-
- TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
-
- return refCount;
+ return 2; /* non-heap based object */
}
static ULONG WINAPI ISF_Desktop_fnRelease (IShellFolder2 * iface)
{
- IGenericSFImpl *This = (IGenericSFImpl *)iface;
- ULONG refCount = InterlockedDecrement(&This->ref);
-
- TRACE ("(%p)->(count=%u)\n", This, refCount + 1);
-
- if (!refCount)
- {
- TRACE ("-- destroying IShellFolder(%p)\n", This);
- SHFree (This->pidlRoot);
- SHFree (This->sPathTarget);
- LocalFree ((HLOCAL) This);
- return 0;
- }
- return refCount;
+ return 1; /* non-heap based object */
}
/**************************************************************************
@@ -865,9 +847,8 @@ static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 =
HRESULT WINAPI ISF_Desktop_Constructor (
IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
{
- IGenericSFImpl *sf;
+ static IGenericSFImpl *cached_sf;
WCHAR szMyPath[MAX_PATH];
- HRESULT r;
TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
@@ -876,26 +857,31 @@ HRESULT WINAPI ISF_Desktop_Constructor (
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
- if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
- return E_UNEXPECTED;
+ if (!cached_sf)
+ {
+ IGenericSFImpl *sf;
- sf = LocalAlloc( LMEM_ZEROINIT, sizeof (IGenericSFImpl) );
- if (!sf)
- return E_OUTOFMEMORY;
+ if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
+ return E_UNEXPECTED;
- sf->ref = 0;
- sf->lpVtbl = &vt_MCFldr_ShellFolder2;
- sf->pidlRoot = _ILCreateDesktop(); /* my qualified pidl */
- sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
- lstrcpyW( sf->sPathTarget, szMyPath );
+ sf = LocalAlloc( LMEM_ZEROINIT, sizeof (IGenericSFImpl) );
+ if (!sf)
+ return E_OUTOFMEMORY;
- r = IUnknown_QueryInterface( _IUnknown_(sf), riid, ppv );
- if (!SUCCEEDED (r))
- {
- IUnknown_Release( _IUnknown_(sf) );
- return r;
+ sf->ref = 1;
+ sf->lpVtbl = &vt_MCFldr_ShellFolder2;
+ sf->pidlRoot = _ILCreateDesktop(); /* my qualified pidl */
+ sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
+ lstrcpyW( sf->sPathTarget, szMyPath );
+
+ if (InterlockedCompareExchangePointer((void *)&cached_sf, sf, NULL) != NULL)
+ {
+ /* some other thread already been here */
+ SHFree( sf->pidlRoot );
+ SHFree( sf->sPathTarget );
+ LocalFree( sf );
+ }
}
- TRACE ("--(%p)\n", sf);
- return S_OK;
+ return IUnknown_QueryInterface( _IUnknown_(cached_sf), riid, ppv );
}
More information about the wine-cvs
mailing list