blob: 79fbf23497b6b79dfb69d50fbac4b1b8a701969a [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi5bcab562017-07-16 17:19:14 +00002/*
Davide Pesavento5afbb0b2018-01-01 17:24:18 -05003 * Copyright (c) 2013-2018 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevf6468892014-01-29 01:04:14 -080020 */
21
22#ifndef NDN_UTIL_SCHEDULER_HPP
23#define NDN_UTIL_SCHEDULER_HPP
24
Junxiao Shi5bcab562017-07-16 17:19:14 +000025#include "time.hpp"
Davide Pesavento4d0d0962017-12-19 22:23:14 -050026#include "../net/asio-fwd.hpp"
Davide Pesaventobdcedf42017-10-15 14:56:28 -040027
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050028#include <boost/system/error_code.hpp>
Davide Pesaventobdcedf42017-10-15 14:56:28 -040029#include <set>
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070030
Alexander Afanasyevf6468892014-01-29 01:04:14 -080031namespace ndn {
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080032namespace util {
Junxiao Shi5bcab562017-07-16 17:19:14 +000033
34namespace detail {
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050035class SteadyTimer;
Junxiao Shi5bcab562017-07-16 17:19:14 +000036} // namespace detail
37
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080038namespace scheduler {
Alexander Afanasyevf6468892014-01-29 01:04:14 -080039
Alexander Afanasyevf6468892014-01-29 01:04:14 -080040/**
Junxiao Shid50f2b42016-08-10 02:59:59 +000041 * \brief Function to be invoked when a scheduled event expires
Alexander Afanasyevf6468892014-01-29 01:04:14 -080042 */
Junxiao Shi5bcab562017-07-16 17:19:14 +000043using EventCallback = std::function<void()>;
Junxiao Shid50f2b42016-08-10 02:59:59 +000044
45/**
46 * \brief Stores internal information about a scheduled event
47 */
48class EventInfo;
49
50/**
51 * \brief Identifies a scheduled event
52 */
53class EventId
54{
55public:
56 /**
57 * \brief Constructs an empty EventId
58 * \note EventId is implicitly convertible from nullptr.
59 */
60 EventId(std::nullptr_t = nullptr)
61 {
62 }
63
64 /**
65 * \retval true The event is valid.
66 * \retval false This EventId is empty, or the event is expired or cancelled.
67 */
68 explicit
Davide Pesaventobdcedf42017-10-15 14:56:28 -040069 operator bool() const;
Junxiao Shid50f2b42016-08-10 02:59:59 +000070
71 /**
72 * \return whether this and other refer to the same event, or are both empty/expired/cancelled
73 */
74 bool
75 operator==(const EventId& other) const;
76
77 bool
78 operator!=(const EventId& other) const
79 {
80 return !this->operator==(other);
81 }
82
83 /**
84 * \brief clear this EventId
85 * \note This does not cancel the event.
86 * \post !(*this)
87 */
88 void
89 reset()
90 {
91 m_info.reset();
92 }
93
94private:
95 explicit
96 EventId(const weak_ptr<EventInfo>& info)
97 : m_info(info)
98 {
99 }
100
101private:
102 weak_ptr<EventInfo> m_info;
103
104 friend class Scheduler;
105 friend std::ostream& operator<<(std::ostream& os, const EventId& eventId);
106};
107
108std::ostream&
109operator<<(std::ostream& os, const EventId& eventId);
110
111class EventQueueCompare
112{
113public:
114 bool
115 operator()(const shared_ptr<EventInfo>& a, const shared_ptr<EventInfo>& b) const;
116};
117
Junxiao Shi5bcab562017-07-16 17:19:14 +0000118using EventQueue = std::multiset<shared_ptr<EventInfo>, EventQueueCompare>;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800119
120/**
121 * \brief Generic scheduler
122 */
Junxiao Shid50f2b42016-08-10 02:59:59 +0000123class Scheduler : noncopyable
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800124{
125public:
Junxiao Shid50f2b42016-08-10 02:59:59 +0000126 explicit
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800127 Scheduler(boost::asio::io_service& ioService);
128
Junxiao Shi5bcab562017-07-16 17:19:14 +0000129 ~Scheduler();
130
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800131 /**
Junxiao Shid50f2b42016-08-10 02:59:59 +0000132 * \brief Schedule a one-time event after the specified delay
Junxiao Shi86dfa532016-08-10 03:00:11 +0000133 * \return EventId that can be used to cancel the scheduled event
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800134 */
135 EventId
Junxiao Shi5bcab562017-07-16 17:19:14 +0000136 scheduleEvent(time::nanoseconds after, const EventCallback& callback);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800137
138 /**
Junxiao Shid50f2b42016-08-10 02:59:59 +0000139 * \brief Cancel a scheduled event
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800140 */
141 void
142 cancelEvent(const EventId& eventId);
143
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700144 /**
145 * \brief Cancel all scheduled events
146 */
147 void
148 cancelAllEvents();
149
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800150private:
Junxiao Shid50f2b42016-08-10 02:59:59 +0000151 /**
152 * \brief Schedule the next event on the deadline timer
153 */
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800154 void
Junxiao Shid50f2b42016-08-10 02:59:59 +0000155 scheduleNext();
156
Junxiao Shi86dfa532016-08-10 03:00:11 +0000157 /**
158 * \brief Execute expired events
159 * \note If an event callback throws, the exception is propagated to the thread running the
160 * io_service. In case there are other expired events, they will be processed in the next
161 * invocation of this method.
162 */
Junxiao Shid50f2b42016-08-10 02:59:59 +0000163 void
164 executeEvent(const boost::system::error_code& code);
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -0700165
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800166private:
Davide Pesavento5afbb0b2018-01-01 17:24:18 -0500167 unique_ptr<detail::SteadyTimer> m_timer;
Junxiao Shid50f2b42016-08-10 02:59:59 +0000168 EventQueue m_queue;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800169 bool m_isEventExecuting;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800170};
171
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800172} // namespace scheduler
173
174using util::scheduler::Scheduler;
175
176} // namespace util
177
178// for backwards compatibility
179using util::scheduler::Scheduler;
180using util::scheduler::EventId;
181
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800182} // namespace ndn
183
184#endif // NDN_UTIL_SCHEDULER_HPP