util: reimplement scheduler::EventId with CancelHandle
<ndn-cxx/util/scheduler-scoped-event-id.hpp> header is deprecated.
It has been combined into <ndn-cxx/util/scheduler.hpp>.
Implicit conversion from nullptr to EventId is also deprecated.
refs #4698
Change-Id: I0310d41ac9638cb5be02ae61b887538f562541b2
diff --git a/ndn-cxx/detail/cancel-handle.cpp b/ndn-cxx/detail/cancel-handle.cpp
index 604522b..8057249 100644
--- a/ndn-cxx/detail/cancel-handle.cpp
+++ b/ndn-cxx/detail/cancel-handle.cpp
@@ -25,16 +25,16 @@
namespace detail {
CancelHandle::CancelHandle(function<void()> cancel)
- : doCancel(std::move(cancel))
+ : m_cancel(std::move(cancel))
{
}
void
-CancelHandle::cancel()
+CancelHandle::cancel() const
{
- if (doCancel != nullptr) {
- doCancel();
- doCancel = nullptr;
+ if (m_cancel != nullptr) {
+ m_cancel();
+ m_cancel = nullptr;
}
}
diff --git a/ndn-cxx/detail/cancel-handle.hpp b/ndn-cxx/detail/cancel-handle.hpp
index 11af4e4..e2cb9b5 100644
--- a/ndn-cxx/detail/cancel-handle.hpp
+++ b/ndn-cxx/detail/cancel-handle.hpp
@@ -32,18 +32,18 @@
class CancelHandle
{
public:
+ CancelHandle() noexcept = default;
+
explicit
- CancelHandle(function<void()> cancel = nullptr);
+ CancelHandle(function<void()> cancel);
/** \brief Cancel the operation.
- * \warning Cancelling the same operation more than once, using same or different CancelHandle or
- * ScopedCancelHandle, may trigger undefined behavior.
*/
void
- cancel();
+ cancel() const;
-protected:
- function<void()> doCancel;
+private:
+ mutable function<void()> m_cancel;
};
/** \brief Cancels an operation automatically upon destruction.
@@ -51,7 +51,7 @@
class ScopedCancelHandle
{
public:
- ScopedCancelHandle() = default;
+ ScopedCancelHandle() noexcept = default;
/** \brief Implicit constructor from CancelHandle.
*/
diff --git a/ndn-cxx/impl/face-impl.hpp b/ndn-cxx/impl/face-impl.hpp
index b676efb..2f68557 100644
--- a/ndn-cxx/impl/face-impl.hpp
+++ b/ndn-cxx/impl/face-impl.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -67,7 +67,6 @@
Impl(Face& face)
: m_face(face)
, m_scheduler(m_face.getIoService())
- , m_processEventsTimeoutEvent(m_scheduler)
{
auto postOnEmptyPitOrNoRegisteredPrefixes = [this] {
this->m_face.getIoService().post([this] { this->onEmptyPitOrNoRegisteredPrefixes(); });
diff --git a/ndn-cxx/impl/pending-interest.hpp b/ndn-cxx/impl/pending-interest.hpp
index 4bed422..6495f56 100644
--- a/ndn-cxx/impl/pending-interest.hpp
+++ b/ndn-cxx/impl/pending-interest.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -26,7 +26,7 @@
#include "ndn-cxx/face.hpp"
#include "ndn-cxx/interest.hpp"
#include "ndn-cxx/lp/nack.hpp"
-#include "ndn-cxx/util/scheduler-scoped-event-id.hpp"
+#include "ndn-cxx/util/scheduler.hpp"
namespace ndn {
@@ -80,7 +80,6 @@
, m_dataCallback(dataCallback)
, m_nackCallback(nackCallback)
, m_timeoutCallback(timeoutCallback)
- , m_timeoutEvent(scheduler)
, m_nNotNacked(0)
{
scheduleTimeoutEvent(scheduler);
@@ -95,7 +94,6 @@
PendingInterest(shared_ptr<const Interest> interest, Scheduler& scheduler)
: m_interest(std::move(interest))
, m_origin(PendingInterestOrigin::FORWARDER)
- , m_timeoutEvent(scheduler)
, m_nNotNacked(0)
{
scheduleTimeoutEvent(scheduler);
diff --git a/ndn-cxx/ims/in-memory-storage-entry.cpp b/ndn-cxx/ims/in-memory-storage-entry.cpp
index 6b380c0..148aee1 100644
--- a/ndn-cxx/ims/in-memory-storage-entry.cpp
+++ b/ndn-cxx/ims/in-memory-storage-entry.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -32,7 +32,7 @@
InMemoryStorageEntry::release()
{
m_dataPacket.reset();
- m_markStaleEventId.reset();
+ m_markStaleEventId.cancel();
}
void
@@ -43,15 +43,9 @@
}
void
-InMemoryStorageEntry::setMarkStaleEventId(unique_ptr<util::scheduler::ScopedEventId> markStaleEventId)
+InMemoryStorageEntry::scheduleMarkStale(util::Scheduler& sched, time::nanoseconds after)
{
- m_markStaleEventId = std::move(markStaleEventId);
-}
-
-void
-InMemoryStorageEntry::markStale()
-{
- m_isFresh = false;
+ m_markStaleEventId = sched.scheduleEvent(after, [this] { m_isFresh = false; });
}
} // namespace ndn
diff --git a/ndn-cxx/ims/in-memory-storage-entry.hpp b/ndn-cxx/ims/in-memory-storage-entry.hpp
index c86e038..1640c02 100644
--- a/ndn-cxx/ims/in-memory-storage-entry.hpp
+++ b/ndn-cxx/ims/in-memory-storage-entry.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -24,7 +24,7 @@
#include "ndn-cxx/data.hpp"
#include "ndn-cxx/interest.hpp"
-#include "ndn-cxx/util/scheduler-scoped-event-id.hpp"
+#include "ndn-cxx/util/scheduler.hpp"
namespace ndn {
@@ -74,15 +74,10 @@
void
setData(const Data& data);
- /** @brief Set eventId for the markStale event.
+ /** @brief Schedule an event to mark this entry as non-fresh.
*/
void
- setMarkStaleEventId(unique_ptr<util::scheduler::ScopedEventId> eventId);
-
- /** @brief Disable the data from satisfying interest with MustBeFresh
- */
- void
- markStale();
+ scheduleMarkStale(util::Scheduler& sched, time::nanoseconds after);
/** @brief Check if the data can satisfy an interest with MustBeFresh
*/
@@ -96,7 +91,7 @@
shared_ptr<const Data> m_dataPacket;
bool m_isFresh;
- unique_ptr<util::scheduler::ScopedEventId> m_markStaleEventId;
+ util::scheduler::ScopedEventId m_markStaleEventId;
};
} // namespace ndn
diff --git a/ndn-cxx/ims/in-memory-storage.cpp b/ndn-cxx/ims/in-memory-storage.cpp
index b86dd22..31ec616 100644
--- a/ndn-cxx/ims/in-memory-storage.cpp
+++ b/ndn-cxx/ims/in-memory-storage.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -186,9 +186,7 @@
m_nPackets++;
entry->setData(data);
if (m_scheduler != nullptr && mustBeFreshProcessingWindow > ZERO_WINDOW) {
- auto eventId = make_unique<util::scheduler::ScopedEventId>(*m_scheduler);
- *eventId = m_scheduler->scheduleEvent(mustBeFreshProcessingWindow, [entry] { entry->markStale(); });
- entry->setMarkStaleEventId(std::move(eventId));
+ entry->scheduleMarkStale(*m_scheduler, mustBeFreshProcessingWindow);
}
m_cache.insert(entry);
diff --git a/ndn-cxx/net/impl/network-monitor-impl-osx.cpp b/ndn-cxx/net/impl/network-monitor-impl-osx.cpp
index 838c630..99f606f 100644
--- a/ndn-cxx/net/impl/network-monitor-impl-osx.cpp
+++ b/ndn-cxx/net/impl/network-monitor-impl-osx.cpp
@@ -104,7 +104,6 @@
NetworkMonitorImplOsx::NetworkMonitorImplOsx(boost::asio::io_service& io)
: m_scheduler(io)
- , m_cfLoopEvent(m_scheduler)
, m_context{0, this, nullptr, nullptr, nullptr}
, m_scStore(SCDynamicStoreCreate(nullptr, CFSTR("net.named-data.ndn-cxx.NetworkMonitor"),
&NetworkMonitorImplOsx::onConfigChanged, &m_context))
diff --git a/ndn-cxx/net/impl/network-monitor-impl-osx.hpp b/ndn-cxx/net/impl/network-monitor-impl-osx.hpp
index 44b9af2..c287faa 100644
--- a/ndn-cxx/net/impl/network-monitor-impl-osx.hpp
+++ b/ndn-cxx/net/impl/network-monitor-impl-osx.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -31,7 +31,6 @@
#include "ndn-cxx/detail/cf-releaser-osx.hpp"
#include "ndn-cxx/util/scheduler.hpp"
-#include "ndn-cxx/util/scheduler-scoped-event-id.hpp"
#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>
diff --git a/ndn-cxx/util/notification-subscriber.cpp b/ndn-cxx/util/notification-subscriber.cpp
index da5089b..2ae1e52 100644
--- a/ndn-cxx/util/notification-subscriber.cpp
+++ b/ndn-cxx/util/notification-subscriber.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018 Regents of the University of California,
+ * Copyright (c) 2014-2019 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -42,7 +42,6 @@
, m_lastNackSequenceNum(std::numeric_limits<uint64_t>::max())
, m_attempts(1)
, m_scheduler(face.getIoService())
- , m_nackEvent(m_scheduler)
, m_lastInterestId(nullptr)
, m_interestLifetime(interestLifetime)
{
diff --git a/ndn-cxx/util/notification-subscriber.hpp b/ndn-cxx/util/notification-subscriber.hpp
index ffa37a9..d2bd2fc 100644
--- a/ndn-cxx/util/notification-subscriber.hpp
+++ b/ndn-cxx/util/notification-subscriber.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2018 Regents of the University of California,
+ * Copyright (c) 2014-2019 Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -31,7 +31,6 @@
#include "ndn-cxx/face.hpp"
#include "ndn-cxx/util/concepts.hpp"
#include "ndn-cxx/util/scheduler.hpp"
-#include "ndn-cxx/util/scheduler-scoped-event-id.hpp"
#include "ndn-cxx/util/signal.hpp"
#include "ndn-cxx/util/time.hpp"
diff --git a/ndn-cxx/util/scheduler-scoped-event-id.cpp b/ndn-cxx/util/scheduler-scoped-event-id.cpp
deleted file mode 100644
index d33678a..0000000
--- a/ndn-cxx/util/scheduler-scoped-event-id.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2018 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- */
-
-#include "ndn-cxx/util/scheduler-scoped-event-id.hpp"
-
-namespace ndn {
-namespace util {
-namespace scheduler {
-
-ScopedEventId::ScopedEventId(Scheduler& scheduler) noexcept
- : m_scheduler(&scheduler)
-{
-}
-
-ScopedEventId&
-ScopedEventId::operator=(EventId event)
-{
- if (m_event != event) {
- cancel();
- m_event = std::move(event);
- }
- return *this;
-}
-
-ScopedEventId::~ScopedEventId()
-{
- cancel();
-}
-
-void
-ScopedEventId::cancel()
-{
- m_scheduler->cancelEvent(m_event);
-}
-
-void
-ScopedEventId::release() noexcept
-{
- m_event.reset();
-}
-
-} // namespace scheduler
-} // namespace util
-} // namespace ndn
diff --git a/ndn-cxx/util/scheduler-scoped-event-id.hpp b/ndn-cxx/util/scheduler-scoped-event-id.hpp
index 87372c0..ea30af9 100644
--- a/ndn-cxx/util/scheduler-scoped-event-id.hpp
+++ b/ndn-cxx/util/scheduler-scoped-event-id.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -22,76 +22,8 @@
#ifndef NDN_UTIL_SCHEDULER_SCOPED_EVENT_ID_HPP
#define NDN_UTIL_SCHEDULER_SCOPED_EVENT_ID_HPP
+#pragma message("scheduler-scoped-event-id.hpp has been combined into scheduler.hpp")
+
#include "ndn-cxx/util/scheduler.hpp"
-namespace ndn {
-namespace util {
-namespace scheduler {
-
-/** \brief Event that is automatically cancelled upon destruction.
- */
-class ScopedEventId
-{
-public:
- /** \brief Construct ScopedEventId tied to the specified scheduler.
- * \param scheduler Scheduler to which the event is tied. Behavior is undefined if
- * \p scheduler is destructed before an uncanceled ScopedEventId.
- */
- explicit
- ScopedEventId(Scheduler& scheduler) noexcept;
-
- ScopedEventId(const ScopedEventId&) = delete;
-
- ScopedEventId&
- operator=(const ScopedEventId&) = delete;
-
- /** \brief Move constructor.
- */
- ScopedEventId(ScopedEventId&&) noexcept;
-
- /** \brief Move assignment operator.
- */
- ScopedEventId&
- operator=(ScopedEventId&&) noexcept;
-
- /** \brief Assign an event.
- *
- * If a different event has been assigned to this instance previously,
- * that event will be cancelled immediately.
- *
- * \note The caller should ensure that this ScopedEventId is tied to the correct Scheduler.
- * Behavior is undefined when assigning an event scheduled in another Scheduler instance.
- */
- ScopedEventId&
- operator=(EventId event);
-
- /** \brief Destructor, automatically cancels the event.
- */
- ~ScopedEventId();
-
- /** \brief Manually cancel the event.
- */
- void
- cancel();
-
- /** \brief Release the event so that it won't be canceled when this ScopedEventId is destructed.
- */
- void
- release() noexcept;
-
-private:
- Scheduler* m_scheduler; // pointer to allow move semantics
- EventId m_event;
-};
-
-inline
-ScopedEventId::ScopedEventId(ScopedEventId&&) noexcept = default;
-
-inline ScopedEventId&
-ScopedEventId::operator=(ScopedEventId&&) noexcept = default;
-
-} // namespace scheduler
-} // namespace util
-} // namespace ndn
-
#endif // NDN_UTIL_SCHEDULER_SCOPED_EVENT_ID_HPP
diff --git a/ndn-cxx/util/scheduler.cpp b/ndn-cxx/util/scheduler.cpp
index 0cbb311..36a662c 100644
--- a/ndn-cxx/util/scheduler.cpp
+++ b/ndn-cxx/util/scheduler.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -28,6 +28,8 @@
namespace util {
namespace scheduler {
+/** \brief Stores internal information about a scheduled event
+ */
class EventInfo : noncopyable
{
public:
@@ -51,6 +53,12 @@
EventQueue::const_iterator queueIt;
};
+EventId::EventId(Scheduler& sched, weak_ptr<EventInfo> info)
+ : CancelHandle([&sched, info] { sched.cancelImpl(info.lock()); })
+ , m_info(std::move(info))
+{
+}
+
EventId::operator bool() const noexcept
{
auto sp = m_info.lock();
@@ -64,6 +72,12 @@
!(m_info.owner_before(other.m_info) || other.m_info.owner_before(m_info));
}
+void
+EventId::reset() noexcept
+{
+ *this = {};
+}
+
std::ostream&
operator<<(std::ostream& os, const EventId& eventId)
{
@@ -97,15 +111,14 @@
this->scheduleNext();
}
- return EventId(*i);
+ return EventId(*this, *i);
}
void
-Scheduler::cancelEvent(const EventId& eventId)
+Scheduler::cancelImpl(const shared_ptr<EventInfo>& info)
{
- shared_ptr<EventInfo> info = eventId.m_info.lock();
if (info == nullptr || info->isExpired) {
- return; // event already expired or cancelled
+ return;
}
if (info->queueIt == m_queue.begin()) {
diff --git a/ndn-cxx/util/scheduler.hpp b/ndn-cxx/util/scheduler.hpp
index d5051b7..578d8ca 100644
--- a/ndn-cxx/util/scheduler.hpp
+++ b/ndn-cxx/util/scheduler.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -23,6 +23,7 @@
#define NDN_UTIL_SCHEDULER_HPP
#include "ndn-cxx/detail/asio-fwd.hpp"
+#include "ndn-cxx/detail/cancel-handle.hpp"
#include "ndn-cxx/util/time.hpp"
#include <boost/system/error_code.hpp>
@@ -37,40 +38,47 @@
namespace scheduler {
-/**
- * \brief Function to be invoked when a scheduled event expires
+class Scheduler;
+class EventInfo;
+
+/** \brief Function to be invoked when a scheduled event expires
*/
using EventCallback = std::function<void()>;
-/**
- * \brief Stores internal information about a scheduled event
+/** \brief A handle of scheduled event.
+ *
+ * \code
+ * EventId eid = scheduler.scheduleEvent(10_ms, [] { doSomething(); });
+ * eid.cancel(); // cancel the event
+ * \endcode
+ *
+ * \note Canceling an expired (executed) or canceled event has no effect.
+ * \warning Canceling an event after the scheduler has been destructed may trigger undefined
+ * behavior.
*/
-class EventInfo;
-
-/**
- * \brief Identifies a scheduled event
- */
-class EventId
+class EventId : public ndn::detail::CancelHandle
{
public:
- /**
- * \brief Constructs an empty EventId
- * \note EventId is implicitly convertible from nullptr.
+ /** \brief Constructs an empty EventId
*/
- constexpr
- EventId(std::nullptr_t = nullptr) noexcept
+ EventId() noexcept = default;
+
+ /** \brief Allow implicit conversion from nullptr.
+ */
+ [[deprecated]]
+ EventId(std::nullptr_t) noexcept
{
}
- /**
- * \retval true The event is valid.
- * \retval false This EventId is empty, or the event is expired or cancelled.
+ /** \brief Determine whether the event is valid.
+ * \retval true The event is valid.
+ * \retval false This EventId is empty, or the event is expired or cancelled.
*/
explicit
operator bool() const noexcept;
- /**
- * \return whether this and other refer to the same event, or are both empty/expired/cancelled
+ /** \brief Determine whether this and other refer to the same event, or are both
+ * empty/expired/cancelled.
*/
bool
operator==(const EventId& other) const noexcept;
@@ -81,23 +89,14 @@
return !this->operator==(other);
}
- /**
- * \brief clear this EventId
- * \note This does not cancel the event.
- * \post !(*this)
+ /** \brief Clear this EventId without canceling.
+ * \post !(*this)
*/
void
- reset() noexcept
- {
- m_info.reset();
- }
+ reset() noexcept;
private:
- explicit
- EventId(weak_ptr<EventInfo> info) noexcept
- : m_info(std::move(info))
- {
- }
+ EventId(Scheduler& sched, weak_ptr<EventInfo> info);
private:
weak_ptr<EventInfo> m_info;
@@ -109,6 +108,38 @@
std::ostream&
operator<<(std::ostream& os, const EventId& eventId);
+/** \brief A scoped handle of scheduled event.
+ *
+ * Upon destruction of this handle, the event is canceled automatically.
+ * Most commonly, the application keeps a ScopedEventId as a class member field, so that it can
+ * cleanup its event when the class instance is destructed.
+ *
+ * \code
+ * {
+ * ScopedEventId eid = scheduler.scheduleEvent(10_ms, [] { doSomething(); });
+ * } // eid goes out of scope, canceling the event
+ * \endcode
+ *
+ * \note Canceling an expired (executed) or canceled event has no effect.
+ * \warning Canceling an event after the scheduler has been destructed may trigger undefined
+ * behavior.
+ */
+class ScopedEventId : public ndn::detail::ScopedCancelHandle
+{
+public:
+ using ScopedCancelHandle::ScopedCancelHandle;
+
+ ScopedEventId() noexcept = default;
+
+ /** \deprecated Scheduler argument is no longer necessary. Use default construction instead.
+ */
+ [[deprecated]]
+ explicit
+ ScopedEventId(Scheduler& scheduler) noexcept
+ {
+ }
+};
+
class EventQueueCompare
{
public:
@@ -118,8 +149,7 @@
using EventQueue = std::multiset<shared_ptr<EventInfo>, EventQueueCompare>;
-/**
- * \brief Generic scheduler
+/** \brief Generic scheduler
*/
class Scheduler : noncopyable
{
@@ -129,37 +159,40 @@
~Scheduler();
- /**
- * \brief Schedule a one-time event after the specified delay
- * \return EventId that can be used to cancel the scheduled event
+ /** \brief Schedule a one-time event after the specified delay
+ * \return EventId that can be used to cancel the scheduled event
*/
EventId
scheduleEvent(time::nanoseconds after, const EventCallback& callback);
- /**
- * \brief Cancel a scheduled event
+ /** \brief Cancel a scheduled event
+ *
+ * You may also invoke `eid.cancel()`
*/
void
- cancelEvent(const EventId& eventId);
+ cancelEvent(const EventId& eid)
+ {
+ eid.cancel();
+ }
- /**
- * \brief Cancel all scheduled events
+ /** \brief Cancel all scheduled events
*/
void
cancelAllEvents();
private:
- /**
- * \brief Schedule the next event on the deadline timer
+ void
+ cancelImpl(const shared_ptr<EventInfo>& info);
+
+ /** \brief Schedule the next event on the deadline timer
*/
void
scheduleNext();
- /**
- * \brief Execute expired events
- * \note If an event callback throws, the exception is propagated to the thread running the
- * io_service. In case there are other expired events, they will be processed in the next
- * invocation of this method.
+ /** \brief Execute expired events
+ *
+ * If an event callback throws, the exception is propagated to the thread running the io_service.
+ * In case there are other expired events, they will be processed in the next invocation.
*/
void
executeEvent(const boost::system::error_code& code);
@@ -168,6 +201,8 @@
unique_ptr<detail::SteadyTimer> m_timer;
EventQueue m_queue;
bool m_isEventExecuting;
+
+ friend EventId;
};
} // namespace scheduler
diff --git a/ndn-cxx/util/segment-fetcher.cpp b/ndn-cxx/util/segment-fetcher.cpp
index 6596b74..bc537a5 100644
--- a/ndn-cxx/util/segment-fetcher.cpp
+++ b/ndn-cxx/util/segment-fetcher.cpp
@@ -257,8 +257,7 @@
afterSegmentReceived(data);
// Cancel timeout event
- m_scheduler.cancelEvent(pendingSegmentIt->second.timeoutEvent);
- pendingSegmentIt->second.timeoutEvent = nullptr;
+ pendingSegmentIt->second.timeoutEvent.cancel();
m_validator.validate(data,
bind(&SegmentFetcher::afterValidationSuccess, this, _1, origInterest,
@@ -403,8 +402,7 @@
}
// Cancel timeout event and set status to InRetxQueue
- m_scheduler.cancelEvent(pendingSegmentIt->second.timeoutEvent);
- pendingSegmentIt->second.timeoutEvent = nullptr;
+ pendingSegmentIt->second.timeoutEvent.cancel();
pendingSegmentIt->second.state = SegmentState::InRetxQueue;
m_rttEstimator.backoffRto();
diff --git a/tests/unit/util/scheduler.t.cpp b/tests/unit/util/scheduler.t.cpp
index 5cd9f89..49c90b6 100644
--- a/tests/unit/util/scheduler.t.cpp
+++ b/tests/unit/util/scheduler.t.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -20,7 +20,6 @@
*/
#include "ndn-cxx/util/scheduler.hpp"
-#include "ndn-cxx/util/scheduler-scoped-event-id.hpp"
#include "tests/boost-test.hpp"
#include "tests/unit/unit-test-time-fixture.hpp"
@@ -235,8 +234,7 @@
BOOST_AUTO_TEST_CASE(CancelAllWithScopedEventId) // Bug 3691
{
Scheduler sched(io);
- ScopedEventId eid(sched);
- eid = sched.scheduleEvent(10_ms, []{});
+ ScopedEventId eid = sched.scheduleEvent(10_ms, []{});
sched.cancelAllEvents();
eid.cancel(); // should not crash
@@ -253,10 +251,7 @@
BOOST_AUTO_TEST_CASE(ConstructEmpty)
{
EventId eid;
- eid = nullptr;
- EventId eid2(nullptr);
-
- BOOST_CHECK(!eid && !eid2);
+ BOOST_CHECK(!eid);
}
BOOST_AUTO_TEST_CASE(Compare)
@@ -264,14 +259,10 @@
EventId eid, eid2;
BOOST_CHECK_EQUAL(eid == eid2, true);
BOOST_CHECK_EQUAL(eid != eid2, false);
- BOOST_CHECK_EQUAL(eid == nullptr, true);
- BOOST_CHECK_EQUAL(eid != nullptr, false);
eid = scheduler.scheduleEvent(10_ms, []{});
BOOST_CHECK_EQUAL(eid == eid2, false);
BOOST_CHECK_EQUAL(eid != eid2, true);
- BOOST_CHECK_EQUAL(eid == nullptr, false);
- BOOST_CHECK_EQUAL(eid != nullptr, true);
eid2 = eid;
BOOST_CHECK_EQUAL(eid, eid2);
@@ -309,7 +300,6 @@
// eid is "expired" during callback execution
BOOST_CHECK(!eid);
- BOOST_CHECK(eid == nullptr);
BOOST_CHECK_NE(eid, eid2);
scheduler.cancelEvent(eid2);
@@ -326,7 +316,6 @@
EventId eid = scheduler.scheduleEvent(10_ms, [&isCallbackInvoked] { isCallbackInvoked = true; });
eid.reset();
BOOST_CHECK(!eid);
- BOOST_CHECK(eid == nullptr);
this->advanceClocks(6_ms, 2);
BOOST_CHECK(isCallbackInvoked);
@@ -354,8 +343,7 @@
{
int hit = 0;
{
- ScopedEventId se(scheduler);
- se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
+ ScopedEventId se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
} // se goes out of scope
this->advanceClocks(1_ms, 15);
BOOST_CHECK_EQUAL(hit, 0);
@@ -364,8 +352,7 @@
BOOST_AUTO_TEST_CASE(Assign)
{
int hit1 = 0, hit2 = 0;
- ScopedEventId se1(scheduler);
- se1 = scheduler.scheduleEvent(10_ms, [&] { ++hit1; });
+ ScopedEventId se1 = scheduler.scheduleEvent(10_ms, [&] { ++hit1; });
se1 = scheduler.scheduleEvent(10_ms, [&] { ++hit2; });
this->advanceClocks(1_ms, 15);
BOOST_CHECK_EQUAL(hit1, 0);
@@ -376,8 +363,7 @@
{
int hit = 0;
{
- ScopedEventId se(scheduler);
- se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
+ ScopedEventId se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
se.release();
} // se goes out of scope
this->advanceClocks(1_ms, 15);
@@ -389,17 +375,15 @@
int hit = 0;
unique_ptr<ScopedEventId> se2;
{
- ScopedEventId se(scheduler);
- se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
+ ScopedEventId se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
se2 = make_unique<ScopedEventId>(std::move(se)); // move constructor
} // se goes out of scope
this->advanceClocks(1_ms, 15);
BOOST_CHECK_EQUAL(hit, 1);
- ScopedEventId se3(scheduler);
+ ScopedEventId se3;
{
- ScopedEventId se(scheduler);
- se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
+ ScopedEventId se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
se3 = std::move(se); // move assignment
} // se goes out of scope
this->advanceClocks(1_ms, 15);