Index: src/plugin/PluginClass.cpp |
=================================================================== |
--- a/src/plugin/PluginClass.cpp |
+++ b/src/plugin/PluginClass.cpp |
@@ -30,6 +30,7 @@ |
#include "../shared/Dictionary.h" |
#include "IeVersion.h" |
#include "../shared/Version.h" |
+#include "Instances.h" |
#include <thread> |
#include <array> |
@@ -57,13 +58,45 @@ |
ATOM CPluginClass::s_atomPaneClass = NULL; |
HINSTANCE CPluginClass::s_hUxtheme = NULL; |
std::set<CPluginClass*> CPluginClass::s_instances; |
-std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances; |
CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; |
CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; |
CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; |
+namespace |
+{ |
+ /** |
+ * A synchronized map whose key is always the current thread ID. |
+ */ |
+ class CurrentThreadMap |
+ : public SyncMap<DWORD, CPluginClass*, nullptr> |
+ { |
+ typedef SyncMap<DWORD, CPluginClass*, nullptr> Base; |
+ |
+ public: |
+ bool AddIfAbsent(CPluginClass* p) |
+ { |
+ return Base::AddIfAbsent(::GetCurrentThreadId(), p); |
+ } |
+ |
+ bool RemoveAndCheck() |
+ { |
+ return Base::RemoveAndCheck(::GetCurrentThreadId()); |
+ } |
+ |
+ CPluginClass* Locate() |
+ { |
+ return Base::Locate(::GetCurrentThreadId()); |
+ } |
+ }; |
+ |
+ /** |
+ * Map from thread ID's to CPluginClass instances |
+ */ |
+ CurrentThreadMap threadMap; |
+} |
+ |
/* |
* Without namespace declaration, the identifier "Rectangle" is ambiguous |
* See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85).aspx |
@@ -118,10 +151,7 @@ |
m_pWndProcStatus = NULL; |
m_hTheme = NULL; |
m_isInitializedOk = false; |
- |
- |
m_tab = new CPluginTab(); |
- |
Dictionary::Create(GetBrowserLanguage()); |
} |
@@ -246,6 +276,14 @@ |
return ss.str(); |
}()); |
+ /* |
+ * Add ourselves to the thread map. |
+ */ |
+ if (!threadMap.AddIfAbsent(this)) |
+ { |
+ throw std::logic_error("CPluginClass::SetSite - May not overwrite existing entry in thread map"); |
+ } |
+ |
//register the mimefilter |
//and only mimefilter |
//on some few computers the mimefilter does not get properly registered when it is done on another thread |
@@ -319,15 +357,14 @@ |
HANDLE hMainThread = NULL; |
HANDLE hTabThread = NULL; |
+ if (!threadMap.RemoveAndCheck()) |
+ { |
+ throw std::logic_error("CPluginClass::SetSite - Missing entry in thread map"); |
+ } |
+ |
s_criticalSectionLocal.Lock(); |
{ |
s_instances.erase(this); |
- |
- std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetCurrentThreadId()); |
- if (it != s_threadInstances.end()) |
- { |
- s_threadInstances.erase(it); |
- } |
if (s_instances.empty()) |
{ |
// TODO: Explicitly releasing a resource when a container becomes empty looks like a job better suited for shared_ptr |
@@ -564,16 +601,11 @@ |
&& flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENABLED); |
if (newtabshown) |
{ |
- std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(GetCurrentThreadId()); |
- if (it == s_threadInstances.end()) |
+ if (!m_isInitializedOk) |
{ |
- s_threadInstances[::GetCurrentThreadId()] = this; |
- if (!m_isInitializedOk) |
- { |
- m_isInitializedOk = true; |
- InitObject(); |
- UpdateStatusBar(); |
- } |
+ m_isInitializedOk = true; |
+ InitObject(); |
+ UpdateStatusBar(); |
} |
} |
notificationMessage.Hide(); |
@@ -992,21 +1024,10 @@ |
return m_tab; |
} |
-CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) |
+CPluginTab* CPluginClass::GetTabCurrentThread() |
{ |
- CPluginTab* tab = NULL; |
- |
- s_criticalSectionLocal.Lock(); |
- { |
- std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dwThreadId); |
- if (it != s_threadInstances.end()) |
- { |
- tab = it->second->m_tab; |
- } |
- } |
- s_criticalSectionLocal.Unlock(); |
- |
- return tab; |
+ auto p = threadMap.Locate(); |
+ return p ? p->m_tab : nullptr; |
} |
// Entry point |
@@ -1417,7 +1438,7 @@ |
// use the disable icon as defualt, if the client doesn't exists |
HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); |
- CPluginTab* tab = GetTab(::GetCurrentThreadId()); |
+ CPluginTab* tab = GetTabCurrentThread(); |
if (tab) |
{ |
CPluginClient* client = CPluginClient::GetInstance(); |
@@ -1581,7 +1602,7 @@ |
case WM_UPDATEUISTATE: |
{ |
- CPluginTab* tab = GetTab(::GetCurrentThreadId()); |
+ CPluginTab* tab = GetTabCurrentThread(); |
Oleksandr
2016/02/10 10:58:49
Nit: I think the whitespace change here is acciden
Eric
2016/05/19 17:23:58
Yes. Fixed.
|
if (tab) |
{ |
tab->OnActivate(); |