1 // Copyright 2022 The gRPC Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // 16 // WakeupFd abstracts the concept of a file descriptor for the purpose of 17 // waking up a thread in select()/poll()/epoll_wait()/etc. 18 19 // The poll() family of system calls provide a way for a thread to block until 20 // there is activity on one (or more) of a set of file descriptors. An 21 // application may wish to wake up this thread to do non file related work. The 22 // typical way to do this is to add a pipe to the set of file descriptors, then 23 // write to the pipe to wake up the thread in poll(). 24 // 25 // Linux has a lighter weight eventfd specifically designed for this purpose. 26 // WakeupFd abstracts the difference between the two. 27 // 28 // Setup: 29 // 1. Call CreateWakeupFd() to crete an initialized WakeupFd. 30 // 2. Add the result of WakeupFd::ReadFd() to the set of monitored file 31 // descriptors for the poll() style API you are using. Monitor the file 32 // descriptor for readability. 33 // 3. To tear down, call WakeupFd::Destroy(). This closes the underlying 34 // file descriptor. 35 // 36 // Usage: 37 // 1. To wake up a polling thread, call WakeupFd::Wakeup() on a wakeup_fd 38 // it is monitoring. 39 // 2. If the polling thread was awakened by a WakeupFd event, call 40 // WakeupFd::Consume() on it. 41 // 42 #ifndef GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_WAKEUP_FD_POSIX_H 43 #define GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_WAKEUP_FD_POSIX_H 44 45 #include <grpc/support/port_platform.h> 46 47 #include "absl/status/status.h" 48 49 namespace grpc_event_engine { 50 namespace experimental { 51 52 class WakeupFd { 53 public: 54 virtual absl::Status ConsumeWakeup() = 0; 55 virtual absl::Status Wakeup() = 0; 56 virtual ~WakeupFd() = default; 57 ReadFd()58 int ReadFd() { return read_fd_; } WriteFd()59 int WriteFd() { return write_fd_; } 60 61 protected: WakeupFd()62 WakeupFd() : read_fd_(0), write_fd_(0) {} SetWakeupFds(int read_fd,int write_fd)63 void SetWakeupFds(int read_fd, int write_fd) { 64 read_fd_ = read_fd; 65 write_fd_ = write_fd; 66 } 67 68 private: 69 int read_fd_; 70 int write_fd_; 71 }; 72 73 } // namespace experimental 74 } // namespace grpc_event_engine 75 76 #endif // GRPC_SRC_CORE_LIB_EVENT_ENGINE_POSIX_ENGINE_WAKEUP_FD_POSIX_H 77