diff --git a/include/tscore/Throttler.h b/include/tscore/Throttler.h index 974861ba8f4..79f466598d7 100644 --- a/include/tscore/Throttler.h +++ b/include/tscore/Throttler.h @@ -105,16 +105,27 @@ class Throttler private: /// Base clock. using Clock = std::chrono::system_clock; - /// Time point type, based on the clock to be used. - using TimePoint = Clock::time_point; + + /** A time_point with a noexcept constructor. + * + * This is a workaround for older gcc and clang compilers which implemented an + * older version of the standard which made atomic's noexcept construction + * specification not compatible with time_point's undecorated constructor. + */ + class TimePoint : public Clock::time_point + { + public: + using time_point::time_point; + + // This noexcept specification makes TimePoint compatible with older + // compiler implementations of atomic. + constexpr TimePoint() noexcept : time_point() {} + + template constexpr TimePoint(const time_point &t) : time_point(t) {} + }; /// Time that the last item was emitted. - // It is strange that we need to explicitly default construct this with a - // default constructed TimePoint. Without it, however, I get a compiler error - // in gcc 8.x and 9.x. Playing around in godbolt I notice that neither clang - // nor gcc versions starting from 10.x require this, so I suspect it is a - // compiler bug. - std::atomic _last_allowed_time{TimePoint{}}; + std::atomic _last_allowed_time; /// The minimum number of microseconds desired between actions. std::atomic _interval{std::chrono::microseconds{0}}; diff --git a/src/tscore/Throttler.cc b/src/tscore/Throttler.cc index 99ce38caa24..8ac025fbf91 100644 --- a/src/tscore/Throttler.cc +++ b/src/tscore/Throttler.cc @@ -29,7 +29,7 @@ bool Throttler::is_throttled(uint64_t &skipped_count) { TimePoint const now = Clock::now(); - TimePoint last_allowed_time{_last_allowed_time}; + TimePoint last_allowed_time{_last_allowed_time.load()}; if ((last_allowed_time + _interval.load()) <= now) { if (_last_allowed_time.compare_exchange_strong(last_allowed_time, now)) { skipped_count = _suppressed_count;