]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // tick_count_timer.cpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
b32b8144 | 5 | // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | // | |
10 | ||
11 | #include <boost/asio.hpp> | |
12 | #include <ctime> | |
13 | #include <iostream> | |
14 | ||
15 | #if defined(WIN32) | |
16 | # include <windows.h> | |
17 | #else | |
18 | # error This example is for Windows only! | |
19 | #endif | |
20 | ||
21 | struct tick_count_traits | |
22 | { | |
23 | // The time type. This type has no constructor that takes a DWORD to ensure | |
24 | // that the timer can only be used with relative times. | |
25 | class time_type | |
26 | { | |
27 | public: | |
28 | time_type() : ticks_(0) {} | |
29 | private: | |
30 | friend struct tick_count_traits; | |
31 | DWORD ticks_; | |
32 | }; | |
33 | ||
34 | // The duration type. According to the TimeTraits requirements, the duration | |
35 | // must be a signed type. This means we can't handle durations larger than | |
36 | // 2^31. | |
37 | class duration_type | |
38 | { | |
39 | public: | |
40 | duration_type() : ticks_(0) {} | |
41 | duration_type(LONG ticks) : ticks_(ticks) {} | |
42 | private: | |
43 | friend struct tick_count_traits; | |
44 | LONG ticks_; | |
45 | }; | |
46 | ||
47 | // Get the current time. | |
48 | static time_type now() | |
49 | { | |
50 | time_type result; | |
51 | result.ticks_ = ::GetTickCount(); | |
52 | return result; | |
53 | } | |
54 | ||
55 | // Add a duration to a time. | |
56 | static time_type add(const time_type& t, const duration_type& d) | |
57 | { | |
58 | time_type result; | |
59 | result.ticks_ = t.ticks_ + d.ticks_; | |
60 | return result; | |
61 | } | |
62 | ||
63 | // Subtract one time from another. | |
64 | static duration_type subtract(const time_type& t1, const time_type& t2) | |
65 | { | |
66 | // DWORD tick count values can wrap (see less_than() below). We'll convert | |
67 | // to a duration by taking the absolute difference and adding the sign | |
68 | // based on which is the "lesser" absolute time. | |
69 | return duration_type(less_than(t1, t2) | |
70 | ? -static_cast<LONG>(t2.ticks_ - t1.ticks_) | |
71 | : static_cast<LONG>(t1.ticks_ - t2.ticks_)); | |
72 | } | |
73 | ||
74 | // Test whether one time is less than another. | |
75 | static bool less_than(const time_type& t1, const time_type& t2) | |
76 | { | |
77 | // DWORD tick count values wrap periodically, so we'll use a heuristic that | |
78 | // says that if subtracting t1 from t2 yields a value smaller than 2^31, | |
79 | // then t1 is probably less than t2. This means that we can't handle | |
80 | // durations larger than 2^31, which shouldn't be a problem in practice. | |
81 | return (t2.ticks_ - t1.ticks_) < static_cast<DWORD>(1 << 31); | |
82 | } | |
83 | ||
84 | // Convert to POSIX duration type. | |
85 | static boost::posix_time::time_duration to_posix_duration( | |
86 | const duration_type& d) | |
87 | { | |
88 | return boost::posix_time::milliseconds(d.ticks_); | |
89 | } | |
90 | }; | |
91 | ||
92 | typedef boost::asio::basic_deadline_timer< | |
93 | DWORD, tick_count_traits> tick_count_timer; | |
94 | ||
95 | void handle_timeout(const boost::system::error_code&) | |
96 | { | |
97 | std::cout << "handle_timeout\n"; | |
98 | } | |
99 | ||
100 | int main() | |
101 | { | |
102 | try | |
103 | { | |
b32b8144 | 104 | boost::asio::io_context io_context; |
7c673cae | 105 | |
b32b8144 | 106 | tick_count_timer timer(io_context, 5000); |
7c673cae FG |
107 | std::cout << "Starting synchronous wait\n"; |
108 | timer.wait(); | |
109 | std::cout << "Finished synchronous wait\n"; | |
110 | ||
111 | timer.expires_from_now(5000); | |
112 | std::cout << "Starting asynchronous wait\n"; | |
113 | timer.async_wait(&handle_timeout); | |
b32b8144 | 114 | io_context.run(); |
7c673cae FG |
115 | std::cout << "Finished asynchronous wait\n"; |
116 | } | |
117 | catch (std::exception& e) | |
118 | { | |
119 | std::cout << "Exception: " << e.what() << "\n"; | |
120 | } | |
121 | ||
122 | return 0; | |
123 | } |