blob: e3927ac169a852e162ae17231283e2ecc450bc92 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevf6468892014-01-29 01:04:14 -08002/**
Alexander Afanasyeve6835fe2017-01-19 20:05:01 -08003 * Copyright (c) 2013-2017 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
25#include "../common.hpp"
26#include "monotonic_deadline_timer.hpp"
27
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070028#include <set>
29
Alexander Afanasyevf6468892014-01-29 01:04:14 -080030namespace ndn {
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080031namespace util {
32namespace scheduler {
Alexander Afanasyevf6468892014-01-29 01:04:14 -080033
Alexander Afanasyevf6468892014-01-29 01:04:14 -080034/**
Junxiao Shid50f2b42016-08-10 02:59:59 +000035 * \brief Function to be invoked when a scheduled event expires
Alexander Afanasyevf6468892014-01-29 01:04:14 -080036 */
Junxiao Shid50f2b42016-08-10 02:59:59 +000037typedef function<void()> EventCallback;
38
39/**
40 * \brief Stores internal information about a scheduled event
41 */
42class EventInfo;
43
44/**
45 * \brief Identifies a scheduled event
46 */
47class EventId
48{
49public:
50 /**
51 * \brief Constructs an empty EventId
52 * \note EventId is implicitly convertible from nullptr.
53 */
54 EventId(std::nullptr_t = nullptr)
55 {
56 }
57
58 /**
59 * \retval true The event is valid.
60 * \retval false This EventId is empty, or the event is expired or cancelled.
61 */
62 explicit
63 operator bool() const
64 {
65 return !this->operator!();
66 }
67
68 /**
69 * \retval true This EventId is empty, or the event is expired or cancelled.
70 * \retval false The event is valid.
71 */
72 bool
73 operator!() const;
74
75 /**
76 * \return whether this and other refer to the same event, or are both empty/expired/cancelled
77 */
78 bool
79 operator==(const EventId& other) const;
80
81 bool
82 operator!=(const EventId& other) const
83 {
84 return !this->operator==(other);
85 }
86
87 /**
88 * \brief clear this EventId
89 * \note This does not cancel the event.
90 * \post !(*this)
91 */
92 void
93 reset()
94 {
95 m_info.reset();
96 }
97
98private:
99 explicit
100 EventId(const weak_ptr<EventInfo>& info)
101 : m_info(info)
102 {
103 }
104
105private:
106 weak_ptr<EventInfo> m_info;
107
108 friend class Scheduler;
109 friend std::ostream& operator<<(std::ostream& os, const EventId& eventId);
110};
111
112std::ostream&
113operator<<(std::ostream& os, const EventId& eventId);
114
115class EventQueueCompare
116{
117public:
118 bool
119 operator()(const shared_ptr<EventInfo>& a, const shared_ptr<EventInfo>& b) const;
120};
121
122typedef std::multiset<shared_ptr<EventInfo>, EventQueueCompare> EventQueue;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800123
124/**
125 * \brief Generic scheduler
126 */
Junxiao Shid50f2b42016-08-10 02:59:59 +0000127class Scheduler : noncopyable
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800128{
129public:
Junxiao Shid50f2b42016-08-10 02:59:59 +0000130 explicit
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800131 Scheduler(boost::asio::io_service& ioService);
132
133 /**
Junxiao Shid50f2b42016-08-10 02:59:59 +0000134 * \brief Schedule a one-time event after the specified delay
Junxiao Shi86dfa532016-08-10 03:00:11 +0000135 * \return EventId that can be used to cancel the scheduled event
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800136 */
137 EventId
Junxiao Shid50f2b42016-08-10 02:59:59 +0000138 scheduleEvent(const time::nanoseconds& after, const EventCallback& callback);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800139
140 /**
Junxiao Shid50f2b42016-08-10 02:59:59 +0000141 * \brief Cancel a scheduled event
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800142 */
143 void
144 cancelEvent(const EventId& eventId);
145
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700146 /**
147 * \brief Cancel all scheduled events
148 */
149 void
150 cancelAllEvents();
151
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800152private:
Junxiao Shid50f2b42016-08-10 02:59:59 +0000153 /**
154 * \brief Schedule the next event on the deadline timer
155 */
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800156 void
Junxiao Shid50f2b42016-08-10 02:59:59 +0000157 scheduleNext();
158
Junxiao Shi86dfa532016-08-10 03:00:11 +0000159 /**
160 * \brief Execute expired events
161 * \note If an event callback throws, the exception is propagated to the thread running the
162 * io_service. In case there are other expired events, they will be processed in the next
163 * invocation of this method.
164 */
Junxiao Shid50f2b42016-08-10 02:59:59 +0000165 void
166 executeEvent(const boost::system::error_code& code);
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -0700167
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800168private:
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700169 monotonic_deadline_timer m_deadlineTimer;
Junxiao Shid50f2b42016-08-10 02:59:59 +0000170 EventQueue m_queue;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800171 bool m_isEventExecuting;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800172};
173
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800174} // namespace scheduler
175
176using util::scheduler::Scheduler;
177
178} // namespace util
179
180// for backwards compatibility
181using util::scheduler::Scheduler;
182using util::scheduler::EventId;
183
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800184} // namespace ndn
185
186#endif // NDN_UTIL_SCHEDULER_HPP