diff options
author | Jocelyn Turcotte <jturcotte@woboq.com> | 2015-02-11 18:35:44 +0300 |
---|---|---|
committer | Jocelyn Turcotte <jturcotte@woboq.com> | 2015-02-11 18:45:11 +0300 |
commit | dc85ee3f0aa90b1ffec234885967b1b313e5fdbb (patch) | |
tree | cc089bea9b67f17dd9edecc45f59408719e8e3f8 /shell_integration | |
parent | 91ae912373377c5122d9314f99b2e34ba842fd39 (diff) |
shell_integration: Fix hangs on Windows Vista
It seems like verclsid.exe hangs on our class IDs when invoked
through explorer.exe for 5-10 seconds. It doesn't hang if I
invoke the same command line from cmd.exe, so there could be some
process parameters that don't play well with our extra thread
or to the pipe connection that we do in it.
Delay creating the RemotePathChecker thread until the first
IsMemberOf call. verclsid.exe only seems to instantiate a object
of each registered class, without actually using them, so we
can use this as a workaround.
This should be fixing issue #2680.
Diffstat (limited to 'shell_integration')
-rw-r--r-- | shell_integration/windows/OCOverlays/OCOverlay.cpp | 19 | ||||
-rw-r--r-- | shell_integration/windows/OCOverlays/OCOverlay.h | 1 |
2 files changed, 16 insertions, 4 deletions
diff --git a/shell_integration/windows/OCOverlays/OCOverlay.cpp b/shell_integration/windows/OCOverlays/OCOverlay.cpp index 22eef5c08..cc60357f6 100644 --- a/shell_integration/windows/OCOverlays/OCOverlay.cpp +++ b/shell_integration/windows/OCOverlays/OCOverlay.cpp @@ -40,17 +40,26 @@ extern HINSTANCE instanceHandle; OCOverlay::OCOverlay(int state) : _referenceCount(1) + , _checker(nullptr) , _state(state) - { - static RemotePathChecker s_remotePathChecker; - _checker = &s_remotePathChecker; } OCOverlay::~OCOverlay(void) { } +void OCOverlay::lazyInit() +{ + // On Vista we'll run into issue #2680 if we try to create the thread+pipe connection + // on any DllGetClassObject of our registered classes. + // Work around the issue by creating the static RemotePathChecker only once actually needed. + if (_checker) + return; + static RemotePathChecker s_remotePathChecker; + _checker = &s_remotePathChecker; +} + IFACEMETHODIMP_(ULONG) OCOverlay::AddRef() { return InterlockedIncrement(&_referenceCount); @@ -119,7 +128,9 @@ IFACEMETHODIMP OCOverlay::GetPriority(int *pPriority) IFACEMETHODIMP OCOverlay::IsMemberOf(PCWSTR pwszPath, DWORD dwAttrib) { - auto watchedDirectories = _checker->WatchedDirectories(); + lazyInit(); + assert(_checker); + auto watchedDirectories = _checker->WatchedDirectories(); wstring wpath(pwszPath); wpath.append(L"\\"); diff --git a/shell_integration/windows/OCOverlays/OCOverlay.h b/shell_integration/windows/OCOverlays/OCOverlay.h index 31d0b5162..31868070f 100644 --- a/shell_integration/windows/OCOverlays/OCOverlay.h +++ b/shell_integration/windows/OCOverlays/OCOverlay.h @@ -37,6 +37,7 @@ protected: private: //bool _GenerateMessage(const wchar_t*, std::wstring*); + void lazyInit(); bool _IsOverlaysEnabled(); long _referenceCount; |