Line data Source code
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