/proc/self/cwd/source/extensions/io_socket/user_space/file_event_impl.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "source/extensions/io_socket/user_space/file_event_impl.h" |
2 | | |
3 | | #include "source/common/common/assert.h" |
4 | | #include "source/extensions/io_socket/user_space/io_handle.h" |
5 | | |
6 | | namespace Envoy { |
7 | | namespace Extensions { |
8 | | namespace IoSocket { |
9 | | namespace UserSpace { |
10 | | |
11 | | FileEventImpl::FileEventImpl(Event::Dispatcher& dispatcher, Event::FileReadyCb cb, uint32_t events, |
12 | | IoHandle& io_source) |
13 | 0 | : schedulable_(dispatcher.createSchedulableCallback([this, cb]() { |
14 | 0 | auto ephemeral_events = event_listener_.getAndClearEphemeralEvents(); |
15 | 0 | ENVOY_LOG(trace, "User space event {} invokes callbacks on events = {}", |
16 | 0 | static_cast<void*>(this), ephemeral_events); |
17 | 0 | cb(ephemeral_events); |
18 | 0 | })), |
19 | 0 | io_source_(io_source) { |
20 | 0 | setEnabled(events); |
21 | 0 | } |
22 | | |
23 | 0 | void FileEventImpl::activate(uint32_t events) { |
24 | | // Only supported event types are set. |
25 | 0 | ASSERT((events & (Event::FileReadyType::Read | Event::FileReadyType::Write | |
26 | 0 | Event::FileReadyType::Closed)) == events); |
27 | 0 | event_listener_.onEventActivated(events); |
28 | 0 | schedulable_->scheduleCallbackNextIteration(); |
29 | 0 | } |
30 | | |
31 | 0 | void FileEventImpl::setEnabled(uint32_t events) { |
32 | | // Only supported event types are set. |
33 | 0 | ASSERT((events & (Event::FileReadyType::Read | Event::FileReadyType::Write | |
34 | 0 | Event::FileReadyType::Closed)) == events); |
35 | | // Align with Event::FileEventImpl. Clear pending events on updates to the fd event mask to avoid |
36 | | // delivering events that are no longer relevant. |
37 | 0 | event_listener_.clearEphemeralEvents(); |
38 | 0 | event_listener_.setEnabledEvents(events); |
39 | 0 | bool was_enabled = schedulable_->enabled(); |
40 | | // Recalculate activated events. |
41 | 0 | uint32_t events_to_notify = 0; |
42 | 0 | if ((events & Event::FileReadyType::Read) && (io_source_.isReadable() || |
43 | | // Notify Read event when end-of-stream is received. |
44 | 0 | io_source_.isPeerShutDownWrite())) { |
45 | 0 | events_to_notify |= Event::FileReadyType::Read; |
46 | 0 | } |
47 | 0 | if ((events & Event::FileReadyType::Write) && io_source_.isPeerWritable()) { |
48 | 0 | events_to_notify |= Event::FileReadyType::Write; |
49 | 0 | } |
50 | 0 | if ((events & Event::FileReadyType::Closed) && io_source_.isPeerShutDownWrite()) { |
51 | 0 | events_to_notify |= Event::FileReadyType::Closed; |
52 | 0 | } |
53 | 0 | if (events_to_notify != 0) { |
54 | 0 | activate(events_to_notify); |
55 | 0 | } else { |
56 | 0 | schedulable_->cancel(); |
57 | 0 | } |
58 | 0 | ENVOY_LOG( |
59 | 0 | trace, |
60 | 0 | "User space file event {} set enabled events {} and events {} is active. Will {}reschedule.", |
61 | 0 | static_cast<void*>(this), events, events_to_notify, was_enabled ? "not " : ""); |
62 | 0 | } |
63 | | |
64 | 0 | void FileEventImpl::activateIfEnabled(uint32_t events) { |
65 | 0 | ASSERT((events & (Event::FileReadyType::Read | Event::FileReadyType::Write | |
66 | 0 | Event::FileReadyType::Closed)) == events); |
67 | | // Filter out disabled events. |
68 | 0 | uint32_t filtered_events = events & event_listener_.getEnabledEvents(); |
69 | 0 | if (filtered_events == 0) { |
70 | 0 | return; |
71 | 0 | } |
72 | 0 | activate(filtered_events); |
73 | 0 | } |
74 | | } // namespace UserSpace |
75 | | } // namespace IoSocket |
76 | | } // namespace Extensions |
77 | | } // namespace Envoy |