Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/plugin/PluginClass.cpp

Issue 29330403: Issue #1467, #3397 - Rewrite the map from threads to tabs (Closed)
Patch Set: add comment; new function body Created July 17, 2016, 4:01 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 12 matching lines...) Expand all
23 #include "PluginFilter.h" 23 #include "PluginFilter.h"
24 #include "PluginMimeFilterClient.h" 24 #include "PluginMimeFilterClient.h"
25 #include "AdblockPlusClient.h" 25 #include "AdblockPlusClient.h"
26 #include "PluginClientBase.h" 26 #include "PluginClientBase.h"
27 #include "PluginClientFactory.h" 27 #include "PluginClientFactory.h"
28 #include "PluginUtil.h" 28 #include "PluginUtil.h"
29 #include "../shared/Utils.h" 29 #include "../shared/Utils.h"
30 #include "../shared/Dictionary.h" 30 #include "../shared/Dictionary.h"
31 #include "IeVersion.h" 31 #include "IeVersion.h"
32 #include "../shared/Version.h" 32 #include "../shared/Version.h"
33 #include "Instances.h"
33 #include <thread> 34 #include <thread>
34 #include <array> 35 #include <array>
35 36
36 #ifdef DEBUG_HIDE_EL 37 #ifdef DEBUG_HIDE_EL
37 DWORD profileTime = 0; 38 DWORD profileTime = 0;
38 #endif 39 #endif
39 40
40 extern CComModule _Module; 41 extern CComModule _Module;
41 42
42 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR); 43 typedef HANDLE (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR);
43 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR ECT); 44 typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HANDLE, HDC, INT, INT, LPRECT, LPR ECT);
44 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE); 45 typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HANDLE);
45 46
46 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL }; 47 HICON CPluginClass::s_hIcons[ICON_MAX] = { NULL, NULL, NULL };
47 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL ED, IDI_ICON_DEACTIVATED }; 48 DWORD CPluginClass::s_hIconTypes[ICON_MAX] = { IDI_ICON_DISABLED, IDI_ICON_ENABL ED, IDI_ICON_DEACTIVATED };
48 uint32_t iconHeight = 32; 49 uint32_t iconHeight = 32;
49 uint32_t iconWidth = 32; 50 uint32_t iconWidth = 32;
50 51
51 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL; 52 CPluginMimeFilterClient* CPluginClass::s_mimeFilter = NULL;
52 53
53 CLOSETHEMEDATA pfnClose = NULL; 54 CLOSETHEMEDATA pfnClose = NULL;
54 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL; 55 DRAWTHEMEBACKGROUND pfnDrawThemeBackground = NULL;
55 OPENTHEMEDATA pfnOpenThemeData = NULL; 56 OPENTHEMEDATA pfnOpenThemeData = NULL;
56 57
57 ATOM CPluginClass::s_atomPaneClass = NULL; 58 ATOM CPluginClass::s_atomPaneClass = NULL;
58 HINSTANCE CPluginClass::s_hUxtheme = NULL; 59 HINSTANCE CPluginClass::s_hUxtheme = NULL;
59 std::set<CPluginClass*> CPluginClass::s_instances; 60 std::set<CPluginClass*> CPluginClass::s_instances;
60 std::map<DWORD, CPluginClass*> CPluginClass::s_threadInstances;
61 61
62 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; 62 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal;
63 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; 63 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow;
64 64
65 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; 65 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2;
66 66
67 namespace
68 {
69 /**
70 * A synchronized map whose key is always the current thread ID.
71 */
72 class CurrentThreadMap
73 : public SyncMap<DWORD, CPluginClass*, nullptr>
74 {
75 typedef SyncMap<DWORD, CPluginClass*, nullptr> Base;
76
77 public:
78 bool AddIfAbsent(CPluginClass* p)
79 {
80 return Base::AddIfAbsent(::GetCurrentThreadId(), p);
81 }
82
83 bool RemoveAndCheck()
84 {
85 return Base::RemoveIfPresent(::GetCurrentThreadId());
86 }
87
88 CPluginClass* Locate()
89 {
90 return Base::Locate(::GetCurrentThreadId());
91 }
92 };
93
94 /**
95 * Map from thread ID's to CPluginClass instances
96 */
97 CurrentThreadMap threadMap;
98 }
99
67 /* 100 /*
68 * Without namespace declaration, the identifier "Rectangle" is ambiguous 101 * Without namespace declaration, the identifier "Rectangle" is ambiguous
69 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx 102 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx
70 */ 103 */
71 namespace AdblockPlus 104 namespace AdblockPlus
72 { 105 {
73 /** 106 /**
74 * Replacement for ATL type CRect. 107 * Replacement for ATL type CRect.
75 */ 108 */
76 class Rectangle 109 class Rectangle
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // _CrtDumpMemoryLeaks(); 144 // _CrtDumpMemoryLeaks();
112 145
113 m_isAdvised = false; 146 m_isAdvised = false;
114 m_hTabWnd = NULL; 147 m_hTabWnd = NULL;
115 m_hStatusBarWnd = NULL; 148 m_hStatusBarWnd = NULL;
116 m_hPaneWnd = NULL; 149 m_hPaneWnd = NULL;
117 m_nPaneWidth = 0; 150 m_nPaneWidth = 0;
118 m_pWndProcStatus = NULL; 151 m_pWndProcStatus = NULL;
119 m_hTheme = NULL; 152 m_hTheme = NULL;
120 m_isInitializedOk = false; 153 m_isInitializedOk = false;
121
122
123 m_tab = new CPluginTab(); 154 m_tab = new CPluginTab();
124
125 Dictionary::Create(GetBrowserLanguage()); 155 Dictionary::Create(GetBrowserLanguage());
126 } 156 }
127 157
128 CPluginClass::~CPluginClass() 158 CPluginClass::~CPluginClass()
129 { 159 {
130 DEBUG_GENERAL([this]() -> std::wstring 160 DEBUG_GENERAL([this]() -> std::wstring
131 { 161 {
132 std::wstring s = L"CPluginClass::<destructor>, this = "; 162 std::wstring s = L"CPluginClass::<destructor>, this = ";
133 s += ToHexLiteral(this); 163 s += ToHexLiteral(this);
134 return s; 164 return s;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p ointer to IWebBrowser2*"); 269 throw std::logic_error("CPluginClass::SetSite - Unable to convert site p ointer to IWebBrowser2*");
240 } 270 }
241 DEBUG_GENERAL([this]() -> std::wstring 271 DEBUG_GENERAL([this]() -> std::wstring
242 { 272 {
243 std::wstringstream ss; 273 std::wstringstream ss;
244 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this); 274 ss << L"CPluginClass::SetSite, this = " << ToHexLiteral(this);
245 ss << L", browser = " << ToHexLiteral(m_webBrowser2); 275 ss << L", browser = " << ToHexLiteral(m_webBrowser2);
246 return ss.str(); 276 return ss.str();
247 }()); 277 }());
248 278
279 /*
280 * Add ourselves to the thread map.
281 */
282 if (!threadMap.AddIfAbsent(this))
283 {
284 throw std::logic_error("CPluginClass::SetSite - May not overwrite existi ng entry in thread map");
285 }
286
249 //register the mimefilter 287 //register the mimefilter
250 //and only mimefilter 288 //and only mimefilter
251 //on some few computers the mimefilter does not get properly registered wh en it is done on another thread 289 //on some few computers the mimefilter does not get properly registered wh en it is done on another thread
252 s_criticalSectionLocal.Lock(); 290 s_criticalSectionLocal.Lock();
253 { 291 {
254 // Always register on startup, then check if we need to unregister in a separate thread 292 // Always register on startup, then check if we need to unregister in a separate thread
255 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); 293 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance();
256 s_asyncWebBrowser2 = unknownSite; 294 s_asyncWebBrowser2 = unknownSite;
257 s_instances.insert(this); 295 s_instances.insert(this);
258 } 296 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 m_hPaneWnd = NULL; 350 m_hPaneWnd = NULL;
313 } 351 }
314 352
315 m_hTabWnd = NULL; 353 m_hTabWnd = NULL;
316 m_hStatusBarWnd = NULL; 354 m_hStatusBarWnd = NULL;
317 355
318 // Remove instance from the list, shutdown threads 356 // Remove instance from the list, shutdown threads
319 HANDLE hMainThread = NULL; 357 HANDLE hMainThread = NULL;
320 HANDLE hTabThread = NULL; 358 HANDLE hTabThread = NULL;
321 359
360 if (!threadMap.RemoveAndCheck())
361 {
362 throw std::logic_error("CPluginClass::SetSite - Missing entry in thread map");
363 }
364
322 s_criticalSectionLocal.Lock(); 365 s_criticalSectionLocal.Lock();
323 { 366 {
324 s_instances.erase(this); 367 s_instances.erase(this);
325
326 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge tCurrentThreadId());
327 if (it != s_threadInstances.end())
328 {
329 s_threadInstances.erase(it);
330 }
331 if (s_instances.empty()) 368 if (s_instances.empty())
332 { 369 {
333 // TODO: Explicitly releasing a resource when a container becomes empt y looks like a job better suited for shared_ptr 370 // TODO: Explicitly releasing a resource when a container becomes empt y looks like a job better suited for shared_ptr
334 CPluginClientFactory::ReleaseMimeFilterClientInstance(); 371 CPluginClientFactory::ReleaseMimeFilterClientInstance();
335 } 372 }
336 } 373 }
337 s_criticalSectionLocal.Unlock(); 374 s_criticalSectionLocal.Unlock();
338 375
339 m_webBrowser2 = nullptr; 376 m_webBrowser2 = nullptr;
340 377
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 // Entry point 594 // Entry point
558 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u nsigned long validFlagsMask) 595 void STDMETHODCALLTYPE CPluginClass::OnWindowStateChanged(unsigned long flags, u nsigned long validFlagsMask)
559 { 596 {
560 try 597 try
561 { 598 {
562 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)"); 599 DEBUG_GENERAL(L"WindowStateChanged (check tab changed)");
563 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL ECMDIDF_WINDOWSTATE_ENABLED) 600 bool newtabshown = validFlagsMask == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OL ECMDIDF_WINDOWSTATE_ENABLED)
564 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA BLED); 601 && flags == (OLECMDIDF_WINDOWSTATE_USERVISIBLE | OLECMDIDF_WINDOWSTATE_ENA BLED);
565 if (newtabshown) 602 if (newtabshown)
566 { 603 {
567 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find( GetCurrentThreadId()); 604 if (!m_isInitializedOk)
568 if (it == s_threadInstances.end())
569 { 605 {
570 s_threadInstances[::GetCurrentThreadId()] = this; 606 m_isInitializedOk = true;
571 if (!m_isInitializedOk) 607 InitObject();
572 { 608 UpdateStatusBar();
573 m_isInitializedOk = true;
574 InitObject();
575 UpdateStatusBar();
576 }
577 } 609 }
578 } 610 }
579 notificationMessage.Hide(); 611 notificationMessage.Hide();
580 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end"); 612 DEBUG_GENERAL(L"WindowStateChanged (check tab changed) end");
581 } 613 }
582 catch (...) 614 catch (...)
583 { 615 {
584 } 616 }
585 } 617 }
586 618
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 s_criticalSectionLocal.Unlock(); 1017 s_criticalSectionLocal.Unlock();
986 1018
987 return result; 1019 return result;
988 } 1020 }
989 1021
990 CPluginTab* CPluginClass::GetTab() 1022 CPluginTab* CPluginClass::GetTab()
991 { 1023 {
992 return m_tab; 1024 return m_tab;
993 } 1025 }
994 1026
995 CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) 1027 CPluginTab* CPluginClass::GetTabForCurrentThread()
996 { 1028 {
997 CPluginTab* tab = NULL; 1029 auto p = threadMap.Locate();
998 1030 return p ? p->m_tab : nullptr;
999 s_criticalSectionLocal.Lock();
1000 {
1001 std::map<DWORD,CPluginClass*>::const_iterator it = s_threadInstances.find(dw ThreadId);
1002 if (it != s_threadInstances.end())
1003 {
1004 tab = it->second->m_tab;
1005 }
1006 }
1007 s_criticalSectionLocal.Unlock();
1008
1009 return tab;
1010 } 1031 }
1011 1032
1012 // Entry point 1033 // Entry point
1013 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O LECMD prgCmds[], OLECMDTEXT* pCmdText) 1034 STDMETHODIMP CPluginClass::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, O LECMD prgCmds[], OLECMDTEXT* pCmdText)
1014 { 1035 {
1015 try 1036 try
1016 { 1037 {
1017 if (cCmds == 0) return E_INVALIDARG; 1038 if (cCmds == 0) return E_INVALIDARG;
1018 if (prgCmds == 0) return E_POINTER; 1039 if (prgCmds == 0) return E_POINTER;
1019 1040
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 } 1431 }
1411 return ::CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lPara m); 1432 return ::CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wParam, lPara m);
1412 } 1433 }
1413 1434
1414 1435
1415 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url) 1436 HICON CPluginClass::GetStatusBarIcon(const std::wstring& url)
1416 { 1437 {
1417 // use the disable icon as defualt, if the client doesn't exists 1438 // use the disable icon as defualt, if the client doesn't exists
1418 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED); 1439 HICON hIcon = GetIcon(ICON_PLUGIN_DEACTIVATED);
1419 1440
1420 CPluginTab* tab = GetTab(::GetCurrentThreadId()); 1441 CPluginTab* tab = GetTabForCurrentThread();
1421 if (tab) 1442 if (tab)
1422 { 1443 {
1423 CPluginClient* client = CPluginClient::GetInstance(); 1444 CPluginClient* client = CPluginClient::GetInstance();
1424 if (CPluginSettings::GetInstance()->IsPluginEnabled()) 1445 if (CPluginSettings::GetInstance()->IsPluginEnabled())
1425 { 1446 {
1426 if (client->IsWhitelistedUrl(url)) 1447 if (client->IsWhitelistedUrl(url))
1427 { 1448 {
1428 hIcon = GetIcon(ICON_PLUGIN_DISABLED); 1449 hIcon = GetIcon(ICON_PLUGIN_DISABLED);
1429 } 1450 }
1430 else 1451 else
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1574 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN | TPM_BOTTOMALIGN ); 1595 pClass->DisplayPluginMenu(hMenu, -1, pt, TPM_LEFTALIGN | TPM_BOTTOMALIGN );
1575 break; 1596 break;
1576 } 1597 }
1577 case WM_DESTROY: 1598 case WM_DESTROY:
1578 break; 1599 break;
1579 case SC_CLOSE: 1600 case SC_CLOSE:
1580 break; 1601 break;
1581 1602
1582 case WM_UPDATEUISTATE: 1603 case WM_UPDATEUISTATE:
1583 { 1604 {
1584 CPluginTab* tab = GetTab(::GetCurrentThreadId()); 1605 CPluginTab* tab = GetTabForCurrentThread();
1585 if (tab) 1606 if (tab)
1586 { 1607 {
1587 tab->OnActivate(); 1608 tab->OnActivate();
1588 RECT rect; 1609 RECT rect;
1589 GetWindowRect(pClass->m_hPaneWnd, &rect); 1610 GetWindowRect(pClass->m_hPaneWnd, &rect);
1590 pClass->notificationMessage.MoveToCenter(rect); 1611 pClass->notificationMessage.MoveToCenter(rect);
1591 } 1612 }
1592 if (LOWORD(wParam) == UIS_CLEAR) 1613 if (LOWORD(wParam) == UIS_CLEAR)
1593 { 1614 {
1594 pClass->notificationMessage.Hide(); 1615 pClass->notificationMessage.Hide();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 s_criticalSectionLocal.Unlock(); 1728 s_criticalSectionLocal.Unlock();
1708 1729
1709 return icon; 1730 return icon;
1710 } 1731 }
1711 1732
1712 ATOM CPluginClass::GetAtomPaneClass() 1733 ATOM CPluginClass::GetAtomPaneClass()
1713 { 1734 {
1714 return s_atomPaneClass; 1735 return s_atomPaneClass;
1715 } 1736 }
1716 1737
OLDNEW

Powered by Google App Engine
This is Rietveld