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_SRC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H
48 #define GRPC_SRC_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 
63 typedef struct grpc_wakeup_fd grpc_wakeup_fd;
64 
65 typedef struct grpc_wakeup_fd_vtable {
66   grpc_error_handle (*init)(grpc_wakeup_fd* fd_info);
67   grpc_error_handle (*consume)(grpc_wakeup_fd* fd_info);
68   grpc_error_handle (*wakeup)(grpc_wakeup_fd* fd_info);
69   void (*destroy)(grpc_wakeup_fd* fd_info);
70   // Must be called before calling any other functions
71   int (*check_availability)(void);
72 } grpc_wakeup_fd_vtable;
73 
74 struct grpc_wakeup_fd {
75   int read_fd;
76   int write_fd;
77 };
78 
79 extern int grpc_allow_specialized_wakeup_fd;
80 extern int grpc_allow_pipe_wakeup_fd;
81 
82 #define GRPC_WAKEUP_FD_GET_READ_FD(fd_info) ((fd_info)->read_fd)
83 
84 grpc_error_handle grpc_wakeup_fd_init(grpc_wakeup_fd* fd_info)
85     GRPC_MUST_USE_RESULT;
86 grpc_error_handle grpc_wakeup_fd_consume_wakeup(grpc_wakeup_fd* fd_info)
87     GRPC_MUST_USE_RESULT;
88 grpc_error_handle grpc_wakeup_fd_wakeup(grpc_wakeup_fd* fd_info)
89     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_SRC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H
97