blob: 2139c76a7a7b4383c90273ba42a488ffd5a3eea3 [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/*
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
Junxiao Shi5bcab562017-07-16 17:19:14 +000025#include "time.hpp"
Davide Pesaventobdcedf42017-10-15 14:56:28 -040026
Junxiao Shi5bcab562017-07-16 17:19:14 +000027#include <boost/asio/io_service.hpp>
Davide Pesaventobdcedf42017-10-15 14:56:28 -040028#include <set>
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070029
Alexander Afanasyevf6468892014-01-29 01:04:14 -080030namespace ndn {
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080031namespace util {
Junxiao Shi5bcab562017-07-16 17:19:14 +000032
33namespace detail {
34class MonotonicDeadlineTimer;
35} // namespace detail
36
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -080037namespace scheduler {
Alexander Afanasyevf6468892014-01-29 01:04:14 -080038
Alexander Afanasyevf6468892014-01-29 01:04:14 -080039/**
Junxiao Shid50f2b42016-08-10 02:59:59 +000040 * \brief Function to be invoked when a scheduled event expires
Alexander Afanasyevf6468892014-01-29 01:04:14 -080041 */
Junxiao Shi5bcab562017-07-16 17:19:14 +000042using EventCallback = std::function<void()>;
Junxiao Shid50f2b42016-08-10 02:59:59 +000043
44/**
45 * \brief Stores internal information about a scheduled event
46 */
47class EventInfo;
48
49/**
50 * \brief Identifies a scheduled event
51 */
52class EventId
53{
54public:
55 /**
56 * \brief Constructs an empty EventId
57 * \note EventId is implicitly convertible from nullptr.
58 */
59 EventId(std::nullptr_t = nullptr)
60 {
61 }
62
63 /**
64 * \retval true The event is valid.
65 * \retval false This EventId is empty, or the event is expired or cancelled.
66 */
67 explicit
Davide Pesaventobdcedf42017-10-15 14:56:28 -040068 operator bool() const;
Junxiao Shid50f2b42016-08-10 02:59:59 +000069
70 /**
71 * \return whether this and other refer to the same event, or are both empty/expired/cancelled
72 */
73 bool
74 operator==(const EventId& other) const;
75
76 bool
77 operator!=(const EventId& other) const
78 {
79 return !this->operator==(other);
80 }
81
82 /**
83 * \brief clear this EventId
84 * \note This does not cancel the event.
85 * \post !(*this)
86 */
87 void
88 reset()
89 {
90 m_info.reset();
91 }
92
93private:
94 explicit
95 EventId(const weak_ptr<EventInfo>& info)
96 : m_info(info)
97 {
98 }
99
100private:
101 weak_ptr<EventInfo> m_info;
102
103 friend class Scheduler;
104 friend std::ostream& operator<<(std::ostream& os, const EventId& eventId);
105};
106
107std::ostream&
108operator<<(std::ostream& os, const EventId& eventId);
109
110class EventQueueCompare
111{
112public:
113 bool
114 operator()(const shared_ptr<EventInfo>& a, const shared_ptr<EventInfo>& b) const;
115};
116
Junxiao Shi5bcab562017-07-16 17:19:14 +0000117using EventQueue = std::multiset<shared_ptr<EventInfo>, EventQueueCompare>;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800118
119/**
120 * \brief Generic scheduler
121 */
Junxiao Shid50f2b42016-08-10 02:59:59 +0000122class Scheduler : noncopyable
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800123{
124public:
Junxiao Shid50f2b42016-08-10 02:59:59 +0000125 explicit
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800126 Scheduler(boost::asio::io_service& ioService);
127
Junxiao Shi5bcab562017-07-16 17:19:14 +0000128 ~Scheduler();
129
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800130 /**
Junxiao Shid50f2b42016-08-10 02:59:59 +0000131 * \brief Schedule a one-time event after the specified delay
Junxiao Shi86dfa532016-08-10 03:00:11 +0000132 * \return EventId that can be used to cancel the scheduled event
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800133 */
134 EventId
Junxiao Shi5bcab562017-07-16 17:19:14 +0000135 scheduleEvent(time::nanoseconds after, const EventCallback& callback);
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800136
137 /**
Junxiao Shid50f2b42016-08-10 02:59:59 +0000138 * \brief Cancel a scheduled event
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800139 */
140 void
141 cancelEvent(const EventId& eventId);
142
Alexander Afanasyev7ae4bf52014-07-11 17:12:41 -0700143 /**
144 * \brief Cancel all scheduled events
145 */
146 void
147 cancelAllEvents();
148
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800149private:
Junxiao Shid50f2b42016-08-10 02:59:59 +0000150 /**
151 * \brief Schedule the next event on the deadline timer
152 */
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800153 void
Junxiao Shid50f2b42016-08-10 02:59:59 +0000154 scheduleNext();
155
Junxiao Shi86dfa532016-08-10 03:00:11 +0000156 /**
157 * \brief Execute expired events
158 * \note If an event callback throws, the exception is propagated to the thread running the
159 * io_service. In case there are other expired events, they will be processed in the next
160 * invocation of this method.
161 */
Junxiao Shid50f2b42016-08-10 02:59:59 +0000162 void
163 executeEvent(const boost::system::error_code& code);
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -0700164
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800165private:
Junxiao Shi5bcab562017-07-16 17:19:14 +0000166 unique_ptr<detail::MonotonicDeadlineTimer> m_deadlineTimer;
Junxiao Shid50f2b42016-08-10 02:59:59 +0000167 EventQueue m_queue;
Yingdi Yuf2a82092014-02-03 16:49:15 -0800168 bool m_isEventExecuting;
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800169};
170
Alexander Afanasyev9a9952f2015-01-28 19:06:48 -0800171} // namespace scheduler
172
173using util::scheduler::Scheduler;
174
175} // namespace util
176
177// for backwards compatibility
178using util::scheduler::Scheduler;
179using util::scheduler::EventId;
180
Alexander Afanasyevf6468892014-01-29 01:04:14 -0800181} // namespace ndn
182
183#endif // NDN_UTIL_SCHEDULER_HPP