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

Unified Diff: src/DefaultTimer.cpp

Issue 29395640: Issue 3595 - Get rid of detached threads for setTimeout (Closed)
Patch Set: only rebase Created March 27, 2017, 2:44 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/DefaultTimer.cpp
diff --git a/src/DefaultTimer.cpp b/src/DefaultTimer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d4d36e15a3035afe1d7c272b8630a3ed32f1743b
--- /dev/null
+++ b/src/DefaultTimer.cpp
@@ -0,0 +1,83 @@
+/*
+* This file is part of Adblock Plus <https://adblockplus.org/>,
+* Copyright (C) 2006-2017 eyeo GmbH
+*
+* Adblock Plus is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 3 as
+* published by the Free Software Foundation.
+*
+* Adblock Plus is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "DefaultTimer.h"
+
+using AdblockPlus::DefaultTimer;
+
+DefaultTimer::DefaultTimer()
+ : shouldThreadStop(false)
+{
+ m_thread = std::thread([this]
+ {
+ ThreadFunc();
+ });
+}
+
+DefaultTimer::~DefaultTimer()
+{
+ shouldThreadStop = true;
+ conditionVariable.notify_one();
+ if (m_thread.joinable())
+ m_thread.join();
+}
+
+void DefaultTimer::SetTimer(const std::chrono::milliseconds& timeout, const TimerCallback& timerCallback)
+{
+ if (!timerCallback)
+ return;
+ std::lock_guard<std::mutex> lock(mutex);
Oleksandr 2017/03/28 10:39:55 If there's already a timer for let's say 1 minute
sergei 2017/03/28 11:06:59 No, `conditionVariable.wait(lock,...` and `conditi
Oleksandr 2017/03/28 11:11:00 Fair enough.
+ TimerUnit timer = { std::chrono::steady_clock::now() + timeout, timerCallback };
+ timers.push(timer);
+ conditionVariable.notify_one();
+}
+
+void DefaultTimer::ThreadFunc()
+{
+ while (!shouldThreadStop)
+ {
+ std::unique_lock<std::mutex> lock(mutex);
+ if (timers.empty())
+ {
+ conditionVariable.wait(lock, [this]()->bool
+ {
+ return shouldThreadStop || !timers.empty();
+ });
+ }
+ else
+ {
+ conditionVariable.wait_until(lock, timers.top().fireAt);
+ }
+ // execute all expired timers and remove them
+ while (!shouldThreadStop && !timers.empty() && timers.top().fireAt <= std::chrono::steady_clock::now())
+ {
+ auto callback = timers.top().callback;
+ timers.pop();
+ // allow to put new timers while this timer is being processed
+ lock.unlock();
+ try
+ {
+ callback();
+ }
+ catch (...)
+ {
+ // do nothing, but the thread will be alive.
+ }
+ lock.lock();
+ }
+ }
+}
« src/DefaultTimer.h ('K') | « src/DefaultTimer.h ('k') | src/GlobalJsObject.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld