Skip to content

Commit c777f34

Browse files
committed
timers: Add timer::set_interval()
1 parent 03f3727 commit c777f34

4 files changed

Lines changed: 109 additions & 0 deletions

File tree

examples/timers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
add_subdirectory(basic)
2+
add_subdirectory(modify_interval)
23
add_subdirectory(threadpool)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
set(TARGET threadpool-example-timers-modify_interval)
2+
3+
add_executable(${TARGET})
4+
5+
target_link_libraries(
6+
${TARGET}
7+
PRIVATE
8+
threadpool
9+
)
10+
11+
target_sources(
12+
${TARGET}
13+
PRIVATE
14+
main.cpp
15+
)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <timer.hpp>
2+
3+
#include <chrono>
4+
#include <iostream>
5+
6+
void
7+
print_time(std::ostream& out)
8+
{
9+
using clock_type = std::chrono::steady_clock;
10+
11+
static const auto start = clock_type::now();
12+
13+
out << std::chrono::duration_cast<std::chrono::milliseconds>(clock_type::now() - start).count();
14+
}
15+
16+
int
17+
main()
18+
{
19+
using namespace std::chrono_literals;
20+
21+
jbo::timers::executors::standalone<1> te(jbo::timers::manager::instance(), 10ms);
22+
te.start();
23+
24+
// Create periodic timer
25+
auto t1 = jbo::timers::manager::instance().periodic(1s, []{
26+
static std::size_t i = 0;
27+
print_time(std::cout);
28+
std::cout << " | periodic 1: (" << i++ << ") --- thread: " << std::this_thread::get_id() << std::endl;
29+
});
30+
31+
std::this_thread::sleep_for(5s);
32+
33+
// Modify interval
34+
std::cout << "Modifying interval" << std::endl;
35+
t1.set_interval(250ms);
36+
37+
std::this_thread::sleep_for(5s);
38+
39+
// Modify interval
40+
std::cout << "Modifying interval" << std::endl;
41+
t1.set_interval(2500ms);
42+
43+
std::this_thread::sleep_for(5s);
44+
45+
std::cout << "stopping timer executor..." << std::endl;
46+
te.stop();
47+
48+
std::cout << "done" << std::endl;
49+
50+
return EXIT_SUCCESS;
51+
}

lib/jbo/threadpool/timer.hpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ namespace jbo::timers
6262
void
6363
stop();
6464

65+
/**
66+
* Change the interval of a periodic timer.
67+
*
68+
* @note This will fail (do nothing and return false) if the timer is not a constant interval type.
69+
*
70+
* @return Whether the interval was changed successfully.
71+
*/
72+
template<typename Rep, typename Period>
73+
bool
74+
set_interval(const std::chrono::duration<Rep, Period>& interval);
75+
6576
private:
6677
data* m_data = nullptr;
6778
};
@@ -71,6 +82,12 @@ namespace jbo::timers
7182
*/
7283
struct data
7384
{
85+
private:
86+
struct periodic_constant;
87+
struct periodic_uniform;
88+
struct singleshot;
89+
90+
public:
7491
/**
7592
* The task type.
7693
*
@@ -94,6 +111,20 @@ namespace jbo::timers
94111
m_enabled = false;
95112
}
96113

114+
template<typename Rep, typename Period>
115+
bool
116+
set_interval(const std::chrono::duration<Rep, Period>& interval)
117+
{
118+
std::scoped_lock lock(m_mutex);
119+
120+
if (auto pc = std::get_if<periodic_constant>(&m_data); pc) {
121+
pc->interval = std::chrono::duration_cast<decltype(pc->interval)>(interval);
122+
return true;
123+
}
124+
125+
return false;
126+
}
127+
97128
private:
98129
friend struct manager;
99130

@@ -194,6 +225,17 @@ namespace jbo::timers
194225
m_data->stop();
195226
}
196227

228+
template<typename Rep, typename Period>
229+
inline
230+
bool
231+
timer::set_interval(const std::chrono::duration<Rep, Period>& interval)
232+
{
233+
if (!m_data) [[unlikely]]
234+
return false;
235+
236+
return m_data->set_interval(interval);
237+
}
238+
197239
/**
198240
* A manager to manage timers.
199241
*

0 commit comments

Comments
 (0)