Line data Source code
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 "poller_base.hpp"
32 : #include "i_poll_events.hpp"
33 : #include "err.hpp"
34 :
35 2052 : zmq::poller_base_t::poller_base_t ()
36 : {
37 1026 : }
38 :
39 3078 : zmq::poller_base_t::~poller_base_t ()
40 : {
41 : // Make sure there is no more load on the shutdown.
42 1026 : zmq_assert (get_load () == 0);
43 1026 : }
44 :
45 65046 : int zmq::poller_base_t::get_load ()
46 : {
47 131118 : return load.get ();
48 : }
49 :
50 46226 : void zmq::poller_base_t::adjust_load (int amount_)
51 : {
52 46226 : if (amount_ > 0)
53 23116 : load.add (amount_);
54 : else
55 23110 : if (amount_ < 0)
56 23116 : load.sub (-amount_);
57 46226 : }
58 :
59 7290 : void zmq::poller_base_t::add_timer (int timeout_, i_poll_events *sink_, int id_)
60 : {
61 7290 : uint64_t expiration = clock.now_ms () + timeout_;
62 7289 : timer_info_t info = {sink_, id_};
63 21867 : timers.insert (timers_t::value_type (expiration, info));
64 7289 : }
65 :
66 7053 : void zmq::poller_base_t::cancel_timer (i_poll_events *sink_, int id_)
67 : {
68 : // Complexity of this operation is O(n). We assume it is rarely used.
69 49346 : for (timers_t::iterator it = timers.begin (); it != timers.end (); ++it)
70 24676 : if (it->second.sink == sink_ && it->second.id == id_) {
71 7053 : timers.erase (it);
72 7053 : return;
73 : }
74 :
75 : // Timer not found.
76 0 : zmq_assert (false);
77 : }
78 :
79 34014 : uint64_t zmq::poller_base_t::execute_timers ()
80 : {
81 : // Fast track.
82 68028 : if (timers.empty ())
83 : return 0;
84 :
85 : // Get the current time.
86 9685 : uint64_t current = clock.now_ms ();
87 :
88 : // Execute the timers that are already due.
89 19374 : timers_t::iterator it = timers.begin ();
90 29535 : while (it != timers.end ()) {
91 :
92 : // If we have to wait to execute the item, same will be true about
93 : // all the following items (multimap is sorted). Thus we can stop
94 : // checking the subsequent timers and return the time to wait for
95 : // the next timer (at least 1ms).
96 9802 : if (it->first > current)
97 9565 : return it->first - current;
98 :
99 : // Trigger the timer.
100 474 : it->second.sink->timer_event (it->second.id);
101 :
102 : // Remove it from the list of active timers.
103 237 : timers_t::iterator o = it;
104 : ++it;
105 237 : timers.erase (o);
106 : }
107 :
108 : // There are no more timers.
109 : return 0;
110 : }
|