Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2022 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #include "Timer.h"
21 : #include "RialtoCommonLogging.h"
22 :
23 : namespace firebolt::rialto::common
24 : {
25 : std::weak_ptr<ITimerFactory> TimerFactory::m_factory;
26 :
27 29 : std::shared_ptr<ITimerFactory> ITimerFactory::getFactory()
28 : {
29 29 : std::shared_ptr<ITimerFactory> factory = TimerFactory::m_factory.lock();
30 :
31 29 : if (!factory)
32 : {
33 : try
34 : {
35 29 : factory = std::make_shared<TimerFactory>();
36 : }
37 0 : catch (const std::exception &e)
38 : {
39 0 : RIALTO_COMMON_LOG_ERROR("Failed to create the timer factory, reason: %s", e.what());
40 : }
41 :
42 29 : TimerFactory::m_factory = factory;
43 : }
44 :
45 29 : return factory;
46 : }
47 :
48 3 : std::unique_ptr<ITimer> TimerFactory::createTimer(const std::chrono::milliseconds &timeout,
49 : const std::function<void()> &callback, TimerType timerType) const
50 : {
51 3 : return std::make_unique<Timer>(timeout, callback, timerType);
52 : }
53 :
54 3 : Timer::Timer(const std::chrono::milliseconds &timeout, const std::function<void()> &callback, TimerType timerType)
55 3 : : m_active{true}, m_timeout{timeout}, m_callback{callback}
56 : {
57 6 : m_thread = std::thread(
58 37 : [this, timerType]()
59 : {
60 : do
61 : {
62 6 : std::unique_lock<std::mutex> lock{m_mutex};
63 17 : if (!m_cv.wait_for(lock, m_timeout, [this]() { return !m_active; }))
64 : {
65 4 : if (m_active && m_callback)
66 : {
67 4 : lock.unlock();
68 4 : m_callback();
69 : }
70 : }
71 6 : } while (timerType == TimerType::PERIODIC && m_active);
72 3 : m_active = false;
73 6 : });
74 3 : }
75 :
76 6 : Timer::~Timer()
77 : {
78 3 : cancel();
79 6 : }
80 :
81 4 : void Timer::cancel()
82 : {
83 4 : m_active = false;
84 :
85 4 : if (std::this_thread::get_id() != m_thread.get_id() && m_thread.joinable())
86 : {
87 3 : m_cv.notify_one();
88 3 : m_thread.join();
89 : }
90 4 : }
91 :
92 4 : bool Timer::isActive() const
93 : {
94 4 : return m_active;
95 : }
96 : } // namespace firebolt::rialto::common
|