Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
simple_timer.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2022 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include <jau/simple_timer.hpp>
26
27using namespace jau;
28
29void simple_timer::timer_work(service_runner& sr_ref) {
30 if( !sr_ref.shall_stop() ) {
31 // non-blocking sleep in regards to stop()
32 std::unique_lock<std::mutex> lock(sr_ref.mtx_shall_stop()); // RAII-style acquire and relinquish via destructor
33 bool overflow = false;
34 const fraction_timespec timeout_time = getMonotonicTime() + fraction_timespec(duration, &overflow);
35 if( overflow ) {
36 sr_ref.set_shall_stop(); // bail out
37 }
38 std::cv_status s { std::cv_status::no_timeout };
39 while( !sr_ref.shall_stop() && std::cv_status::timeout != s ) {
40 s = wait_until( sr_ref.cv_shall_stop(), lock, timeout_time );
41 if( std::cv_status::timeout == s && !sr_ref.shall_stop() ) {
42 duration = fractions_i64::zero;
43 }
44 }
45 }
46 Timer_func tf;
47 {
48 std::unique_lock<std::mutex> lockReader(mtx_timerfunc); // RAII-style acquire and relinquish via destructor
49 tf = timer_func;
50 }
51 if( !tf.is_null() && !sr_ref.shall_stop() ) {
52 duration = tf(*this);
53 } else {
54 duration = fractions_i64::zero;
55 }
56 if( fractions_i64::zero == duration.load() ) {
57 sr_ref.set_shall_stop();
58 }
59}
60
61simple_timer::simple_timer(const std::string& name, const fraction_i64& service_shutdown_timeout) noexcept
62: timer_service(name, service_shutdown_timeout, jau::bind_member(this, &simple_timer::timer_work)),
63 timer_func(), duration()
64{}
65
66bool simple_timer::start(const fraction_i64& duration_, Timer_func tofunc) noexcept {
67 if( is_running() ) {
68 return false;
69 }
70 timer_func = std::move(tofunc);
71 duration = duration_;
72 timer_service.start();
73 return true;
74}
75
76void simple_timer::start_or_update(const fraction_i64& duration_, Timer_func tofunc) noexcept {
77 if( is_running() ) {
78 std::unique_lock<std::mutex> lockReader(mtx_timerfunc); // RAII-style acquire and relinquish via destructor
79 timer_func = std::move(tofunc);
80 duration = duration_;
81 } else {
82 timer_func = std::move(tofunc);
83 duration = duration_;
84 timer_service.start();
85 }
86}
Service runner, a reusable dedicated thread performing custom user services.
std::mutex & mtx_shall_stop() noexcept
mtx_shall_stop() and cv_shall_stop() allows caller to be notified when shall_stop() changes,...
void set_shall_stop() noexcept
Marks the service thread to stop in due process by flagging shall stop to true.
std::condition_variable & cv_shall_stop() noexcept
mtx_shall_stop() and cv_shall_stop() allows caller to be notified when shall_stop() changes,...
bool shall_stop() const noexcept
Returns true if service shall stop.
bool start(const fraction_i64 &duration_, Timer_func tofunc) noexcept
Start the timer with given user Timer_func function and initial duration.
simple_timer(const std::string &name, const fraction_i64 &service_shutdown_timeout) noexcept
Constructs a new service.
function< fraction_i64(Timer0_ref)> Timer_func
User defined timer function using custom granularity via fraction_i64.
void start_or_update(const fraction_i64 &duration_, Timer_func tofunc) noexcept
Start or update the timer with given user Timer_func function and initial duration.
fraction_timespec getMonotonicTime() noexcept
Returns current monotonic time since Unix Epoch 00:00:00 UTC on 1970-01-01.
Definition: basic_types.cpp:52
jau::function< R(A...)> bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept
Bind given class instance and non-void member function to an anonymous function using func_member_tar...
@ overflow
See FE_OVERFLOW.
constexpr const jau::fraction_i64 zero(0l, 1lu)
zero is 0/1
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
std::cv_status wait_until(std::condition_variable &cv, std::unique_lock< std::mutex > &lock, const fraction_timespec &absolute_time, const bool monotonic=true) noexcept
wait_until causes the current thread to block until the condition variable is notified,...
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
CXX_ALWAYS_INLINE _Tp load() const noexcept