1 /* 2 * 3 * Copyright 2015 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 /* 20 * wakeup_fd abstracts the concept of a file descriptor for the purpose of 21 * waking up a thread in select()/poll()/epoll_wait()/etc. 22 23 * The poll() family of system calls provide a way for a thread to block until 24 * there is activity on one (or more) of a set of file descriptors. An 25 * application may wish to wake up this thread to do non file related work. The 26 * typical way to do this is to add a pipe to the set of file descriptors, then 27 * write to the pipe to wake up the thread in poll(). 28 * 29 * Linux has a lighter weight eventfd specifically designed for this purpose. 30 * wakeup_fd abstracts the difference between the two. 31 * 32 * Setup: 33 * 1. Before calling anything, call global_init() at least once. 34 * 1. Call grpc_wakeup_fd_init() to set up a wakeup_fd. 35 * 2. Add the result of GRPC_WAKEUP_FD_FD to the set of monitored file 36 * descriptors for the poll() style API you are using. Monitor the file 37 * descriptor for readability. 38 * 3. To tear down, call grpc_wakeup_fd_destroy(). This closes the underlying 39 * file descriptor. 40 * 41 * Usage: 42 * 1. To wake up a polling thread, call grpc_wakeup_fd_wakeup() on a wakeup_fd 43 * it is monitoring. 44 * 2. If the polling thread was awakened by a wakeup_fd event, call 45 * grpc_wakeup_fd_consume_wakeup() on it. 46 */ 47 #ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H 48 #define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H 49 50 #include <grpc/support/port_platform.h> 51 52 #include "src/core/lib/iomgr/error.h" 53 54 void grpc_wakeup_fd_global_init(void); 55 void grpc_wakeup_fd_global_destroy(void); 56 57 /* Force using the fallback implementation. This is intended for testing 58 * purposes only.*/ 59 void grpc_wakeup_fd_global_init_force_fallback(void); 60 61 int grpc_has_wakeup_fd(void); 62 int grpc_cv_wakeup_fds_enabled(void); 63 void grpc_enable_cv_wakeup_fds(int enable); 64 65 typedef struct grpc_wakeup_fd grpc_wakeup_fd; 66 67 typedef struct grpc_wakeup_fd_vtable { 68 grpc_error* (*init)(grpc_wakeup_fd* fd_info); 69 grpc_error* (*consume)(grpc_wakeup_fd* fd_info); 70 grpc_error* (*wakeup)(grpc_wakeup_fd* fd_info); 71 void (*destroy)(grpc_wakeup_fd* fd_info); 72 /* Must be called before calling any other functions */ 73 int (*check_availability)(void); 74 } grpc_wakeup_fd_vtable; 75 76 struct grpc_wakeup_fd { 77 int read_fd; 78 int write_fd; 79 }; 80 81 extern int grpc_allow_specialized_wakeup_fd; 82 extern int grpc_allow_pipe_wakeup_fd; 83 84 #define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd) 85 86 grpc_error* grpc_wakeup_fd_init(grpc_wakeup_fd* fd_info) GRPC_MUST_USE_RESULT; 87 grpc_error* grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd* fd_info) 88 GRPC_MUST_USE_RESULT; 89 grpc_error* grpc_wakeup_fd_wakeup(grpc_wakeup_fd* fd_info) GRPC_MUST_USE_RESULT; 90 void grpc_wakeup_fd_destroy(grpc_wakeup_fd* fd_info); 91 92 /* Defined in some specialized implementation's .c file, or by 93 * wakeup_fd_nospecial.c if no such implementation exists. */ 94 extern const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable; 95 96 #endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H */ 97