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

Delta Between Two Patch Sets: src/engine/Main.cpp

Issue 6505394822184960: Issue 1109 - Support notifications (Closed)
Left Patch Set: Created May 11, 2015, 10:01 a.m.
Right Patch Set: fix obtaining of DPI value of content (NotificationWindow) of NotificationBorderWindow Created Aug. 18, 2015, 9:43 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
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
Oleksandr 2015/06/24 01:22:34 We have the same in PluginStdAfx.h. Maybe it makes
sergei 2015/06/24 17:31:35 I don't think it's time to unite them. Even more,
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 <thread> 26 #include <thread>
27 #include <mutex>
28 #include <condition_variable>
26 #include <Windows.h> 29 #include <Windows.h>
27 30
28 #include "../shared/AutoHandle.h" 31 #include "../shared/AutoHandle.h"
29 #include "../shared/Communication.h" 32 #include "../shared/Communication.h"
30 #include "../shared/Dictionary.h" 33 #include "../shared/Dictionary.h"
31 #include "../shared/Utils.h" 34 #include "../shared/Utils.h"
32 #include "../shared/Version.h" 35 #include "../shared/Version.h"
33 #include "../shared/CriticalSection.h" 36 #include "../shared/CriticalSection.h"
34 #include "../shared/IE_version.h" 37 #include "IeVersion.h"
35 #include "AdblockPlus.h" 38 #include "AdblockPlus.h"
36 #include "Debug.h" 39 #include "Debug.h"
37 #include "Updater.h" 40 #include "Updater.h"
41 #include "Registry.h"
38 #include "NotificationWindow.h" 42 #include "NotificationWindow.h"
39 43
40 namespace 44 namespace
41 { 45 {
42 class MyModule : public ATL::CAtlExeModuleT<MyModule> { 46 struct ScopedAtlAxInitializer
47 {
48 ScopedAtlAxInitializer()
49 {
50 ATL::AtlAxWinInit();
51 }
52 ~ScopedAtlAxInitializer()
53 {
54 ATL::AtlAxWinTerm();
55 }
56 };
57
58 class ABPAtlModule : public ATL::CAtlExeModuleT<ABPAtlModule>
59 {
60 enum CustomMessages
61 {
62 TASK_POSTED = WM_USER + 1
63 };
64
43 public: 65 public:
66 ABPAtlModule() : m_msgHWnd(nullptr)
67 {
68 }
69 void Finalize();
70 HRESULT PreMessageLoop(int showCmd) 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
72 static HRESULT InitializeCom() throw()
73 {
74 // The default implementation initializes multithreaded version but
75 // in this case hosted ActiveX does not properly work.
76 return CoInitialize(nullptr);
77 }
78 private:
79 void onNewNotification(const AdblockPlus::NotificationPtr& notification);
80 void DispatchTask(std::function<void()>&& task);
81 void ProcessTasks();
82
83 ScopedAtlAxInitializer m_scopedAtlAxInit;
84 HWND m_msgHWnd;
85 std::recursive_mutex m_tasksMutex;
86 std::deque<std::function<void()>> m_tasks;
87 std::unique_ptr<NotificationBorderWindow> m_notificationWindow;
44 } _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
45 89
46 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine; 90 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine;
47 std::auto_ptr<Updater> updater; 91 std::auto_ptr<Updater> updater;
48 int activeConnections = 0; 92 int activeConnections = 0;
49 CriticalSection activeConnectionsLock; 93 CriticalSection activeConnectionsLock;
50 HWND callbackWindow; 94 HWND callbackWindow;
51
52 std::string GetWhitelistingFilter(const std::string& urlArg,
53 const std::vector<std::string>& frameHierarchy, AdblockPlus::FilterEngine::C ontentType type)
54 {
55 auto GetWhitelistingFilter = [&type](const std::string& url, const std::stri ng& parent)->std::string
56 {
57 AdblockPlus::FilterPtr match = filterEngine->Matches(url, type, parent);
58 if (match && match->GetType() == AdblockPlus::Filter::TYPE_EXCEPTION)
59 {
60 return match->GetProperty("text")->AsString();
61 }
62 return "";
63 };
64 if (frameHierarchy.empty())
65 {
66 return GetWhitelistingFilter(urlArg, "");
67 }
68 auto frameIterator = frameHierarchy.begin();
69 std::string parentUrl;
70 std::string url = urlArg;
71 while (frameIterator != frameHierarchy.end())
72 {
73 parentUrl = *frameIterator;
74 auto filterText = GetWhitelistingFilter(url, parentUrl);
75 if (!filterText.empty())
76 {
77 return filterText;
78 }
79 url = parentUrl;
80 ++frameIterator;
81 }
82 return "";
83 }
84 95
85 void WriteSubscriptions(Communication::OutputBuffer& response, 96 void WriteSubscriptions(Communication::OutputBuffer& response,
86 const std::vector<AdblockPlus::SubscriptionPtr>& subscriptions) 97 const std::vector<AdblockPlus::SubscriptionPtr>& subscriptions)
87 { 98 {
88 int32_t count = static_cast<int32_t>(subscriptions.size()); 99 int32_t count = static_cast<int32_t>(subscriptions.size());
89 response << count; 100 response << count;
90 for (int32_t i = 0; i < count; i++) 101 for (int32_t i = 0; i < count; i++)
91 { 102 {
92 AdblockPlus::SubscriptionPtr subscription = subscriptions[i]; 103 AdblockPlus::SubscriptionPtr subscription = subscriptions[i];
93 response << subscription->GetProperty("url")->AsString() 104 response << subscription->GetProperty("url")->AsString()
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 } 249 }
239 } 250 }
240 251
241 response << domains; 252 response << domains;
242 break; 253 break;
243 } 254 }
244 case Communication::PROC_GET_WHITELISTING_FITER: 255 case Communication::PROC_GET_WHITELISTING_FITER:
245 { 256 {
246 std::string url; 257 std::string url;
247 request >> url; 258 request >> url;
248 std::vector<std::string> frameHierarchy; 259 AdblockPlus::FilterPtr match = filterEngine->Matches(url,
249 request >> frameHierarchy; 260 AdblockPlus::FilterEngine::ContentType::CONTENT_TYPE_DOCUMENT, url);
250 response << GetWhitelistingFilter(url, frameHierarchy, AdblockPlus::Filt erEngine::CONTENT_TYPE_DOCUMENT); 261 std::string filterText;
262 if (match && match->GetType() == AdblockPlus::Filter::TYPE_EXCEPTION)
263 {
264 filterText = match->GetProperty("text")->AsString();
265 }
266 response << filterText;
251 break; 267 break;
252 } 268 }
253 case Communication::PROC_IS_ELEMHIDE_WHITELISTED_ON_URL: 269 case Communication::PROC_IS_ELEMHIDE_WHITELISTED_ON_URL:
254 { 270 {
255 std::string url; 271 std::string url;
256 request >> url; 272 request >> url;
257 std::vector<std::string> frameHierarchy; 273 AdblockPlus::FilterPtr match = filterEngine->Matches(url,
258 request >> frameHierarchy; 274 AdblockPlus::FilterEngine::ContentType::CONTENT_TYPE_ELEMHIDE, url);
259 response << !GetWhitelistingFilter(url, frameHierarchy, AdblockPlus::Fil terEngine::CONTENT_TYPE_ELEMHIDE).empty(); 275 response << (match && match->GetType() == AdblockPlus::Filter::TYPE_EXCE PTION);
260 break; 276 break;
261 } 277 }
262 case Communication::PROC_ADD_FILTER: 278 case Communication::PROC_ADD_FILTER:
263 { 279 {
264 std::string text; 280 std::string text;
265 request >> text; 281 request >> text;
266 282
267 filterEngine->GetFilter(text)->AddToList(); 283 filterEngine->GetFilter(text)->AddToList();
268 break; 284 break;
269 } 285 }
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 457
442 Debug("Client disconnected " + threadString); 458 Debug("Client disconnected " + threadString);
443 459
444 { 460 {
445 CriticalSection::Lock lock(activeConnectionsLock); 461 CriticalSection::Lock lock(activeConnectionsLock);
446 activeConnections--; 462 activeConnections--;
447 if (activeConnections < 1) 463 if (activeConnections < 1)
448 { 464 {
449 Debug("No connections left, shutting down the engine"); 465 Debug("No connections left, shutting down the engine");
450 activeConnections = 0; 466 activeConnections = 0;
467
468 // The following exit(0) calls the destructor of _AtlModule from the
469 // current thread which results in the disaster because there is a
470 // running message loop as well as there can be alive notification
471 // window which holds v8::Value as well as m_tasks can hold v8::Value
472 // but JS Engine is destroyed before _AtlModule. BTW, various free
473 // running threads like Timeout also cause the crash because the engine
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
475 _AtlModule.Finalize();
451 exit(0); 476 exit(0);
452 } 477 }
453 } 478 }
454 479
455 } 480 }
456 481
457 void OnUpdateAvailable(AdblockPlus::JsValueList& params) 482 void OnUpdateAvailable(AdblockPlus::JsValueList& params)
458 { 483 {
459 if (params.size() < 1) 484 if (params.size() < 1)
460 { 485 {
461 Debug("updateAvailable event missing URL"); 486 Debug("updateAvailable event missing URL");
462 return; 487 return;
463 } 488 }
464 updateAvailable = true; 489 updateAvailable = true;
465 490
466 updater->Update(params[0]->AsString()); 491 updater->Update(params[0]->AsString());
492 }
493
494 std::wstring PreconfigurationValueFromRegistry(const std::wstring& preconfigNa me)
495 {
496 try
497 {
498 AdblockPlus::RegistryKey regKey(HKEY_CURRENT_USER, L"Software\\AdblockPlus ");
499 return regKey.value_wstring(preconfigName);
500 }
501 catch (const std::runtime_error&)
502 {
503 return L"";
504 }
467 } 505 }
468 506
469 std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine(const std::wstring& locale) 507 std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine(const std::wstring& locale)
470 { 508 {
471 AdblockPlus::AppInfo appInfo; 509 AdblockPlus::AppInfo appInfo;
472 appInfo.version = ToUtf8String(IEPLUGIN_VERSION); 510 appInfo.version = ToUtf8String(IEPLUGIN_VERSION);
473 appInfo.name = "adblockplusie"; 511 appInfo.name = "adblockplusie";
474 #ifdef _WIN64 512 #ifdef _WIN64
475 appInfo.application = "msie64"; 513 appInfo.application = "msie64";
476 #else 514 #else
477 appInfo.application = "msie32"; 515 appInfo.application = "msie32";
478 #endif 516 #endif
479 appInfo.applicationVersion = ToUtf8String(AdblockPlus::IE::InstalledVersionStr ing()); 517 appInfo.applicationVersion = ToUtf8String(AdblockPlus::IE::InstalledVersionStr ing());
480 appInfo.locale = ToUtf8String(locale); 518 appInfo.locale = ToUtf8String(locale);
481 #ifdef ADBLOCK_PLUS_TEST_MODE 519 #ifdef ADBLOCK_PLUS_TEST_MODE
482 appInfo.developmentBuild = true; 520 appInfo.developmentBuild = true;
483 #else 521 #else
484 appInfo.developmentBuild = false; 522 appInfo.developmentBuild = false;
485 #endif 523 #endif
486 524
487 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::New(appInfo); 525 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::New(appInfo);
488 jsEngine->SetEventCallback("updateAvailable", &OnUpdateAvailable); 526 jsEngine->SetEventCallback("updateAvailable", &OnUpdateAvailable);
489 527
490 std::string dataPath = ToUtf8String(GetAppDataPath()); 528 std::string dataPath = ToUtf8String(GetAppDataPath());
491 dynamic_cast<AdblockPlus::DefaultFileSystem*>(jsEngine->GetFileSystem().get()) ->SetBasePath(dataPath); 529 dynamic_cast<AdblockPlus::DefaultFileSystem*>(jsEngine->GetFileSystem().get()) ->SetBasePath(dataPath);
492 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine(new AdblockPlus::FilterE ngine(jsEngine)); 530 std::map<std::string, AdblockPlus::JsValuePtr> preconfig;
531 preconfig["disable_auto_updates"] = jsEngine->NewValue(
532 PreconfigurationValueFromRegistry(L"disable_auto_updates") == L"true");
533 preconfig["suppress_first_run_page"] = jsEngine->NewValue(
534 PreconfigurationValueFromRegistry(L"suppress_first_run_page") == L"true");
535 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine(new AdblockPlus::FilterE ngine(jsEngine, preconfig));
493 return filterEngine; 536 return filterEngine;
494 } 537 }
495 538
496 class ScopedTimer 539 void ABPAtlModule::Finalize()
497 { 540 {
498 public: 541 std::condition_variable cv;
499 explicit ScopedTimer(HWND hwnd, UINT_PTR timerId, UINT elapse, TIMERPROC timer Proc) 542 std::mutex cvMutex;
500 : m_hwnd(hwnd), m_timerId(timerId) 543 std::unique_lock<std::mutex> lock(cvMutex);
501 { 544 DispatchTask([&cvMutex, &cv, this]
502 m_timerId = SetTimer(m_hwnd, m_timerId, elapse, timerProc); 545 {
503 } 546 if (m_notificationWindow)
504 ~ScopedTimer() 547 {
505 { 548 m_notificationWindow->SendMessage(WM_CLOSE);
506 Close(); 549 }
507 } 550 SendMessage(m_msgHWnd, WM_QUIT, 0, 0);
508 551 {
509 UINT_PTR GetID() 552 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex);
510 { 553 m_tasks.clear();
511 return m_timerId; 554 }
512 } 555 std::unique_lock<std::mutex> lock(cvMutex);
513 556 cv.notify_one();
514 operator bool() const 557 });
515 { 558 cv.wait(lock);
516 return m_timerId != 0; 559 }
517 } 560
518 561 HRESULT ABPAtlModule::PreMessageLoop(int showCmd) throw()
519 void Close()
520 {
521 if (m_timerId)
522 {
523 KillTimer(m_hwnd, m_timerId);
524 m_timerId = 0;
525 }
526 }
527 private:
528 ScopedTimer(const ScopedTimer&);
529 ScopedTimer& operator=(const ScopedTimer&);
530 private:
531 HWND m_hwnd;
532 UINT_PTR m_timerId;
533 };
534
535 struct ScopedAtlAxInitializer
536 {
537 ScopedAtlAxInitializer()
538 {
539 ATL::AtlAxWinInit();
540 }
541 ~ScopedAtlAxInitializer()
542 {
543 ATL::AtlAxWinTerm();
544 }
545 };
546
547 void ApplicationMessageLoop(HINSTANCE hInstance)
548 { 562 {
549 const std::wstring className = L"ABPEngineMessageWindow"; 563 const std::wstring className = L"ABPEngineMessageWindow";
550 WNDCLASS wc; 564 WNDCLASS wc;
551 wc.style = 0; 565 wc.style = 0;
552 wc.lpfnWndProc = DefWindowProcW; 566 wc.lpfnWndProc = DefWindowProcW;
553 wc.cbClsExtra = 0; 567 wc.cbClsExtra = 0;
554 wc.cbWndExtra = 0; 568 wc.cbWndExtra = 0;
555 wc.hInstance = hInstance; 569 wc.hInstance = ATL::_AtlBaseModule.GetModuleInstance();
556 wc.hIcon = nullptr; 570 wc.hIcon = nullptr;
557 wc.hCursor = nullptr; 571 wc.hCursor = nullptr;
558 wc.hbrBackground = nullptr; 572 wc.hbrBackground = nullptr;
559 wc.lpszMenuName = nullptr; 573 wc.lpszMenuName = nullptr;
560 wc.lpszClassName = className.c_str(); 574 wc.lpszClassName = className.c_str();
561 ATOM atom = RegisterClass(&wc); 575 ATOM atom = RegisterClass(&wc);
562 if (!atom) 576 if (!atom)
563 { 577 {
564 DebugLastError("Cannot register class for message only window"); 578 DebugLastError("Cannot register class for message only window");
565 return; 579 return E_FAIL;
566 } 580 }
567 HWND msgHWnd = CreateWindowW(className.c_str(), 581 m_msgHWnd = CreateWindowW(className.c_str(),
568 nullptr, // window name 582 nullptr, // window name
569 0, // style 583 0, // style
570 0, 0, 0, 0, // geometry (x, y, w, h) 584 0, 0, 0, 0, // geometry (x, y, w, h)
571 HWND_MESSAGE, // parent 585 HWND_MESSAGE, // parent
572 nullptr, // menu handle 586 nullptr, // menu handle
573 hInstance, 587 wc.hInstance,
574 0); // windows creation data. 588 0); // windows creation data.
575 if (!msgHWnd) 589 if (!m_msgHWnd)
576 { 590 {
577 DebugLastError("Cannot create message only window"); 591 DebugLastError("Cannot create message only window");
578 return; 592 return E_FAIL;
579 } 593 }
594
595 filterEngine->SetShowNotificationCallback([this](const AdblockPlus::Notificati onPtr& notification)
596 {
597 if (!notification)
598 {
599 return;
600 }
601 DispatchTask([notification, this]
602 {
603 onNewNotification(notification);
604 });
605 });
606
607 HRESULT retValue = __super::PreMessageLoop(showCmd);
608 // __super::PreMessageLoop returns S_FALSE because there is nothing to
609 // register but S_OK is required to run message loop.
610 return FAILED(retValue) ? retValue : S_OK;
611 }
612
613 void ABPAtlModule::RunMessageLoop() throw()
614 {
580 MSG msg = {}; 615 MSG msg = {};
581 ScopedTimer notificationTimer(msgHWnd, /*timer ID*/1, 3000/*msec*/, nullptr);
582 std::unique_ptr<NotificationWindow> notificationWindow;
583 while (GetMessage(&msg, /*hwnd*/nullptr, /*msgFilterMin*/0, /*msgFilterMax*/0) ) 616 while (GetMessage(&msg, /*hwnd*/nullptr, /*msgFilterMin*/0, /*msgFilterMax*/0) )
584 { 617 {
585 if (msg.hwnd == msgHWnd) 618 if (msg.hwnd == m_msgHWnd && msg.message == CustomMessages::TASK_POSTED)
586 { 619 {
587 if (msg.message == WM_TIMER) 620 ProcessTasks();
588 {
589 if (msg.wParam == notificationTimer.GetID())
590 {
591 notificationTimer.Close();
592 auto notification = filterEngine->GetNextNotificationToShow();
593 if (notification)
594 {
595 notificationWindow.reset(new NotificationWindow(*notification, GetEx eDir()));
596 notificationWindow->destroyed = [&notificationWindow]
597 {
598 notificationWindow.reset();
599 };
600 notificationWindow->linkClicked = [](const std::wstring& url)
601 {
602 ShellExecute(nullptr, L"open", url.c_str(), nullptr, nullptr, SW_S HOWNORMAL);
Oleksandr 2015/06/24 01:22:34 This will open a default browser, not necessarily
sergei 2015/06/24 17:31:35 I was trying to launch internet explorer using CoC
603 };
604 notificationWindow->Create(/*parent window*/nullptr);
605 if (notificationWindow->operator HWND() != nullptr)
606 {
607 notificationWindow->ShowWindow(SW_SHOWNOACTIVATE);
608 notificationWindow->UpdateWindow();
609 }
610 }
611 }
612 }
613 } 621 }
614 TranslateMessage(&msg); 622 TranslateMessage(&msg);
615 DispatchMessage(&msg); 623 DispatchMessage(&msg);
616 } 624 }
617 } 625 }
618 626
627 void ABPAtlModule::onNewNotification(const AdblockPlus::NotificationPtr& notific ation)
628 {
629 m_notificationWindow.reset(new NotificationBorderWindow(*notification, GetExeD ir() + L"html\\templates\\"));
630 m_notificationWindow->SetOnDestroyed([notification, this]
631 {
632 notification->MarkAsShown();
633 m_notificationWindow.reset();
634 });
635 m_notificationWindow->SetOnLinkClicked([](const std::wstring& url)
636 {
637 ATL::CComPtr<IWebBrowser2> webBrowser;
638 if (SUCCEEDED(webBrowser.CoCreateInstance(__uuidof(InternetExplorer))) && we bBrowser)
639 {
640 ATL::CComVariant emptyVariant;
641 webBrowser->Navigate(ATL::CComBSTR(url.c_str()), &emptyVariant, &emptyVari ant, &emptyVariant, &emptyVariant);
642 webBrowser->put_Visible(VARIANT_TRUE);
643 }
644 });
645 m_notificationWindow->Create(/*parent window*/nullptr);
646 if (m_notificationWindow->operator HWND() != nullptr)
647 {
648 m_notificationWindow->ShowWindow(SW_SHOWNOACTIVATE);
649 m_notificationWindow->UpdateWindow();
650 }
651 }
652
653 void ABPAtlModule::DispatchTask(std::function<void()>&& task)
654 {
655 {
656 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex);
657 m_tasks.emplace_back(std::move(task));
658 }
659 PostMessageW(m_msgHWnd, CustomMessages::TASK_POSTED, 0, 0);
660 }
661
662 void ABPAtlModule::ProcessTasks()
663 {
664 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex);
665 while(!m_tasks.empty())
666 {
667 auto task = *m_tasks.begin();
668 m_tasks.pop_front();
669 if (task)
670 task();
671 }
672 }
673
619 } // namespace { 674 } // namespace {
620 675
621 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) 676 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int cmdShow)
622 { 677 {
623 AutoHandle mutex(CreateMutexW(0, false, L"AdblockPlusEngine")); 678 AutoHandle mutex(CreateMutexW(0, false, L"AdblockPlusEngine"));
624 if (!mutex) 679 if (!mutex)
625 { 680 {
626 DebugLastError("CreateMutex failed"); 681 DebugLastError("CreateMutex failed");
627 return 1; 682 return 1;
628 } 683 }
629 684
630 if (GetLastError() == ERROR_ALREADY_EXISTS) 685 if (GetLastError() == ERROR_ALREADY_EXISTS)
631 { 686 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 return 1; 719 return 1;
665 } 720 }
666 catch (const std::runtime_error& e) 721 catch (const std::runtime_error& e)
667 { 722 {
668 DebugException(e); 723 DebugException(e);
669 return 1; 724 return 1;
670 } 725 }
671 } 726 }
672 }); 727 });
673 728
674 ScopedAtlAxInitializer atlAxInit; 729 int retValue = _AtlModule.WinMain(cmdShow);
675 ApplicationMessageLoop(hInstance);
676 if (communicationThread.joinable()) 730 if (communicationThread.joinable())
677 { 731 {
678 communicationThread.join(); 732 communicationThread.join();
679 } 733 }
680 734
681 735 return retValue;
682 return 0;
683 } 736 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld