1
#include "source/common/event/schedulable_cb_impl.h"
2

            
3
#include "source/common/common/assert.h"
4

            
5
#include "event2/event.h"
6

            
7
namespace Envoy {
8
namespace Event {
9

            
10
SchedulableCallbackImpl::SchedulableCallbackImpl(Libevent::BasePtr& libevent,
11
                                                 std::function<void()> cb)
12
427221
    : cb_(cb) {
13
427221
  ASSERT(cb_);
14
427221
  evtimer_assign(
15
427221
      &raw_event_, libevent.get(),
16
427221
      [](evutil_socket_t, short, void* arg) -> void {
17
427221
        SchedulableCallbackImpl* cb = static_cast<SchedulableCallbackImpl*>(arg);
18
427221
        cb->cb_();
19
427221
      },
20
427221
      this);
21
427221
}
22

            
23
796014
void SchedulableCallbackImpl::scheduleCallbackCurrentIteration() {
24
796014
  if (enabled()) {
25
17153
    return;
26
17153
  }
27
  // event_active directly adds the event to the end of the work queue so it executes in the current
28
  // iteration of the event loop.
29
778861
  event_active(&raw_event_, EV_TIMEOUT, 0);
30
778861
}
31

            
32
2253743
void SchedulableCallbackImpl::scheduleCallbackNextIteration() {
33
2253743
  if (enabled()) {
34
14283
    return;
35
14283
  }
36
  // libevent computes the list of timers to move to the work list after polling for fd events, but
37
  // iteration through the work list starts. Zero delay timers added while iterating through the
38
  // work list execute on the next iteration of the event loop.
39
2239460
  const timeval zero_tv{};
40
2239460
  event_add(&raw_event_, &zero_tv);
41
2239460
}
42

            
43
640742
void SchedulableCallbackImpl::cancel() { event_del(&raw_event_); }
44

            
45
4442933
bool SchedulableCallbackImpl::enabled() { return 0 != evtimer_pending(&raw_event_, nullptr); }
46

            
47
} // namespace Event
48
} // namespace Envoy