libzmq  master
ZeroMQ C++ Core Engine (LIBZMQ)
timers.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3 
4 This file is part of libzmq, the ZeroMQ core engine in C++.
5 
6 libzmq is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10 
11 As a special exception, the Contributors give you permission to link
12 this library with independent modules to produce an executable,
13 regardless of the license terms of these independent modules, and to
14 copy and distribute the resulting executable under terms of your choice,
15 provided that you also meet, for each linked independent module, the
16 terms and conditions of the license of that module. An independent
17 module is a module which is not derived from or based on this library.
18 If you modify this library, you must extend this exception to your
19 version of the library.
20 
21 libzmq is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 License for more details.
25 
26 You should have received a copy of the GNU Lesser General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 */
29 
30 #include "precompiled.hpp"
31 #include "timers.hpp"
32 #include "err.hpp"
33 
35 tag (0xCAFEDADA),
36 next_timer_id (0)
37 {
38 
39 }
40 
42 {
43  // Mark the timers as dead
44  tag = 0xdeadbeef;
45 }
46 
48 {
49  return tag == 0xCAFEDADA;
50 }
51 
52 int zmq::timers_t::add (size_t interval_, timers_timer_fn handler_, void* arg_)
53 {
54  uint64_t when = clock.now_ms() + interval_;
55  timer_t timer = {++next_timer_id, interval_, handler_, arg_};
56  timers.insert (timersmap_t::value_type (when, timer));
57 
58  return timer.timer_id;
59 }
60 
61 int zmq::timers_t::cancel (int timer_id_)
62 {
63  cancelled_timers_t::iterator it = cancelled_timers.find (timer_id_);
64 
65  if (it != cancelled_timers.end ()) {
66  errno = EINVAL;
67  return -1;
68  }
69 
70  cancelled_timers.insert (timer_id_);
71 
72  return 0;
73 }
74 
75 int zmq::timers_t::set_interval (int timer_id_, size_t interval_)
76 {
77  for (timersmap_t::iterator it = timers.begin (); it != timers.end (); ++it) {
78  if (it->second.timer_id == timer_id_) {
79  timer_t timer = it->second;
80  timer.interval = interval_;
81  uint64_t when = clock.now_ms() + interval_;
82  timers.erase (it);
83  timers.insert (timersmap_t::value_type (when, timer));
84 
85  return 0;
86  }
87  }
88 
89  errno = EINVAL;
90  return -1;
91 }
92 
93 int zmq::timers_t::reset (int timer_id_) {
94  for (timersmap_t::iterator it = timers.begin (); it != timers.end (); ++it) {
95  if (it->second.timer_id == timer_id_) {
96  timer_t timer = it->second;
97  uint64_t when = clock.now_ms() + timer.interval;
98  timers.erase (it);
99  timers.insert (timersmap_t::value_type (when, timer));
100 
101  return 0;
102  }
103  }
104 
105  errno = EINVAL;
106  return -1;
107 }
108 
110 {
111  timersmap_t::iterator it = timers.begin ();
112 
113  uint64_t now = clock.now_ms();
114 
115  while (it != timers.end ()) {
116  cancelled_timers_t::iterator cancelled_it = cancelled_timers.find (it->second.timer_id);
117 
118  // Live timer, lets return the timeout
119  if (cancelled_it == cancelled_timers.end ()) {
120  if (it->first > now)
121  return (long) (it->first - now);
122  else
123  return 0;
124  }
125 
126  // Let's remove it from the begining of the list
127  timersmap_t::iterator old = it;
128  ++it;
129  timers.erase (old);
130  cancelled_timers.erase (cancelled_it);
131  }
132 
133  // Wait forever as no timers are alive
134  return -1;
135 }
136 
138 {
139  timersmap_t::iterator it = timers.begin ();
140 
141  uint64_t now = clock.now_ms();
142 
143  while (it != timers.end ()) {
144  cancelled_timers_t::iterator cancelled_it = cancelled_timers.find (it->second.timer_id);
145 
146  // Dead timer, lets remove it and continue
147  if (cancelled_it != cancelled_timers.end ()) {
148  timersmap_t::iterator old = it;
149  ++it;
150  timers.erase (old);
151  cancelled_timers.erase (cancelled_it);
152  continue;
153  }
154 
155  // Map is ordered, if we have to wait for current timer we can stop.
156  if (it->first > now)
157  break;
158 
159  timer_t timer = it->second;
160 
161  timer.handler (timer.timer_id, timer.arg);
162 
163  timersmap_t::iterator old = it;
164  ++it;
165  timers.erase (old);
166  timers.insert (timersmap_t::value_type (now + timer.interval, timer));
167  }
168 
169  return 0;
170 }
timers_timer_fn * handler
Definition: timers.hpp:93
uint64_t now_ms()
Definition: clock.cpp:182
clock_t clock
Definition: timers.hpp:88
void( timers_timer_fn)(int timer_id, void *arg)
Definition: timers.hpp:41
int reset(int timer_id)
Definition: timers.cpp:93
long timeout()
Definition: timers.cpp:109
int add(size_t interval, timers_timer_fn handler, void *arg)
Definition: timers.cpp:52
uint32_t tag
Definition: timers.hpp:83
int next_timer_id
Definition: timers.hpp:85
bool check_tag()
Definition: timers.cpp:47
int set_interval(int timer_id, size_t interval)
Definition: timers.cpp:75
timersmap_t timers
Definition: timers.hpp:98
int cancel(int timer_id)
Definition: timers.cpp:61
int execute()
Definition: timers.cpp:137
cancelled_timers_t cancelled_timers
Definition: timers.hpp:101