Line data Source code
1 : /*
2 : * Copyright (C) 2023 Sky UK
3 : *
4 : * This library is free software; you can redistribute it and/or
5 : * modify it under the terms of the GNU Lesser General Public
6 : * License as published by the Free Software Foundation;
7 : * version 2.1 of the License.
8 : *
9 : * This library is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : * Lesser General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public
15 : * License along with this library; if not, write to the Free Software
16 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 : */
18 :
19 : #include "Timer.h"
20 : #include <gst/gst.h>
21 :
22 : std::weak_ptr<ITimerFactory> TimerFactory::m_factory;
23 :
24 29 : std::shared_ptr<ITimerFactory> ITimerFactory::getFactory()
25 : {
26 29 : std::shared_ptr<ITimerFactory> factory = TimerFactory::m_factory.lock();
27 :
28 29 : if (!factory)
29 : {
30 : try
31 : {
32 29 : factory = std::make_shared<TimerFactory>();
33 : }
34 0 : catch (const std::exception &e)
35 : {
36 0 : GST_ERROR("Failed to create the timer factory, reason: %s", e.what());
37 : }
38 :
39 29 : TimerFactory::m_factory = factory;
40 : }
41 :
42 29 : return factory;
43 : }
44 :
45 3 : std::unique_ptr<ITimer> TimerFactory::createTimer(const std::chrono::milliseconds &timeout,
46 : const std::function<void()> &callback, TimerType timerType) const
47 : {
48 3 : return std::make_unique<Timer>(timeout, callback, timerType);
49 : }
50 :
51 3 : Timer::Timer(const std::chrono::milliseconds &timeout, const std::function<void()> &callback, TimerType timerType)
52 3 : : m_active{true}, m_timeout{timeout}, m_callback{callback}
53 : {
54 3 : m_thread = std::thread(
55 6 : [this, timerType]()
56 : {
57 : do
58 : {
59 6 : std::unique_lock<std::mutex> lock{m_mutex};
60 17 : if (!m_cv.wait_for(lock, m_timeout, [this]() { return !m_active; }))
61 : {
62 4 : if (m_active && m_callback)
63 : {
64 4 : lock.unlock();
65 4 : m_callback();
66 : }
67 : }
68 6 : } while (timerType == TimerType::PERIODIC && m_active);
69 3 : m_active = false;
70 6 : });
71 3 : }
72 :
73 6 : Timer::~Timer()
74 : {
75 3 : doCancel();
76 6 : }
77 :
78 1 : void Timer::cancel()
79 : {
80 1 : doCancel();
81 : }
82 :
83 4 : bool Timer::isActive() const
84 : {
85 4 : return m_active;
86 : }
87 :
88 4 : void Timer::doCancel()
89 : {
90 4 : m_active = false;
91 :
92 4 : if (std::this_thread::get_id() != m_thread.get_id() && m_thread.joinable())
93 : {
94 3 : m_cv.notify_one();
95 3 : m_thread.join();
96 : }
97 4 : }
|