Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 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 |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 */ | 16 */ |
17 | 17 |
18 #pragma comment(linker,"\"/manifestdependency:type='win32' \ | 18 #pragma comment(linker,"\"/manifestdependency:type='win32' \ |
19 name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ | 19 name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ |
20 processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") | 20 processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") |
Eric
2015/08/19 17:43:37
I did not say it wasn't available, I said it wasn'
Oleksandr
2015/08/20 13:12:13
Common Controls 6 are essentially Windows XP UI up
| |
21 | 21 |
22 #include <AdblockPlus.h> | 22 #include <AdblockPlus.h> |
23 #include <functional> | 23 #include <functional> |
24 #include <vector> | 24 #include <vector> |
25 #include <deque> | 25 #include <deque> |
26 #include <thread> | 26 #include <thread> |
27 #include <mutex> | 27 #include <mutex> |
28 #include <condition_variable> | 28 #include <condition_variable> |
29 #include <Windows.h> | 29 #include <Windows.h> |
30 | 30 |
(...skipping 17 matching lines...) Expand all Loading... | |
48 ScopedAtlAxInitializer() | 48 ScopedAtlAxInitializer() |
49 { | 49 { |
50 ATL::AtlAxWinInit(); | 50 ATL::AtlAxWinInit(); |
51 } | 51 } |
52 ~ScopedAtlAxInitializer() | 52 ~ScopedAtlAxInitializer() |
53 { | 53 { |
54 ATL::AtlAxWinTerm(); | 54 ATL::AtlAxWinTerm(); |
55 } | 55 } |
56 }; | 56 }; |
57 | 57 |
58 class ABPAtlModule : public ATL::CAtlExeModuleT<ABPAtlModule> { | 58 class ABPAtlModule : public ATL::CAtlExeModuleT<ABPAtlModule> |
59 { | |
59 enum CustomMessages | 60 enum CustomMessages |
60 { | 61 { |
61 TaskPosted = WM_USER + 1 | 62 TASK_POSTED = WM_USER + 1 |
Oleksandr
2015/07/29 10:47:16
Nit: TASK_POSTED. Our enums are almost always uppe
| |
62 }; | 63 }; |
64 | |
63 public: | 65 public: |
64 ABPAtlModule() : m_msgHWnd(nullptr) | 66 ABPAtlModule() : m_msgHWnd(nullptr) |
65 { | 67 { |
66 } | 68 } |
67 void Finalize(); | 69 void Finalize(); |
68 HRESULT PreMessageLoop(int showCmd) throw(); | 70 HRESULT PreMessageLoop(int showCmd) throw(); |
69 void RunMessageLoop() throw(); | 71 void RunMessageLoop() throw(); |
Eric
2015/08/19 17:43:37
The only thing this message loop is doing is to pu
sergei
2015/08/20 14:45:42
What does the notification queue refers here?
Righ
| |
70 static HRESULT InitializeCom() throw() | 72 static HRESULT InitializeCom() throw() |
71 { | 73 { |
72 // The default implementation initializes multithreaded version but | 74 // The default implementation initializes multithreaded version but |
73 // in this case hosted ActiveX does not properly work. | 75 // in this case hosted ActiveX does not properly work. |
74 return CoInitialize(nullptr); | 76 return CoInitialize(nullptr); |
75 } | 77 } |
76 private: | 78 private: |
77 void onNewNotification(const AdblockPlus::NotificationPtr& notification); | 79 void onNewNotification(const AdblockPlus::NotificationPtr& notification); |
78 void dispatchTask(std::function<void()>&& task); | 80 void DispatchTask(std::function<void()>&& task); |
79 void processTasks(); | 81 void ProcessTasks(); |
80 private: | 82 |
81 ScopedAtlAxInitializer m_scopedAtlAxInit; | 83 ScopedAtlAxInitializer m_scopedAtlAxInit; |
82 HWND m_msgHWnd; | 84 HWND m_msgHWnd; |
83 std::recursive_mutex m_tasksMutex; | 85 std::recursive_mutex m_tasksMutex; |
84 std::deque<std::function<void()>> m_tasks; | 86 std::deque<std::function<void()>> m_tasks; |
85 std::unique_ptr<NotificationBorderWindow> m_notificationWindow; | 87 std::unique_ptr<NotificationBorderWindow> m_notificationWindow; |
86 } _AtlModule; | 88 } _AtlModule; |
Eric
2015/08/19 17:43:37
'_AtlModule' is defined statically, yet its proper
Oleksandr
2015/08/20 13:12:13
It's not perfect right now, but good enough, IMHO.
sergei
2015/08/20 14:45:41
I faced with the troubles that it's static and yet
| |
87 | 89 |
88 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine; | 90 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine; |
89 std::auto_ptr<Updater> updater; | 91 std::auto_ptr<Updater> updater; |
90 int activeConnections = 0; | 92 int activeConnections = 0; |
91 CriticalSection activeConnectionsLock; | 93 CriticalSection activeConnectionsLock; |
92 HWND callbackWindow; | 94 HWND callbackWindow; |
93 | 95 |
94 void WriteSubscriptions(Communication::OutputBuffer& response, | 96 void WriteSubscriptions(Communication::OutputBuffer& response, |
95 const std::vector<AdblockPlus::SubscriptionPtr>& subscriptions) | 97 const std::vector<AdblockPlus::SubscriptionPtr>& subscriptions) |
96 { | 98 { |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
462 { | 464 { |
463 Debug("No connections left, shutting down the engine"); | 465 Debug("No connections left, shutting down the engine"); |
464 activeConnections = 0; | 466 activeConnections = 0; |
465 | 467 |
466 // The following exit(0) calls the destructor of _AtlModule from the | 468 // The following exit(0) calls the destructor of _AtlModule from the |
467 // current thread which results in the disaster because there is a | 469 // current thread which results in the disaster because there is a |
468 // running message loop as well as there can be alive notification | 470 // running message loop as well as there can be alive notification |
469 // window which holds v8::Value as well as m_tasks can hold v8::Value | 471 // window which holds v8::Value as well as m_tasks can hold v8::Value |
470 // but JS Engine is destroyed before _AtlModule. BTW, various free | 472 // but JS Engine is destroyed before _AtlModule. BTW, various free |
471 // running threads like Timeout also cause the crash because the engine | 473 // running threads like Timeout also cause the crash because the engine |
472 // is already destroyed. | 474 // is already destroyed. |
Eric
2015/08/19 17:43:38
If it's possible for a dependency of a class to be
sergei
2015/08/20 14:45:41
Yes, this code needs attention. I would like to no
| |
473 _AtlModule.Finalize(); | 475 _AtlModule.Finalize(); |
474 exit(0); | 476 exit(0); |
475 } | 477 } |
476 } | 478 } |
477 | 479 |
478 } | 480 } |
479 | 481 |
480 void OnUpdateAvailable(AdblockPlus::JsValueList& params) | 482 void OnUpdateAvailable(AdblockPlus::JsValueList& params) |
481 { | 483 { |
482 if (params.size() < 1) | 484 if (params.size() < 1) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
532 PreconfigurationValueFromRegistry(L"suppress_first_run_page") == L"true"); | 534 PreconfigurationValueFromRegistry(L"suppress_first_run_page") == L"true"); |
533 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine(new AdblockPlus::FilterE ngine(jsEngine, preconfig)); | 535 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine(new AdblockPlus::FilterE ngine(jsEngine, preconfig)); |
534 return filterEngine; | 536 return filterEngine; |
535 } | 537 } |
536 | 538 |
537 void ABPAtlModule::Finalize() | 539 void ABPAtlModule::Finalize() |
538 { | 540 { |
539 std::condition_variable cv; | 541 std::condition_variable cv; |
540 std::mutex cvMutex; | 542 std::mutex cvMutex; |
541 std::unique_lock<std::mutex> lock(cvMutex); | 543 std::unique_lock<std::mutex> lock(cvMutex); |
542 dispatchTask([&cvMutex, &cv, this] | 544 DispatchTask([&cvMutex, &cv, this] |
543 { | 545 { |
544 if (m_notificationWindow) | 546 if (m_notificationWindow) |
545 { | 547 { |
546 m_notificationWindow->SendMessage(WM_CLOSE); | 548 m_notificationWindow->SendMessage(WM_CLOSE); |
547 } | 549 } |
548 SendMessage(m_msgHWnd, WM_QUIT, 0, 0); | 550 SendMessage(m_msgHWnd, WM_QUIT, 0, 0); |
549 { | 551 { |
550 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex); | 552 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex); |
551 m_tasks.clear(); | 553 m_tasks.clear(); |
552 } | 554 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
589 DebugLastError("Cannot create message only window"); | 591 DebugLastError("Cannot create message only window"); |
590 return E_FAIL; | 592 return E_FAIL; |
591 } | 593 } |
592 | 594 |
593 filterEngine->SetShowNotificationCallback([this](const AdblockPlus::Notificati onPtr& notification) | 595 filterEngine->SetShowNotificationCallback([this](const AdblockPlus::Notificati onPtr& notification) |
594 { | 596 { |
595 if (!notification) | 597 if (!notification) |
596 { | 598 { |
597 return; | 599 return; |
598 } | 600 } |
599 dispatchTask([notification, this] | 601 DispatchTask([notification, this] |
600 { | 602 { |
601 onNewNotification(notification); | 603 onNewNotification(notification); |
602 }); | 604 }); |
603 }); | 605 }); |
604 | 606 |
605 HRESULT retValue = __super::PreMessageLoop(showCmd); | 607 HRESULT retValue = __super::PreMessageLoop(showCmd); |
606 // __super::PreMessageLoop returns S_FALSE because there is nothing to | 608 // __super::PreMessageLoop returns S_FALSE because there is nothing to |
607 // register but S_OK is required to run message loop. | 609 // register but S_OK is required to run message loop. |
608 return FAILED(retValue) ? retValue : S_OK; | 610 return FAILED(retValue) ? retValue : S_OK; |
609 } | 611 } |
610 | 612 |
611 void ABPAtlModule::RunMessageLoop() throw() | 613 void ABPAtlModule::RunMessageLoop() throw() |
612 { | 614 { |
613 MSG msg = {}; | 615 MSG msg = {}; |
614 while (GetMessage(&msg, /*hwnd*/nullptr, /*msgFilterMin*/0, /*msgFilterMax*/0) ) | 616 while (GetMessage(&msg, /*hwnd*/nullptr, /*msgFilterMin*/0, /*msgFilterMax*/0) ) |
615 { | 617 { |
616 if (msg.hwnd == m_msgHWnd && msg.message == CustomMessages::TaskPosted) | 618 if (msg.hwnd == m_msgHWnd && msg.message == CustomMessages::TASK_POSTED) |
617 { | 619 { |
618 processTasks(); | 620 ProcessTasks(); |
619 } | 621 } |
620 TranslateMessage(&msg); | 622 TranslateMessage(&msg); |
621 DispatchMessage(&msg); | 623 DispatchMessage(&msg); |
622 } | 624 } |
623 } | 625 } |
624 | 626 |
625 void ABPAtlModule::onNewNotification(const AdblockPlus::NotificationPtr& notific ation) | 627 void ABPAtlModule::onNewNotification(const AdblockPlus::NotificationPtr& notific ation) |
626 { | 628 { |
627 m_notificationWindow.reset(new NotificationBorderWindow(*notification, GetExeD ir() + L"html\\templates\\")); | 629 m_notificationWindow.reset(new NotificationBorderWindow(*notification, GetExeD ir() + L"html\\templates\\")); |
628 m_notificationWindow->SetOnDestroyed([notification, this] | 630 m_notificationWindow->SetOnDestroyed([notification, this] |
(...skipping 12 matching lines...) Expand all Loading... | |
641 } | 643 } |
642 }); | 644 }); |
643 m_notificationWindow->Create(/*parent window*/nullptr); | 645 m_notificationWindow->Create(/*parent window*/nullptr); |
644 if (m_notificationWindow->operator HWND() != nullptr) | 646 if (m_notificationWindow->operator HWND() != nullptr) |
645 { | 647 { |
646 m_notificationWindow->ShowWindow(SW_SHOWNOACTIVATE); | 648 m_notificationWindow->ShowWindow(SW_SHOWNOACTIVATE); |
647 m_notificationWindow->UpdateWindow(); | 649 m_notificationWindow->UpdateWindow(); |
648 } | 650 } |
649 } | 651 } |
650 | 652 |
651 void ABPAtlModule::dispatchTask(std::function<void()>&& task) | 653 void ABPAtlModule::DispatchTask(std::function<void()>&& task) |
Oleksandr
2015/07/29 10:47:16
Nit: How about "DispatchTask" instead? We usually
| |
652 { | 654 { |
653 { | 655 { |
654 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex); | 656 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex); |
655 m_tasks.emplace_back(std::move(task)); | 657 m_tasks.emplace_back(std::move(task)); |
656 } | 658 } |
657 PostMessageW(m_msgHWnd, CustomMessages::TaskPosted, 0, 0); | 659 PostMessageW(m_msgHWnd, CustomMessages::TASK_POSTED, 0, 0); |
658 } | 660 } |
659 | 661 |
660 void ABPAtlModule::processTasks() | 662 void ABPAtlModule::ProcessTasks() |
Oleksandr
2015/07/29 10:47:16
Nit: ProcessTasks(). Upper case?
| |
661 { | 663 { |
662 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex); | 664 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex); |
663 while(!m_tasks.empty()) | 665 while(!m_tasks.empty()) |
664 { | 666 { |
665 auto task = *m_tasks.begin(); | 667 auto task = *m_tasks.begin(); |
666 m_tasks.pop_front(); | 668 m_tasks.pop_front(); |
667 if (task) | 669 if (task) |
668 task(); | 670 task(); |
669 } | 671 } |
670 } | 672 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
725 }); | 727 }); |
726 | 728 |
727 int retValue = _AtlModule.WinMain(cmdShow); | 729 int retValue = _AtlModule.WinMain(cmdShow); |
728 if (communicationThread.joinable()) | 730 if (communicationThread.joinable()) |
729 { | 731 { |
730 communicationThread.join(); | 732 communicationThread.join(); |
731 } | 733 } |
732 | 734 |
733 return retValue; | 735 return retValue; |
734 } | 736 } |
LEFT | RIGHT |