1 #include "private/uds/channel_event_set.h" 2 3 #include <log/log.h> 4 5 #include <uds/ipc_helper.h> 6 7 namespace android { 8 namespace pdx { 9 namespace uds { 10 11 ChannelEventSet::ChannelEventSet() { 12 const int flags = EFD_CLOEXEC | EFD_NONBLOCK; 13 LocalHandle epoll_fd, event_fd; 14 15 if (!SetupHandle(epoll_create1(EPOLL_CLOEXEC), &epoll_fd, "epoll") || 16 !SetupHandle(eventfd(0, flags), &event_fd, "event")) { 17 return; 18 } 19 20 epoll_event event; 21 event.events = 0; 22 event.data.u32 = 0; 23 if (epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_fd.Get(), &event) < 0) { 24 const int error = errno; 25 ALOGE("ChannelEventSet::ChannelEventSet: Failed to add event_fd: %s", 26 strerror(error)); 27 return; 28 } 29 30 epoll_fd_ = std::move(epoll_fd); 31 event_fd_ = std::move(event_fd); 32 } 33 34 Status<void> ChannelEventSet::AddDataFd(const LocalHandle& data_fd) { 35 epoll_event event; 36 event.events = EPOLLHUP | EPOLLRDHUP; 37 event.data.u32 = event.events; 38 if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, data_fd.Get(), &event) < 0) { 39 const int error = errno; 40 ALOGE("ChannelEventSet::ChannelEventSet: Failed to add event_fd: %s", 41 strerror(error)); 42 return ErrorStatus{error}; 43 } else { 44 return {}; 45 } 46 } 47 48 int ChannelEventSet::ModifyEvents(int clear_mask, int set_mask) { 49 ALOGD_IF(TRACE, "ChannelEventSet::ModifyEvents: clear_mask=%x set_mask=%x", 50 clear_mask, set_mask); 51 const int old_bits = event_bits_; 52 const int new_bits = (event_bits_ & ~clear_mask) | set_mask; 53 event_bits_ = new_bits; 54 55 // If anything changed clear the event and update the event mask. 56 if (old_bits != new_bits) { 57 eventfd_t value; 58 eventfd_read(event_fd_.Get(), &value); 59 60 epoll_event event; 61 event.events = POLLIN; 62 event.data.u32 = event_bits_; 63 if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, event_fd_.Get(), &event) < 64 0) { 65 const int error = errno; 66 ALOGE("ChannelEventSet::AddEventHandle: Failed to update event: %s", 67 strerror(error)); 68 return -error; 69 } 70 } 71 72 // If there are any bits set, re-trigger the eventfd. 73 if (new_bits) 74 eventfd_write(event_fd_.Get(), 1); 75 76 return 0; 77 } 78 79 Status<void> ChannelEventSet::SetupHandle(int fd, LocalHandle* handle, 80 const char* error_name) { 81 const int error = errno; 82 handle->Reset(fd); 83 if (!*handle) { 84 ALOGE("ChannelEventSet::SetupHandle: Failed to setup %s handle: %s", 85 error_name, strerror(error)); 86 return ErrorStatus{error}; 87 } 88 return {}; 89 } 90 91 Status<int> ChannelEventReceiver::GetPendingEvents() const { 92 constexpr long kTimeoutMs = 0; 93 epoll_event event; 94 const int count = 95 RETRY_EINTR(epoll_wait(epoll_fd_.Get(), &event, 1, kTimeoutMs)); 96 97 Status<int> status; 98 if (count < 0) { 99 status.SetError(errno); 100 ALOGE("ChannelEventReceiver::GetPendingEvents: Failed to get events: %s", 101 status.GetErrorMessage().c_str()); 102 return status; 103 } 104 105 const int mask_out = event.data.u32; 106 ALOGD_IF(TRACE, "ChannelEventReceiver::GetPendingEvents: mask_out=%x", 107 mask_out); 108 109 status.SetValue(mask_out); 110 return status; 111 } 112 113 } // namespace uds 114 } // namespace pdx 115 } // namespace android 116