LCOV - code coverage report
Current view: top level - source/common/event - timer_impl.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 9 16 56.2 %
Date: 2024-01-05 06:35:25 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <chrono>
       4             : 
       5             : #include "envoy/event/timer.h"
       6             : 
       7             : #include "source/common/common/scope_tracker.h"
       8             : #include "source/common/common/utility.h"
       9             : #include "source/common/event/event_impl_base.h"
      10             : #include "source/common/event/libevent.h"
      11             : 
      12             : namespace Envoy {
      13             : namespace Event {
      14             : 
      15             : /**
      16             :  * Utility helper functions for Timer implementation.
      17             :  */
      18             : class TimerUtils {
      19             : public:
      20             :   /**
      21             :    * Intended for consumption by enable(HR)Timer, this method is templated method to avoid implicit
      22             :    * duration conversions for its input arguments. This lets us have an opportunity to check bounds
      23             :    * before doing any conversions. When the passed in duration exceeds INT32_MAX max seconds, the
      24             :    * output will be clipped to yield INT32_MAX seconds and 0 microseconds for the
      25             :    * output argument. We clip to INT32_MAX to guard against overflowing the timeval structure.
      26             :    * Throws an EnvoyException on negative duration input.
      27             :    * @tparam Duration std::chrono duration type, e.g. seconds, milliseconds, ...
      28             :    * @param d duration value
      29             :    * @param tv output parameter that will be updated
      30             :    */
      31        9270 :   template <typename Duration> static void durationToTimeval(const Duration& d, timeval& tv) {
      32        9270 :     if (d.count() < 0) {
      33           0 :       ExceptionUtil::throwEnvoyException(
      34           0 :           fmt::format("Negative duration passed to durationToTimeval(): {}", d.count()));
      35           0 :     };
      36        9270 :     constexpr int64_t clip_to = INT32_MAX; // 136.102208 years
      37        9270 :     auto secs = std::chrono::duration_cast<std::chrono::seconds>(d);
      38        9270 :     if (secs.count() > clip_to) {
      39           0 :       tv.tv_sec = clip_to;
      40           0 :       tv.tv_usec = 0;
      41           0 :       return;
      42           0 :     }
      43             : 
      44        9270 :     auto usecs = std::chrono::duration_cast<std::chrono::microseconds>(d - secs);
      45        9270 :     tv.tv_sec = secs.count();
      46        9270 :     tv.tv_usec = usecs.count();
      47        9270 :   }
      48             : };
      49             : 
      50             : /**
      51             :  * libevent implementation of Timer.
      52             :  */
      53             : class TimerImpl : public Timer, ImplBase {
      54             : public:
      55             :   TimerImpl(Libevent::BasePtr& libevent, TimerCb cb, Event::Dispatcher& dispatcher);
      56             : 
      57             :   // Timer
      58             :   void disableTimer() override;
      59             : 
      60             :   void enableTimer(std::chrono::milliseconds d, const ScopeTrackedObject* scope) override;
      61             :   void enableHRTimer(std::chrono::microseconds us, const ScopeTrackedObject* object) override;
      62             : 
      63             :   bool enabled() override;
      64             : 
      65             : private:
      66             :   void internalEnableTimer(const timeval& tv, const ScopeTrackedObject* scope);
      67             :   TimerCb cb_;
      68             :   Dispatcher& dispatcher_;
      69             :   // This has to be atomic for alarms which are handled out of thread, for
      70             :   // example if the DispatcherImpl::post is called by two threads, they race to
      71             :   // both set this to null.
      72             :   std::atomic<const ScopeTrackedObject*> object_{};
      73             : };
      74             : 
      75             : } // namespace Event
      76             : } // namespace Envoy

Generated by: LCOV version 1.15