diff options
author | 2020-02-21 11:52:28 +0100 | |
---|---|---|
committer | 2020-02-26 13:19:16 +0100 | |
commit | f4433f28b509a9f67ca85d79000ccf9c2f4b7a24 (patch) | |
tree | 0f754bc9d8222f3ace11849165753acd85be3b38 /libtransport/src/utils/deadline_timer.h | |
parent | 0e7669445b6be1163189521eabed7dd0124043c8 (diff) |
[HICN-534] Major rework on libtransport organization
Change-Id: I361b83a18b4fd59be136d5f0817fc28e17e89884
Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'libtransport/src/utils/deadline_timer.h')
-rw-r--r-- | libtransport/src/utils/deadline_timer.h | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/libtransport/src/utils/deadline_timer.h b/libtransport/src/utils/deadline_timer.h new file mode 100644 index 000000000..5187754f0 --- /dev/null +++ b/libtransport/src/utils/deadline_timer.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <utils/event_reactor.h> + +#include <chrono> +#include <cstddef> +#include <cstring> +#include <utility> + +namespace std { +namespace chrono { +namespace detail { + +template <typename From, typename To> +struct posix_duration_cast; + +// chrono -> timespec caster +template <typename Rep, typename Period> +struct posix_duration_cast<std::chrono::duration<Rep, Period>, + struct timespec> { + static struct timespec cast(std::chrono::duration<Rep, Period> const &d) { + struct timespec tv; + + std::chrono::seconds const sec = + std::chrono::duration_cast<std::chrono::seconds>(d); + + tv.tv_sec = sec.count(); + tv.tv_nsec = + std::chrono::duration_cast<std::chrono::nanoseconds>(d - sec).count(); + + return tv; + } +}; + +// timespec -> chrono caster +template <typename Rep, typename Period> +struct posix_duration_cast<struct timespec, + std::chrono::duration<Rep, Period>> { + static std::chrono::duration<Rep, Period> cast(struct timespec const &tv) { + return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>( + std::chrono::seconds(tv.tv_sec) + std::chrono::nanoseconds(tv.tv_nsec)); + } +}; + +} // namespace detail + +// chrono -> timespec +template <typename T, typename Rep, typename Period> +auto duration_cast(std::chrono::duration<Rep, Period> const &d) -> + typename std::enable_if<std::is_same<T, struct timespec>::value, + struct timespec>::type { + return detail::posix_duration_cast<std::chrono::duration<Rep, Period>, + timespec>::cast(d); +} + +// timespec -> chrono +template <typename Duration> +Duration duration_cast(struct timespec const &tv) { + return detail::posix_duration_cast<struct timespec, Duration>::cast(tv); +} + +} // namespace chrono +} // namespace std + +namespace utils { + +template <typename Implementation> +class DeadlineTimer { + public: + virtual ~DeadlineTimer() = default; + + template <typename WaitHandler> + void asyncWait(WaitHandler &&callback) { + static_cast<Implementation *>(this)->asyncWaitImpl( + std::forward<WaitHandler>(callback)); + } + + void wait() { static_cast<Implementation *>(this)->waitImpl(); } + + template <typename T, typename R> + void expiresFromNow(std::chrono::duration<T, R> &&duration) { + static_cast<Implementation *>(this)->expiresFromNowImpl( + std::forward<std::chrono::duration<T, R>>(duration)); + } + + template <typename TimePoint, + typename = typename std::enable_if< + std::is_same<std::remove_reference_t<TimePoint>, + std::chrono::steady_clock::time_point>::value, + TimePoint>::type> + void expiresAt(TimePoint &&time_point) { + static_cast<Implementation *>(this)->expiresAtImpl( + std::forward<TimePoint>(time_point)); + } + + void cancel() { static_cast<Implementation *>(this)->cancelImpl(); } +}; + +} // namespace utils |