blob: 72288889c02569ae450889efe77a6ad89691a183 [file] [log] [blame]
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001/*
2 *
3 * Copyright 2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -070034#include <grpc/grpc_posix.h>
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070035#include <grpc/support/port_platform.h>
36
Sree Kuchibhotla5855c472016-06-08 12:56:56 -070037#ifdef GPR_LINUX_EPOLL
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070038
Sree Kuchibhotla4c11a202016-06-06 09:23:25 -070039#include "src/core/lib/iomgr/ev_epoll_linux.h"
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070040
41#include <assert.h>
42#include <errno.h>
43#include <poll.h>
44#include <signal.h>
45#include <string.h>
46#include <sys/epoll.h>
47#include <sys/socket.h>
48#include <unistd.h>
49
50#include <grpc/support/alloc.h>
51#include <grpc/support/log.h>
52#include <grpc/support/string_util.h>
53#include <grpc/support/tls.h>
54#include <grpc/support/useful.h>
55
56#include "src/core/lib/iomgr/ev_posix.h"
57#include "src/core/lib/iomgr/iomgr_internal.h"
58#include "src/core/lib/iomgr/wakeup_fd_posix.h"
59#include "src/core/lib/profiling/timers.h"
60#include "src/core/lib/support/block_annotate.h"
61
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -070062static int grpc_wakeup_signal = -1;
63static bool is_grpc_wakeup_signal_initialized = false;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070064
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -070065/* Implements the function defined in grpc_posix.h. This function might be
66 * called before even calling grpc_init() to set either a different signal to
67 * use. If signum == -1, then the use of signals is disabled */
68void grpc_use_signal(int signum) {
69 grpc_wakeup_signal = signum;
70 is_grpc_wakeup_signal_initialized = true;
71
72 if (grpc_wakeup_signal < 0) {
73 gpr_log(GPR_INFO,
74 "Use of signals is disabled. Epoll engine will not be used");
75 } else {
76 gpr_log(GPR_INFO, "epoll engine will be using signal: %d",
77 grpc_wakeup_signal);
78 }
79}
80
81struct polling_island;
Sree Kuchibhotla5855c472016-06-08 12:56:56 -070082
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070083/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -070084 * Fd Declarations
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070085 */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070086struct grpc_fd {
87 int fd;
88 /* refst format:
Sree Kuchibhotla5098f912016-05-31 10:58:17 -070089 bit 0 : 1=Active / 0=Orphaned
90 bits 1-n : refcount
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -070091 Ref/Unref by two to avoid altering the orphaned bit */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070092 gpr_atm refst;
93
94 gpr_mu mu;
Sree Kuchibhotla79a62332016-06-04 14:01:03 -070095
96 /* Indicates that the fd is shutdown and that any pending read/write closures
97 should fail */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -070098 bool shutdown;
Sree Kuchibhotla79a62332016-06-04 14:01:03 -070099
100 /* The fd is either closed or we relinquished control of it. In either cases,
101 this indicates that the 'fd' on this structure is no longer valid */
102 bool orphaned;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700103
Sree Kuchibhotla3dbf4d62016-06-08 16:26:45 -0700104 /* TODO: sreek - Move this to a lockfree implementation */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700105 grpc_closure *read_closure;
106 grpc_closure *write_closure;
107
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700108 /* The polling island to which this fd belongs to and the mutex protecting the
109 the field */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700110 gpr_mu pi_mu;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700111 struct polling_island *polling_island;
112
113 struct grpc_fd *freelist_next;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700114 grpc_closure *on_done_closure;
115
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700116 /* The pollset that last noticed that the fd is readable */
117 grpc_pollset *read_notifier_pollset;
118
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700119 grpc_iomgr_object iomgr_object;
120};
121
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700122/* Reference counting for fds */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700123#ifdef GRPC_FD_REF_COUNT_DEBUG
124static void fd_ref(grpc_fd *fd, const char *reason, const char *file, int line);
125static void fd_unref(grpc_fd *fd, const char *reason, const char *file,
126 int line);
127#define GRPC_FD_REF(fd, reason) fd_ref(fd, reason, __FILE__, __LINE__)
128#define GRPC_FD_UNREF(fd, reason) fd_unref(fd, reason, __FILE__, __LINE__)
129#else
130static void fd_ref(grpc_fd *fd);
131static void fd_unref(grpc_fd *fd);
132#define GRPC_FD_REF(fd, reason) fd_ref(fd)
133#define GRPC_FD_UNREF(fd, reason) fd_unref(fd)
134#endif
135
136static void fd_global_init(void);
137static void fd_global_shutdown(void);
138
139#define CLOSURE_NOT_READY ((grpc_closure *)0)
140#define CLOSURE_READY ((grpc_closure *)1)
141
142/*******************************************************************************
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700143 * Polling island Declarations
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700144 */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700145
146// #define GRPC_PI_REF_COUNT_DEBUG
147#ifdef GRPC_PI_REF_COUNT_DEBUG
148
149#define PI_ADD_REF(p, r) pi_add_ref_dbg((p), 1, (r), __FILE__, __LINE__)
150#define PI_UNREF(p, r) pi_unref_dbg((p), 1, (r), __FILE__, __LINE__)
151
152#else /* defined(GRPC_PI_REF_COUNT_DEBUG) */
153
154#define PI_ADD_REF(p, r) pi_add_ref((p), 1)
155#define PI_UNREF(p, r) pi_unref((p), 1)
156
157#endif /* !defined(GPRC_PI_REF_COUNT_DEBUG) */
158
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700159typedef struct polling_island {
160 gpr_mu mu;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700161 /* Ref count. Use PI_ADD_REF() and PI_UNREF() macros to increment/decrement
162 the refcount.
163 Once the ref count becomes zero, this structure is destroyed which means
164 we should ensure that there is never a scenario where a PI_ADD_REF() is
165 racing with a PI_UNREF() that just made the ref_count zero. */
166 gpr_atm ref_count;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700167
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700168 /* Pointer to the polling_island this merged into.
169 * merged_to value is only set once in polling_island's lifetime (and that too
170 * only if the island is merged with another island). Because of this, we can
171 * use gpr_atm type here so that we can do atomic access on this and reduce
172 * lock contention on 'mu' mutex.
173 *
174 * Note that if this field is not NULL (i.e not 0), all the remaining fields
175 * (except mu and ref_count) are invalid and must be ignored. */
176 gpr_atm merged_to;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700177
178 /* The fd of the underlying epoll set */
179 int epoll_fd;
180
181 /* The file descriptors in the epoll set */
182 size_t fd_cnt;
183 size_t fd_capacity;
184 grpc_fd **fds;
185
186 /* Polling islands that are no longer needed are kept in a freelist so that
187 they can be reused. This field points to the next polling island in the
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700188 free list */
189 struct polling_island *next_free;
190} polling_island;
191
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700192/*******************************************************************************
193 * Pollset Declarations
194 */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700195struct grpc_pollset_worker {
Sree Kuchibhotla9bc3d2d2016-06-06 10:27:56 -0700196 pthread_t pt_id; /* Thread id of this worker */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700197 struct grpc_pollset_worker *next;
198 struct grpc_pollset_worker *prev;
199};
200
201struct grpc_pollset {
202 gpr_mu mu;
203 grpc_pollset_worker root_worker;
204 bool kicked_without_pollers;
205
206 bool shutting_down; /* Is the pollset shutting down ? */
207 bool finish_shutdown_called; /* Is the 'finish_shutdown_locked()' called ? */
208 grpc_closure *shutdown_done; /* Called after after shutdown is complete */
209
210 /* The polling island to which this pollset belongs to and the mutex
211 protecting the field */
Sree Kuchibhotlae682e462016-06-08 15:40:21 -0700212 /* TODO: sreek: This lock might actually be adding more overhead to the
213 critical path (i.e pollset_work() function). Consider removing this lock
214 and just using the overall pollset lock */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700215 gpr_mu pi_mu;
216 struct polling_island *polling_island;
217};
218
219/*******************************************************************************
220 * Pollset-set Declarations
221 */
Sree Kuchibhotla3dbf4d62016-06-08 16:26:45 -0700222/* TODO: sreek - Change the pollset_set implementation such that a pollset_set
223 * directly points to a polling_island (and adding an fd/pollset/pollset_set to
224 * the current pollset_set would result in polling island merges. This would
225 * remove the need to maintain fd_count here. This will also significantly
226 * simplify the grpc_fd structure since we would no longer need to explicitly
227 * maintain the orphaned state */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700228struct grpc_pollset_set {
229 gpr_mu mu;
230
231 size_t pollset_count;
232 size_t pollset_capacity;
233 grpc_pollset **pollsets;
234
235 size_t pollset_set_count;
236 size_t pollset_set_capacity;
237 struct grpc_pollset_set **pollset_sets;
238
239 size_t fd_count;
240 size_t fd_capacity;
241 grpc_fd **fds;
242};
243
244/*******************************************************************************
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700245 * Polling island Definitions
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700246 */
247
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700248/* The wakeup fd that is used to wake up all threads in a Polling island. This
249 is useful in the polling island merge operation where we need to wakeup all
250 the threads currently polling the smaller polling island (so that they can
251 start polling the new/merged polling island)
252
253 NOTE: This fd is initialized to be readable and MUST NOT be consumed i.e the
254 threads that woke up MUST NOT call grpc_wakeup_fd_consume_wakeup() */
255static grpc_wakeup_fd polling_island_wakeup_fd;
256
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700257/* Polling island freelist */
258static gpr_mu g_pi_freelist_mu;
259static polling_island *g_pi_freelist = NULL;
260
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700261static void polling_island_delete(); /* Forward declaration */
262
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -0700263#ifdef GRPC_TSAN
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700264/* Currently TSAN may incorrectly flag data races between epoll_ctl and
265 epoll_wait for any grpc_fd structs that are added to the epoll set via
266 epoll_ctl and are returned (within a very short window) via epoll_wait().
267
268 To work-around this race, we establish a happens-before relation between
269 the code just-before epoll_ctl() and the code after epoll_wait() by using
270 this atomic */
271gpr_atm g_epoll_sync;
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -0700272#endif /* defined(GRPC_TSAN) */
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700273
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700274#ifdef GRPC_PI_REF_COUNT_DEBUG
275long pi_add_ref(polling_island *pi, int ref_cnt);
276long pi_unref(polling_island *pi, int ref_cnt);
277
278void pi_add_ref_dbg(polling_island *pi, int ref_cnt, char *reason, char *file,
279 int line) {
280 long old_cnt = pi_add_ref(pi, ref_cnt);
281 gpr_log(GPR_DEBUG, "Add ref pi: %p, old:%ld -> new:%ld (%s) - (%s, %d)",
282 (void *)pi, old_cnt, (old_cnt + ref_cnt), reason, file, line);
283}
284
285void pi_unref_dbg(polling_island *pi, int ref_cnt, char *reason, char *file,
286 int line) {
287 long old_cnt = pi_unref(pi, ref_cnt);
288 gpr_log(GPR_DEBUG, "Unref pi: %p, old:%ld -> new:%ld (%s) - (%s, %d)",
289 (void *)pi, old_cnt, (old_cnt - ref_cnt), reason, file, line);
290}
291#endif
292
293long pi_add_ref(polling_island *pi, int ref_cnt) {
294 return gpr_atm_no_barrier_fetch_add(&pi->ref_count, ref_cnt);
295}
296
297long pi_unref(polling_island *pi, int ref_cnt) {
298 long old_cnt = gpr_atm_no_barrier_fetch_add(&pi->ref_count, -ref_cnt);
299
300 /* If ref count went to zero, delete the polling island. Note that this need
301 not be done under a lock. Once the ref count goes to zero, we are
302 guaranteed that no one else holds a reference to the polling island (and
303 that there is no racing pi_add_ref() call either.
304
305 Also, if we are deleting the polling island and the merged_to field is
306 non-empty, we should remove a ref to the merged_to polling island
307 */
308 if (old_cnt == ref_cnt) {
309 polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
310 polling_island_delete(pi);
311 if (next != NULL) {
312 PI_UNREF(next, "pi_delete"); /* Recursive call */
313 }
314 }
315
316 return old_cnt;
317}
318
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700319/* The caller is expected to hold pi->mu lock before calling this function */
320static void polling_island_add_fds_locked(polling_island *pi, grpc_fd **fds,
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700321 size_t fd_count, bool add_fd_refs) {
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700322 int err;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700323 size_t i;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700324 struct epoll_event ev;
325
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -0700326#ifdef GRPC_TSAN
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700327 /* See the definition of g_epoll_sync for more context */
328 gpr_atm_rel_store(&g_epoll_sync, 0);
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -0700329#endif /* defined(GRPC_TSAN) */
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700330
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700331 for (i = 0; i < fd_count; i++) {
332 ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
333 ev.data.ptr = fds[i];
334 err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_ADD, fds[i]->fd, &ev);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700335
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700336 if (err < 0) {
337 if (errno != EEXIST) {
338 /* TODO: sreek - We need a better way to bubble up this error instead of
339 just logging a message */
340 gpr_log(GPR_ERROR, "epoll_ctl add for fd: %d failed with error: %s",
341 fds[i]->fd, strerror(errno));
342 }
343
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700344 continue;
345 }
346
347 if (pi->fd_cnt == pi->fd_capacity) {
348 pi->fd_capacity = GPR_MAX(pi->fd_capacity + 8, pi->fd_cnt * 3 / 2);
349 pi->fds = gpr_realloc(pi->fds, sizeof(grpc_fd *) * pi->fd_capacity);
350 }
351
352 pi->fds[pi->fd_cnt++] = fds[i];
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700353 if (add_fd_refs) {
354 GRPC_FD_REF(fds[i], "polling_island");
355 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700356 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700357}
358
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700359/* The caller is expected to hold pi->mu before calling this */
360static void polling_island_add_wakeup_fd_locked(polling_island *pi,
361 grpc_wakeup_fd *wakeup_fd) {
362 struct epoll_event ev;
363 int err;
364
365 ev.events = (uint32_t)(EPOLLIN | EPOLLET);
366 ev.data.ptr = wakeup_fd;
367 err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_ADD,
368 GRPC_WAKEUP_FD_GET_READ_FD(wakeup_fd), &ev);
369 if (err < 0) {
370 gpr_log(GPR_ERROR,
371 "Failed to add grpc_wake_up_fd (%d) to the epoll set (epoll_fd: %d)"
372 ". Error: %s",
373 GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), pi->epoll_fd,
374 strerror(errno));
375 }
376}
377
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700378/* The caller is expected to hold pi->mu lock before calling this function */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700379static void polling_island_remove_all_fds_locked(polling_island *pi,
380 bool remove_fd_refs) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700381 int err;
382 size_t i;
383
384 for (i = 0; i < pi->fd_cnt; i++) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700385 err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_DEL, pi->fds[i]->fd, NULL);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700386 if (err < 0 && errno != ENOENT) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700387 /* TODO: sreek - We need a better way to bubble up this error instead of
Sree Kuchibhotlaad162ba2016-06-06 16:23:37 -0700388 * just logging a message */
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -0700389 gpr_log(GPR_ERROR,
390 "epoll_ctl deleting fds[%zu]: %d failed with error: %s", i,
391 pi->fds[i]->fd, strerror(errno));
Sree Kuchibhotlaad162ba2016-06-06 16:23:37 -0700392 }
393
394 if (remove_fd_refs) {
395 GRPC_FD_UNREF(pi->fds[i], "polling_island");
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700396 }
397 }
398
399 pi->fd_cnt = 0;
400}
401
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700402/* The caller is expected to hold pi->mu lock before calling this function */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700403static void polling_island_remove_fd_locked(polling_island *pi, grpc_fd *fd,
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700404 bool is_fd_closed) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700405 int err;
406 size_t i;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700407
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700408 /* If fd is already closed, then it would have been automatically been removed
409 from the epoll set */
410 if (!is_fd_closed) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700411 err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_DEL, fd->fd, NULL);
412 if (err < 0 && errno != ENOENT) {
Sree Kuchibhotlaad162ba2016-06-06 16:23:37 -0700413 gpr_log(GPR_ERROR, "epoll_ctl deleting fd: %d failed with error; %s",
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700414 fd->fd, strerror(errno));
415 }
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700416 }
417
418 for (i = 0; i < pi->fd_cnt; i++) {
419 if (pi->fds[i] == fd) {
420 pi->fds[i] = pi->fds[--pi->fd_cnt];
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700421 GRPC_FD_UNREF(fd, "polling_island");
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700422 break;
423 }
424 }
425}
426
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700427static polling_island *polling_island_create(grpc_fd *initial_fd) {
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700428 polling_island *pi = NULL;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700429
430 /* Try to get one from the polling island freelist */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700431 gpr_mu_lock(&g_pi_freelist_mu);
432 if (g_pi_freelist != NULL) {
433 pi = g_pi_freelist;
434 g_pi_freelist = g_pi_freelist->next_free;
435 pi->next_free = NULL;
436 }
437 gpr_mu_unlock(&g_pi_freelist_mu);
438
439 /* Create new polling island if we could not get one from the free list */
440 if (pi == NULL) {
441 pi = gpr_malloc(sizeof(*pi));
442 gpr_mu_init(&pi->mu);
443 pi->fd_cnt = 0;
444 pi->fd_capacity = 0;
445 pi->fds = NULL;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700446 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700447
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700448 gpr_atm_no_barrier_store(&pi->ref_count, 0);
449 gpr_atm_no_barrier_store(&pi->merged_to, NULL);
450
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700451 pi->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700452
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700453 if (pi->epoll_fd < 0) {
454 gpr_log(GPR_ERROR, "epoll_create1() failed with error: %s",
455 strerror(errno));
456 }
457 GPR_ASSERT(pi->epoll_fd >= 0);
458
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700459 polling_island_add_wakeup_fd_locked(pi, &grpc_global_wakeup_fd);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700460
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700461 pi->next_free = NULL;
462
463 if (initial_fd != NULL) {
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700464 /* Lock the polling island here just in case we got this structure from the
465 freelist and the polling island lock was not released yet (by the code
466 that adds the polling island to the freelist) */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700467 gpr_mu_lock(&pi->mu);
468 polling_island_add_fds_locked(pi, &initial_fd, 1, true);
469 gpr_mu_unlock(&pi->mu);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700470 }
471
472 return pi;
473}
474
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700475static void polling_island_delete(polling_island *pi) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700476 GPR_ASSERT(pi->fd_cnt == 0);
477
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700478 gpr_atm_rel_store(&pi->merged_to, NULL);
479
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700480 close(pi->epoll_fd);
481 pi->epoll_fd = -1;
482
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700483 gpr_mu_lock(&g_pi_freelist_mu);
484 pi->next_free = g_pi_freelist;
485 g_pi_freelist = pi;
486 gpr_mu_unlock(&g_pi_freelist_mu);
487}
488
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700489/* Gets the lock on the *latest* polling island i.e the last polling island in
490 the linked list (linked by 'merged_to' link). Call gpr_mu_unlock on the
491 returned polling island's mu.
492 Usage: To lock/unlock polling island "pi", do the following:
493 polling_island *pi_latest = polling_island_lock(pi);
494 ...
495 ... critical section ..
496 ...
497 gpr_mu_unlock(&pi_latest->mu); //NOTE: use pi_latest->mu. NOT pi->mu */
498polling_island *polling_island_lock(polling_island *pi) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700499 polling_island *next = NULL;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700500 while (true) {
501 next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
502 if (next == NULL) {
503 /* pi is the last node in the linked list. Get the lock and check again
504 (under the pi->mu lock) that pi is still the last node (because a merge
505 may have happend after the (next == NULL) check above and before
506 getting the pi->mu lock.
507 If pi is the last node, we are done. If not, unlock and continue
508 traversing the list */
509 gpr_mu_lock(&pi->mu);
510 next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
511 if (next == NULL) {
512 break;
513 }
514 gpr_mu_unlock(&pi->mu);
515 }
516
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700517 pi = next;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700518 }
519
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700520 return pi;
521}
522
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700523/* Gets the lock on the *latest* polling islands pointed by *p and *q.
524 This function is needed because calling the following block of code to obtain
525 locks on polling islands (*p and *q) is prone to deadlocks.
526 {
527 polling_island_lock(*p);
528 polling_island_lock(*q);
529 }
530
531 Usage/exmaple:
532 polling_island *p1;
533 polling_island *p2;
534 ..
535 polling_island_lock_pair(&p1, &p2);
536 ..
537 .. Critical section with both p1 and p2 locked
538 ..
539 // Release locks
540 // **IMPORTANT**: Make sure you check p1 == p2 AFTER the function
541 // polling_island_lock_pair() was called and if so, release the lock only
542 // once. Note: Even if p1 != p2 beforec calling polling_island_lock_pair(),
543 // they might be after the function returns:
544 if (p1 == p2) {
545 gpr_mu_unlock(&p1->mu)
546 } else {
547 gpr_mu_unlock(&p1->mu);
548 gpr_mu_unlock(&p2->mu);
549 }
550
551*/
552void polling_island_lock_pair(polling_island **p, polling_island **q) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700553 polling_island *pi_1 = *p;
554 polling_island *pi_2 = *q;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700555 polling_island *next_1 = NULL;
556 polling_island *next_2 = NULL;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700557
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700558 /* The algorithm is simple:
559 - Go to the last polling islands in the linked lists *pi_1 and *pi_2 (and
560 keep updating pi_1 and pi_2)
561 - Then obtain locks on the islands by following a lock order rule of
562 locking polling_island with lower address first
563 Special case: Before obtaining the locks, check if pi_1 and pi_2 are
564 pointing to the same island. If that is the case, we can just call
565 polling_island_lock()
566 - After obtaining both the locks, double check that the polling islands
567 are still the last polling islands in their respective linked lists
568 (this is because there might have been polling island merges before
569 we got the lock)
570 - If the polling islands are the last islands, we are done. If not,
571 release the locks and continue the process from the first step */
572 while (true) {
573 next_1 = (polling_island *)gpr_atm_acq_load(&pi_1->merged_to);
574 while (next_1 != NULL) {
575 pi_1 = next_1;
576 next_1 = (polling_island *)gpr_atm_acq_load(&pi_1->merged_to);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700577 }
578
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700579 next_2 = (polling_island *)gpr_atm_acq_load(&pi_2->merged_to);
580 while (next_2 != NULL) {
581 pi_2 = next_2;
582 next_2 = (polling_island *)gpr_atm_acq_load(&pi_2->merged_to);
583 }
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700584
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700585 if (pi_1 == pi_2) {
586 pi_1 = pi_2 = polling_island_lock(pi_1);
587 break;
588 }
589
590 if (pi_1 < pi_2) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700591 gpr_mu_lock(&pi_1->mu);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700592 gpr_mu_lock(&pi_2->mu);
593 } else {
594 gpr_mu_lock(&pi_2->mu);
595 gpr_mu_lock(&pi_1->mu);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700596 }
597
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700598 next_1 = (polling_island *)gpr_atm_acq_load(&pi_1->merged_to);
599 next_2 = (polling_island *)gpr_atm_acq_load(&pi_2->merged_to);
600 if (next_1 == NULL && next_2 == NULL) {
601 break;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700602 }
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700603
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700604 gpr_mu_unlock(&pi_1->mu);
605 gpr_mu_unlock(&pi_2->mu);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700606 }
607
608 *p = pi_1;
609 *q = pi_2;
610}
611
612polling_island *polling_island_merge(polling_island *p, polling_island *q) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700613 /* Get locks on both the polling islands */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700614 polling_island_lock_pair(&p, &q);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700615
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700616 if (p == q) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700617 /* Nothing needs to be done here */
618 gpr_mu_unlock(&p->mu);
619 return p;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700620 }
621
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700622 /* Make sure that p points to the polling island with fewer fds than q */
623 if (p->fd_cnt > q->fd_cnt) {
624 GPR_SWAP(polling_island *, p, q);
625 }
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700626
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700627 /* "Merge" p with q i.e move all the fds from p (The one with fewer fds) to q
Sree Kuchibhotla0553a432016-06-09 00:42:41 -0700628 Note that the refcounts on the fds being moved will not change here. This
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700629 is why the last parameter in the following two functions is 'false') */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700630 polling_island_add_fds_locked(q, p->fds, p->fd_cnt, false);
631 polling_island_remove_all_fds_locked(p, false);
632
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700633 /* Wakeup all the pollers (if any) on p so that they can pickup this change */
634 polling_island_add_wakeup_fd_locked(p, &polling_island_wakeup_fd);
635
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700636 /* Add the 'merged_to' link from p --> q */
637 gpr_atm_rel_store(&p->merged_to, q);
638 PI_ADD_REF(q, "pi_merge"); /* To account for the new incoming ref from p */
Sree Kuchibhotla58e58962016-06-13 00:52:56 -0700639
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700640 gpr_mu_unlock(&p->mu);
641 gpr_mu_unlock(&q->mu);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700642
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700643 /* Return the merged polling island */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700644 return q;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700645}
646
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700647static void polling_island_global_init() {
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700648 gpr_mu_init(&g_pi_freelist_mu);
649 g_pi_freelist = NULL;
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700650 grpc_wakeup_fd_init(&polling_island_wakeup_fd);
651 grpc_wakeup_fd_wakeup(&polling_island_wakeup_fd);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700652}
653
Sree Kuchibhotlad627c102016-06-06 15:49:32 -0700654static void polling_island_global_shutdown() {
655 polling_island *next;
656 gpr_mu_lock(&g_pi_freelist_mu);
657 gpr_mu_unlock(&g_pi_freelist_mu);
658 while (g_pi_freelist != NULL) {
659 next = g_pi_freelist->next_free;
660 gpr_mu_destroy(&g_pi_freelist->mu);
661 gpr_free(g_pi_freelist->fds);
662 gpr_free(g_pi_freelist);
663 g_pi_freelist = next;
664 }
Sree Kuchibhotlad627c102016-06-06 15:49:32 -0700665 gpr_mu_destroy(&g_pi_freelist_mu);
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700666
667 grpc_wakeup_fd_destroy(&polling_island_wakeup_fd);
Sree Kuchibhotlad627c102016-06-06 15:49:32 -0700668}
669
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700670/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700671 * Fd Definitions
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700672 */
673
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700674/* We need to keep a freelist not because of any concerns of malloc performance
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700675 * but instead so that implementations with multiple threads in (for example)
676 * epoll_wait deal with the race between pollset removal and incoming poll
677 * notifications.
678 *
679 * The problem is that the poller ultimately holds a reference to this
680 * object, so it is very difficult to know when is safe to free it, at least
681 * without some expensive synchronization.
682 *
683 * If we keep the object freelisted, in the worst case losing this race just
684 * becomes a spurious read notification on a reused fd.
685 */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700686
687/* The alarm system needs to be able to wakeup 'some poller' sometimes
688 * (specifically when a new alarm needs to be triggered earlier than the next
689 * alarm 'epoch'). This wakeup_fd gives us something to alert on when such a
690 * case occurs. */
Sree Kuchibhotla9bc3d2d2016-06-06 10:27:56 -0700691
692/* TODO: sreek: Right now, this wakes up all pollers. In future we should make
693 * sure to wake up one polling thread (which can wake up other threads if
694 * needed) */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700695grpc_wakeup_fd grpc_global_wakeup_fd;
696
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700697static grpc_fd *fd_freelist = NULL;
698static gpr_mu fd_freelist_mu;
699
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700700#ifdef GRPC_FD_REF_COUNT_DEBUG
701#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__)
702#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
703static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file,
704 int line) {
705 gpr_log(GPR_DEBUG, "FD %d %p ref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
706 gpr_atm_no_barrier_load(&fd->refst),
707 gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line);
708#else
709#define REF_BY(fd, n, reason) ref_by(fd, n)
710#define UNREF_BY(fd, n, reason) unref_by(fd, n)
711static void ref_by(grpc_fd *fd, int n) {
712#endif
713 GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0);
714}
715
716#ifdef GRPC_FD_REF_COUNT_DEBUG
717static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file,
718 int line) {
719 gpr_atm old;
720 gpr_log(GPR_DEBUG, "FD %d %p unref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
721 gpr_atm_no_barrier_load(&fd->refst),
722 gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line);
723#else
724static void unref_by(grpc_fd *fd, int n) {
725 gpr_atm old;
726#endif
727 old = gpr_atm_full_fetch_add(&fd->refst, -n);
728 if (old == n) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700729 /* Add the fd to the freelist */
730 gpr_mu_lock(&fd_freelist_mu);
731 fd->freelist_next = fd_freelist;
732 fd_freelist = fd;
733 grpc_iomgr_unregister_object(&fd->iomgr_object);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700734
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700735 gpr_mu_unlock(&fd_freelist_mu);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700736 } else {
737 GPR_ASSERT(old > n);
738 }
739}
740
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700741/* Increment refcount by two to avoid changing the orphan bit */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700742#ifdef GRPC_FD_REF_COUNT_DEBUG
743static void fd_ref(grpc_fd *fd, const char *reason, const char *file,
744 int line) {
745 ref_by(fd, 2, reason, file, line);
746}
747
748static void fd_unref(grpc_fd *fd, const char *reason, const char *file,
749 int line) {
750 unref_by(fd, 2, reason, file, line);
751}
752#else
753static void fd_ref(grpc_fd *fd) { ref_by(fd, 2); }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700754static void fd_unref(grpc_fd *fd) { unref_by(fd, 2); }
755#endif
756
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700757static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); }
758
759static void fd_global_shutdown(void) {
760 gpr_mu_lock(&fd_freelist_mu);
761 gpr_mu_unlock(&fd_freelist_mu);
762 while (fd_freelist != NULL) {
763 grpc_fd *fd = fd_freelist;
764 fd_freelist = fd_freelist->freelist_next;
765 gpr_mu_destroy(&fd->mu);
766 gpr_free(fd);
767 }
768 gpr_mu_destroy(&fd_freelist_mu);
769}
770
771static grpc_fd *fd_create(int fd, const char *name) {
772 grpc_fd *new_fd = NULL;
773
774 gpr_mu_lock(&fd_freelist_mu);
775 if (fd_freelist != NULL) {
776 new_fd = fd_freelist;
777 fd_freelist = fd_freelist->freelist_next;
778 }
779 gpr_mu_unlock(&fd_freelist_mu);
780
781 if (new_fd == NULL) {
782 new_fd = gpr_malloc(sizeof(grpc_fd));
783 gpr_mu_init(&new_fd->mu);
784 gpr_mu_init(&new_fd->pi_mu);
785 }
786
787 /* Note: It is not really needed to get the new_fd->mu lock here. If this is a
788 newly created fd (or an fd we got from the freelist), no one else would be
789 holding a lock to it anyway. */
790 gpr_mu_lock(&new_fd->mu);
791
792 gpr_atm_rel_store(&new_fd->refst, 1);
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700793 new_fd->fd = fd;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700794 new_fd->shutdown = false;
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700795 new_fd->orphaned = false;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700796 new_fd->read_closure = CLOSURE_NOT_READY;
797 new_fd->write_closure = CLOSURE_NOT_READY;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700798 new_fd->polling_island = NULL;
799 new_fd->freelist_next = NULL;
800 new_fd->on_done_closure = NULL;
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700801 new_fd->read_notifier_pollset = NULL;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700802
803 gpr_mu_unlock(&new_fd->mu);
804
805 char *fd_name;
806 gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
807 grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name);
808 gpr_free(fd_name);
809#ifdef GRPC_FD_REF_COUNT_DEBUG
810 gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, r, fd_name);
811#endif
812 return new_fd;
813}
814
815static bool fd_is_orphaned(grpc_fd *fd) {
816 return (gpr_atm_acq_load(&fd->refst) & 1) == 0;
817}
818
819static int fd_wrapped_fd(grpc_fd *fd) {
820 int ret_fd = -1;
821 gpr_mu_lock(&fd->mu);
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700822 if (!fd->orphaned) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700823 ret_fd = fd->fd;
824 }
825 gpr_mu_unlock(&fd->mu);
826
827 return ret_fd;
828}
829
830static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
831 grpc_closure *on_done, int *release_fd,
832 const char *reason) {
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700833 bool is_fd_closed = false;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700834 gpr_mu_lock(&fd->mu);
835 fd->on_done_closure = on_done;
836
837 /* If release_fd is not NULL, we should be relinquishing control of the file
838 descriptor fd->fd (but we still own the grpc_fd structure). */
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700839 if (release_fd != NULL) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700840 *release_fd = fd->fd;
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700841 } else {
842 close(fd->fd);
843 is_fd_closed = true;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700844 }
845
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700846 fd->orphaned = true;
847
848 /* Remove the active status but keep referenced. We want this grpc_fd struct
849 to be alive (and not added to freelist) until the end of this function */
850 REF_BY(fd, 1, reason);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700851
852 /* Remove the fd from the polling island:
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700853 - Get a lock on the latest polling island (i.e the last island in the
854 linked list pointed by fd->polling_island). This is the island that
855 would actually contain the fd
856 - Remove the fd from the latest polling island
857 - Unlock the latest polling island
858 - Set fd->polling_island to NULL (but remove the ref on the polling island
859 before doing this.) */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700860 gpr_mu_lock(&fd->pi_mu);
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -0700861 if (fd->polling_island != NULL) {
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700862 polling_island *pi_latest = polling_island_lock(fd->polling_island);
863 polling_island_remove_fd_locked(pi_latest, fd, is_fd_closed);
864 gpr_mu_unlock(&pi_latest->mu);
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700865
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700866 PI_UNREF(fd->polling_island, "fd_orphan");
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -0700867 fd->polling_island = NULL;
868 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700869 gpr_mu_unlock(&fd->pi_mu);
870
871 grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, true, NULL);
872
873 gpr_mu_unlock(&fd->mu);
874 UNREF_BY(fd, 2, reason); /* Drop the reference */
875}
876
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700877static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
878 grpc_closure **st, grpc_closure *closure) {
879 if (*st == CLOSURE_NOT_READY) {
880 /* not ready ==> switch to a waiting state by setting the closure */
881 *st = closure;
882 } else if (*st == CLOSURE_READY) {
883 /* already ready ==> queue the closure to run immediately */
884 *st = CLOSURE_NOT_READY;
885 grpc_exec_ctx_enqueue(exec_ctx, closure, !fd->shutdown, NULL);
886 } else {
887 /* upcallptr was set to a different closure. This is an error! */
888 gpr_log(GPR_ERROR,
889 "User called a notify_on function with a previous callback still "
890 "pending");
891 abort();
892 }
893}
894
895/* returns 1 if state becomes not ready */
896static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
897 grpc_closure **st) {
898 if (*st == CLOSURE_READY) {
899 /* duplicate ready ==> ignore */
900 return 0;
901 } else if (*st == CLOSURE_NOT_READY) {
902 /* not ready, and not waiting ==> flag ready */
903 *st = CLOSURE_READY;
904 return 0;
905 } else {
906 /* waiting ==> queue closure */
907 grpc_exec_ctx_enqueue(exec_ctx, *st, !fd->shutdown, NULL);
908 *st = CLOSURE_NOT_READY;
909 return 1;
910 }
911}
912
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700913static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
914 grpc_fd *fd) {
915 grpc_pollset *notifier = NULL;
916
917 gpr_mu_lock(&fd->mu);
918 notifier = fd->read_notifier_pollset;
919 gpr_mu_unlock(&fd->mu);
920
921 return notifier;
922}
923
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700924static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
925 gpr_mu_lock(&fd->mu);
926 GPR_ASSERT(!fd->shutdown);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700927 fd->shutdown = true;
928
929 /* Flush any pending read and write closures. Since fd->shutdown is 'true' at
930 this point, the closures would be called with 'success = false' */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700931 set_ready_locked(exec_ctx, fd, &fd->read_closure);
932 set_ready_locked(exec_ctx, fd, &fd->write_closure);
933 gpr_mu_unlock(&fd->mu);
934}
935
936static void fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
937 grpc_closure *closure) {
938 gpr_mu_lock(&fd->mu);
939 notify_on_locked(exec_ctx, fd, &fd->read_closure, closure);
940 gpr_mu_unlock(&fd->mu);
941}
942
943static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
944 grpc_closure *closure) {
945 gpr_mu_lock(&fd->mu);
946 notify_on_locked(exec_ctx, fd, &fd->write_closure, closure);
947 gpr_mu_unlock(&fd->mu);
948}
949
950/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700951 * Pollset Definitions
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700952 */
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -0700953GPR_TLS_DECL(g_current_thread_pollset);
954GPR_TLS_DECL(g_current_thread_worker);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700955
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700956static void sig_handler(int sig_num) {
Sree Kuchibhotlad627c102016-06-06 15:49:32 -0700957#ifdef GRPC_EPOLL_DEBUG
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700958 gpr_log(GPR_INFO, "Received signal %d", sig_num);
Sree Kuchibhotla9bc3d2d2016-06-06 10:27:56 -0700959#endif
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700960}
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700961
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -0700962static void poller_kick_init() { signal(grpc_wakeup_signal, sig_handler); }
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700963
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700964/* Global state management */
965static void pollset_global_init(void) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700966 grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -0700967 gpr_tls_init(&g_current_thread_pollset);
968 gpr_tls_init(&g_current_thread_worker);
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700969 poller_kick_init();
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700970}
971
972static void pollset_global_shutdown(void) {
973 grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -0700974 gpr_tls_destroy(&g_current_thread_pollset);
975 gpr_tls_destroy(&g_current_thread_worker);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700976}
977
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700978static void pollset_worker_kick(grpc_pollset_worker *worker) {
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -0700979 pthread_kill(worker->pt_id, grpc_wakeup_signal);
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700980}
981
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700982/* Return 1 if the pollset has active threads in pollset_work (pollset must
983 * be locked) */
984static int pollset_has_workers(grpc_pollset *p) {
985 return p->root_worker.next != &p->root_worker;
986}
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700987
988static void remove_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
989 worker->prev->next = worker->next;
990 worker->next->prev = worker->prev;
991}
992
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700993static grpc_pollset_worker *pop_front_worker(grpc_pollset *p) {
994 if (pollset_has_workers(p)) {
995 grpc_pollset_worker *w = p->root_worker.next;
996 remove_worker(p, w);
997 return w;
998 } else {
999 return NULL;
1000 }
1001}
1002
1003static void push_back_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
1004 worker->next = &p->root_worker;
1005 worker->prev = worker->next->prev;
1006 worker->prev->next = worker->next->prev = worker;
1007}
1008
1009static void push_front_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
1010 worker->prev = &p->root_worker;
1011 worker->next = worker->prev->next;
1012 worker->prev->next = worker->next->prev = worker;
1013}
1014
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001015/* p->mu must be held before calling this function */
1016static void pollset_kick(grpc_pollset *p,
1017 grpc_pollset_worker *specific_worker) {
1018 GPR_TIMER_BEGIN("pollset_kick", 0);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001019
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001020 grpc_pollset_worker *worker = specific_worker;
1021 if (worker != NULL) {
1022 if (worker == GRPC_POLLSET_KICK_BROADCAST) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001023 if (pollset_has_workers(p)) {
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001024 GPR_TIMER_BEGIN("pollset_kick.broadcast", 0);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001025 for (worker = p->root_worker.next; worker != &p->root_worker;
1026 worker = worker->next) {
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001027 if (gpr_tls_get(&g_current_thread_worker) != (intptr_t)worker) {
1028 pollset_worker_kick(worker);
1029 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001030 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001031 } else {
1032 p->kicked_without_pollers = true;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001033 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001034 GPR_TIMER_END("pollset_kick.broadcast", 0);
1035 } else {
1036 GPR_TIMER_MARK("kicked_specifically", 0);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001037 if (gpr_tls_get(&g_current_thread_worker) != (intptr_t)worker) {
1038 pollset_worker_kick(worker);
1039 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001040 }
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001041 } else if (gpr_tls_get(&g_current_thread_pollset) != (intptr_t)p) {
1042 /* Since worker == NULL, it means that we can kick "any" worker on this
1043 pollset 'p'. If 'p' happens to be the same pollset this thread is
1044 currently polling (i.e in pollset_work() function), then there is no need
1045 to kick any other worker since the current thread can just absorb the
1046 kick. This is the reason why we enter this case only when
1047 g_current_thread_pollset is != p */
1048
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001049 GPR_TIMER_MARK("kick_anonymous", 0);
1050 worker = pop_front_worker(p);
1051 if (worker != NULL) {
1052 GPR_TIMER_MARK("finally_kick", 0);
1053 push_back_worker(p, worker);
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001054 pollset_worker_kick(worker);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001055 } else {
1056 GPR_TIMER_MARK("kicked_no_pollers", 0);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001057 p->kicked_without_pollers = true;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001058 }
1059 }
1060
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001061 GPR_TIMER_END("pollset_kick", 0);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001062}
1063
1064static void kick_poller(void) { grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd); }
1065
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001066static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
1067 gpr_mu_init(&pollset->mu);
1068 *mu = &pollset->mu;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001069
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001070 pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001071 pollset->kicked_without_pollers = false;
1072
1073 pollset->shutting_down = false;
1074 pollset->finish_shutdown_called = false;
1075 pollset->shutdown_done = NULL;
1076
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001077 gpr_mu_init(&pollset->pi_mu);
1078 pollset->polling_island = NULL;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001079}
1080
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001081/* Convert a timespec to milliseconds:
1082 - Very small or negative poll times are clamped to zero to do a non-blocking
1083 poll (which becomes spin polling)
1084 - Other small values are rounded up to one millisecond
1085 - Longer than a millisecond polls are rounded up to the next nearest
1086 millisecond to avoid spinning
1087 - Infinite timeouts are converted to -1 */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001088static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
1089 gpr_timespec now) {
1090 gpr_timespec timeout;
1091 static const int64_t max_spin_polling_us = 10;
1092 if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) == 0) {
1093 return -1;
1094 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001095
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001096 if (gpr_time_cmp(deadline, gpr_time_add(now, gpr_time_from_micros(
1097 max_spin_polling_us,
1098 GPR_TIMESPAN))) <= 0) {
1099 return 0;
1100 }
1101 timeout = gpr_time_sub(deadline, now);
1102 return gpr_time_to_millis(gpr_time_add(
1103 timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN)));
1104}
1105
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001106static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1107 grpc_pollset *notifier) {
1108 /* Need the fd->mu since we might be racing with fd_notify_on_read */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001109 gpr_mu_lock(&fd->mu);
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001110 set_ready_locked(exec_ctx, fd, &fd->read_closure);
1111 fd->read_notifier_pollset = notifier;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001112 gpr_mu_unlock(&fd->mu);
1113}
1114
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001115static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001116 /* Need the fd->mu since we might be racing with fd_notify_on_write */
1117 gpr_mu_lock(&fd->mu);
1118 set_ready_locked(exec_ctx, fd, &fd->write_closure);
1119 gpr_mu_unlock(&fd->mu);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001120}
1121
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001122static void pollset_release_polling_island(grpc_pollset *ps, char *reason) {
1123 gpr_mu_lock(&ps->pi_mu);
1124 if (ps->polling_island != NULL) {
1125 PI_UNREF(ps->polling_island, reason);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001126 }
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001127 ps->polling_island = NULL;
1128 gpr_mu_unlock(&ps->pi_mu);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001129}
1130
1131static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
1132 grpc_pollset *pollset) {
1133 /* The pollset cannot have any workers if we are at this stage */
1134 GPR_ASSERT(!pollset_has_workers(pollset));
1135
1136 pollset->finish_shutdown_called = true;
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001137
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001138 /* Release the ref and set pollset->polling_island to NULL */
1139 pollset_release_polling_island(pollset, "ps_shutdown");
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001140 grpc_exec_ctx_enqueue(exec_ctx, pollset->shutdown_done, true, NULL);
1141}
1142
1143/* pollset->mu lock must be held by the caller before calling this */
1144static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1145 grpc_closure *closure) {
1146 GPR_TIMER_BEGIN("pollset_shutdown", 0);
1147 GPR_ASSERT(!pollset->shutting_down);
1148 pollset->shutting_down = true;
1149 pollset->shutdown_done = closure;
1150 pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST);
1151
1152 /* If the pollset has any workers, we cannot call finish_shutdown_locked()
1153 because it would release the underlying polling island. In such a case, we
1154 let the last worker call finish_shutdown_locked() from pollset_work() */
1155 if (!pollset_has_workers(pollset)) {
1156 GPR_ASSERT(!pollset->finish_shutdown_called);
1157 GPR_TIMER_MARK("pollset_shutdown.finish_shutdown_locked", 0);
1158 finish_shutdown_locked(exec_ctx, pollset);
1159 }
1160 GPR_TIMER_END("pollset_shutdown", 0);
1161}
1162
1163/* pollset_shutdown is guaranteed to be called before pollset_destroy. So other
1164 * than destroying the mutexes, there is nothing special that needs to be done
1165 * here */
1166static void pollset_destroy(grpc_pollset *pollset) {
1167 GPR_ASSERT(!pollset_has_workers(pollset));
1168 gpr_mu_destroy(&pollset->pi_mu);
1169 gpr_mu_destroy(&pollset->mu);
1170}
1171
1172static void pollset_reset(grpc_pollset *pollset) {
1173 GPR_ASSERT(pollset->shutting_down);
1174 GPR_ASSERT(!pollset_has_workers(pollset));
1175 pollset->shutting_down = false;
1176 pollset->finish_shutdown_called = false;
1177 pollset->kicked_without_pollers = false;
1178 pollset->shutdown_done = NULL;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001179 pollset_release_polling_island(pollset, "ps_reset");
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001180}
1181
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001182#define GRPC_EPOLL_MAX_EVENTS 1000
1183static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
1184 grpc_pollset *pollset, int timeout_ms,
1185 sigset_t *sig_mask) {
1186 struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS];
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -07001187 int epoll_fd = -1;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001188 int ep_rv;
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001189 polling_island *pi = NULL;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001190 GPR_TIMER_BEGIN("pollset_work_and_unlock", 0);
1191
1192 /* We need to get the epoll_fd to wait on. The epoll_fd is in inside the
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001193 latest polling island pointed by pollset->polling_island.
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001194 Acquire the following locks:
1195 - pollset->mu (which we already have)
1196 - pollset->pi_mu
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001197 - pollset->polling_island lock */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001198 gpr_mu_lock(&pollset->pi_mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001199
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001200 if (pollset->polling_island == NULL) {
1201 pollset->polling_island = polling_island_create(NULL);
1202 PI_ADD_REF(pollset->polling_island, "ps");
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -07001203 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001204
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001205 pi = polling_island_lock(pollset->polling_island);
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001206 epoll_fd = pi->epoll_fd;
1207
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001208 /* Update the pollset->polling_island since the island being pointed by
1209 pollset->polling_island may not be the latest (i.e pi) */
1210 if (pollset->polling_island != pi) {
1211 /* Always do PI_ADD_REF before PI_UNREF because PI_UNREF may cause the
1212 polling island to be deleted */
1213 PI_ADD_REF(pi, "ps");
1214 PI_UNREF(pollset->polling_island, "ps");
1215 pollset->polling_island = pi;
1216 }
Sree Kuchibhotlad627c102016-06-06 15:49:32 -07001217
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001218 /* Add an extra ref so that the island does not get destroyed (which means
1219 the epoll_fd won't be closed) while we are are doing an epoll_wait() on the
1220 epoll_fd */
1221 PI_ADD_REF(pi, "ps_work");
1222
1223 gpr_mu_unlock(&pi->mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001224 gpr_mu_unlock(&pollset->pi_mu);
1225 gpr_mu_unlock(&pollset->mu);
1226
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001227 do {
1228 ep_rv = epoll_pwait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, timeout_ms,
1229 sig_mask);
1230 if (ep_rv < 0) {
1231 if (errno != EINTR) {
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001232 gpr_log(GPR_ERROR, "epoll_pwait() failed: %s", strerror(errno));
1233 } else {
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001234 /* We were interrupted. Save an interation by doing a zero timeout
1235 epoll_wait to see if there are any other events of interest */
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001236 ep_rv = epoll_wait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0);
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001237 }
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001238 }
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001239
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -07001240#ifdef GRPC_TSAN
Sree Kuchibhotla41622a82016-06-13 16:43:14 -07001241 /* See the definition of g_poll_sync for more details */
1242 gpr_atm_acq_load(&g_epoll_sync);
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -07001243#endif /* defined(GRPC_TSAN) */
Sree Kuchibhotla41622a82016-06-13 16:43:14 -07001244
Sree Kuchibhotla58e58962016-06-13 00:52:56 -07001245 for (int i = 0; i < ep_rv; ++i) {
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001246 void *data_ptr = ep_ev[i].data.ptr;
1247 if (data_ptr == &grpc_global_wakeup_fd) {
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001248 grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd);
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001249 } else if (data_ptr == &polling_island_wakeup_fd) {
1250 /* This means that our polling island is merged with a different
1251 island. We do not have to do anything here since the subsequent call
1252 to the function pollset_work_and_unlock() will pick up the correct
1253 epoll_fd */
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001254 } else {
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001255 grpc_fd *fd = data_ptr;
1256 int cancel = ep_ev[i].events & (EPOLLERR | EPOLLHUP);
1257 int read_ev = ep_ev[i].events & (EPOLLIN | EPOLLPRI);
1258 int write_ev = ep_ev[i].events & EPOLLOUT;
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001259 if (read_ev || cancel) {
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001260 fd_become_readable(exec_ctx, fd, pollset);
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001261 }
1262 if (write_ev || cancel) {
1263 fd_become_writable(exec_ctx, fd);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001264 }
1265 }
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001266 }
1267 } while (ep_rv == GRPC_EPOLL_MAX_EVENTS);
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001268
1269 GPR_ASSERT(pi != NULL);
1270
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001271 /* Before leaving, release the extra ref we added to the polling island. It
1272 is important to use "pi" here (i.e our old copy of pollset->polling_island
1273 that we got before releasing the polling island lock). This is because
1274 pollset->polling_island pointer might get udpated in other parts of the
1275 code when there is an island merge while we are doing epoll_wait() above */
1276 PI_UNREF(pi, "ps_work");
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001277
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001278 GPR_TIMER_END("pollset_work_and_unlock", 0);
1279}
1280
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001281/* pollset->mu lock must be held by the caller before calling this.
1282 The function pollset_work() may temporarily release the lock (pollset->mu)
1283 during the course of its execution but it will always re-acquire the lock and
1284 ensure that it is held by the time the function returns */
1285static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1286 grpc_pollset_worker **worker_hdl, gpr_timespec now,
1287 gpr_timespec deadline) {
1288 GPR_TIMER_BEGIN("pollset_work", 0);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001289 int timeout_ms = poll_deadline_to_millis_timeout(deadline, now);
1290
1291 sigset_t new_mask;
1292 sigset_t orig_mask;
1293
1294 grpc_pollset_worker worker;
1295 worker.next = worker.prev = NULL;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001296 worker.pt_id = pthread_self();
1297
1298 *worker_hdl = &worker;
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001299 gpr_tls_set(&g_current_thread_pollset, (intptr_t)pollset);
1300 gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001301
1302 if (pollset->kicked_without_pollers) {
1303 /* If the pollset was kicked without pollers, pretend that the current
1304 worker got the kick and skip polling. A kick indicates that there is some
1305 work that needs attention like an event on the completion queue or an
1306 alarm */
1307 GPR_TIMER_MARK("pollset_work.kicked_without_pollers", 0);
1308 pollset->kicked_without_pollers = 0;
1309 } else if (!pollset->shutting_down) {
1310 sigemptyset(&new_mask);
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07001311 sigaddset(&new_mask, grpc_wakeup_signal);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001312 pthread_sigmask(SIG_BLOCK, &new_mask, &orig_mask);
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07001313 sigdelset(&orig_mask, grpc_wakeup_signal);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001314
1315 push_front_worker(pollset, &worker);
1316
1317 pollset_work_and_unlock(exec_ctx, pollset, timeout_ms, &orig_mask);
1318 grpc_exec_ctx_flush(exec_ctx);
1319
1320 gpr_mu_lock(&pollset->mu);
1321 remove_worker(pollset, &worker);
1322 }
1323
1324 /* If we are the last worker on the pollset (i.e pollset_has_workers() is
1325 false at this point) and the pollset is shutting down, we may have to
1326 finish the shutdown process by calling finish_shutdown_locked().
1327 See pollset_shutdown() for more details.
1328
1329 Note: Continuing to access pollset here is safe; it is the caller's
1330 responsibility to not destroy a pollset when it has outstanding calls to
1331 pollset_work() */
1332 if (pollset->shutting_down && !pollset_has_workers(pollset) &&
1333 !pollset->finish_shutdown_called) {
1334 GPR_TIMER_MARK("pollset_work.finish_shutdown_locked", 0);
1335 finish_shutdown_locked(exec_ctx, pollset);
1336
1337 gpr_mu_unlock(&pollset->mu);
1338 grpc_exec_ctx_flush(exec_ctx);
1339 gpr_mu_lock(&pollset->mu);
1340 }
1341
1342 *worker_hdl = NULL;
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001343 gpr_tls_set(&g_current_thread_pollset, (intptr_t)0);
1344 gpr_tls_set(&g_current_thread_worker, (intptr_t)0);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001345 GPR_TIMER_END("pollset_work", 0);
1346}
1347
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001348static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1349 grpc_fd *fd) {
Sree Kuchibhotla9bc3d2d2016-06-06 10:27:56 -07001350 /* TODO sreek - Double check if we need to get a pollset->mu lock here */
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001351 gpr_mu_lock(&pollset->pi_mu);
1352 gpr_mu_lock(&fd->pi_mu);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001353
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001354 polling_island *pi_new = NULL;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001355
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001356 /* 1) If fd->polling_island and pollset->polling_island are both non-NULL and
1357 * equal, do nothing.
1358 * 2) If fd->polling_island and pollset->polling_island are both NULL, create
1359 * a new polling island (with a refcount of 2) and make the polling_island
1360 * fields in both fd and pollset to point to the new island
1361 * 3) If one of fd->polling_island or pollset->polling_island is NULL, update
1362 * the NULL polling_island field to point to the non-NULL polling_island
1363 * field (ensure that the refcount on the polling island is incremented by
1364 * 1 to account for the newly added reference)
1365 * 4) Finally, if fd->polling_island and pollset->polling_island are non-NULL
1366 * and different, merge both the polling islands and update the
1367 * polling_island fields in both fd and pollset to point to the merged
1368 * polling island.
1369 */
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001370 if (fd->polling_island == pollset->polling_island) {
1371 pi_new = fd->polling_island;
1372 if (pi_new == NULL) {
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001373 pi_new = polling_island_create(fd);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001374 }
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001375 } else if (fd->polling_island == NULL) {
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001376 pi_new = polling_island_lock(pollset->polling_island);
1377 polling_island_add_fds_locked(pi_new, &fd, 1, true);
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -07001378 gpr_mu_unlock(&pi_new->mu);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001379 } else if (pollset->polling_island == NULL) {
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001380 pi_new = polling_island_lock(fd->polling_island);
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -07001381 gpr_mu_unlock(&pi_new->mu);
Sree Kuchibhotla5098f912016-05-31 10:58:17 -07001382 } else {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001383 pi_new = polling_island_merge(fd->polling_island, pollset->polling_island);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001384 }
1385
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001386 if (fd->polling_island != pi_new) {
1387 PI_ADD_REF(pi_new, "fd");
1388 if (fd->polling_island != NULL) {
1389 PI_UNREF(fd->polling_island, "fd");
1390 }
1391 fd->polling_island = pi_new;
1392 }
1393
1394 if (pollset->polling_island != pi_new) {
1395 PI_ADD_REF(pi_new, "ps");
1396 if (pollset->polling_island != NULL) {
1397 PI_UNREF(pollset->polling_island, "ps");
1398 }
1399 pollset->polling_island = pi_new;
1400 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001401
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001402 gpr_mu_unlock(&fd->pi_mu);
1403 gpr_mu_unlock(&pollset->pi_mu);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001404}
1405
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001406/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001407 * Pollset-set Definitions
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001408 */
1409
1410static grpc_pollset_set *pollset_set_create(void) {
1411 grpc_pollset_set *pollset_set = gpr_malloc(sizeof(*pollset_set));
1412 memset(pollset_set, 0, sizeof(*pollset_set));
1413 gpr_mu_init(&pollset_set->mu);
1414 return pollset_set;
1415}
1416
1417static void pollset_set_destroy(grpc_pollset_set *pollset_set) {
1418 size_t i;
1419 gpr_mu_destroy(&pollset_set->mu);
1420 for (i = 0; i < pollset_set->fd_count; i++) {
1421 GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set");
1422 }
1423 gpr_free(pollset_set->pollsets);
1424 gpr_free(pollset_set->pollset_sets);
1425 gpr_free(pollset_set->fds);
1426 gpr_free(pollset_set);
1427}
1428
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001429static void pollset_set_add_fd(grpc_exec_ctx *exec_ctx,
1430 grpc_pollset_set *pollset_set, grpc_fd *fd) {
1431 size_t i;
1432 gpr_mu_lock(&pollset_set->mu);
1433 if (pollset_set->fd_count == pollset_set->fd_capacity) {
1434 pollset_set->fd_capacity = GPR_MAX(8, 2 * pollset_set->fd_capacity);
1435 pollset_set->fds = gpr_realloc(
1436 pollset_set->fds, pollset_set->fd_capacity * sizeof(*pollset_set->fds));
1437 }
1438 GRPC_FD_REF(fd, "pollset_set");
1439 pollset_set->fds[pollset_set->fd_count++] = fd;
1440 for (i = 0; i < pollset_set->pollset_count; i++) {
1441 pollset_add_fd(exec_ctx, pollset_set->pollsets[i], fd);
1442 }
1443 for (i = 0; i < pollset_set->pollset_set_count; i++) {
1444 pollset_set_add_fd(exec_ctx, pollset_set->pollset_sets[i], fd);
1445 }
1446 gpr_mu_unlock(&pollset_set->mu);
1447}
1448
1449static void pollset_set_del_fd(grpc_exec_ctx *exec_ctx,
1450 grpc_pollset_set *pollset_set, grpc_fd *fd) {
1451 size_t i;
1452 gpr_mu_lock(&pollset_set->mu);
1453 for (i = 0; i < pollset_set->fd_count; i++) {
1454 if (pollset_set->fds[i] == fd) {
1455 pollset_set->fd_count--;
1456 GPR_SWAP(grpc_fd *, pollset_set->fds[i],
1457 pollset_set->fds[pollset_set->fd_count]);
1458 GRPC_FD_UNREF(fd, "pollset_set");
1459 break;
1460 }
1461 }
1462 for (i = 0; i < pollset_set->pollset_set_count; i++) {
1463 pollset_set_del_fd(exec_ctx, pollset_set->pollset_sets[i], fd);
1464 }
1465 gpr_mu_unlock(&pollset_set->mu);
1466}
1467
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001468static void pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
1469 grpc_pollset_set *pollset_set,
1470 grpc_pollset *pollset) {
1471 size_t i, j;
1472 gpr_mu_lock(&pollset_set->mu);
1473 if (pollset_set->pollset_count == pollset_set->pollset_capacity) {
1474 pollset_set->pollset_capacity =
1475 GPR_MAX(8, 2 * pollset_set->pollset_capacity);
1476 pollset_set->pollsets =
1477 gpr_realloc(pollset_set->pollsets, pollset_set->pollset_capacity *
1478 sizeof(*pollset_set->pollsets));
1479 }
1480 pollset_set->pollsets[pollset_set->pollset_count++] = pollset;
1481 for (i = 0, j = 0; i < pollset_set->fd_count; i++) {
1482 if (fd_is_orphaned(pollset_set->fds[i])) {
1483 GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set");
1484 } else {
1485 pollset_add_fd(exec_ctx, pollset, pollset_set->fds[i]);
1486 pollset_set->fds[j++] = pollset_set->fds[i];
1487 }
1488 }
1489 pollset_set->fd_count = j;
1490 gpr_mu_unlock(&pollset_set->mu);
1491}
1492
1493static void pollset_set_del_pollset(grpc_exec_ctx *exec_ctx,
1494 grpc_pollset_set *pollset_set,
1495 grpc_pollset *pollset) {
1496 size_t i;
1497 gpr_mu_lock(&pollset_set->mu);
1498 for (i = 0; i < pollset_set->pollset_count; i++) {
1499 if (pollset_set->pollsets[i] == pollset) {
1500 pollset_set->pollset_count--;
1501 GPR_SWAP(grpc_pollset *, pollset_set->pollsets[i],
1502 pollset_set->pollsets[pollset_set->pollset_count]);
1503 break;
1504 }
1505 }
1506 gpr_mu_unlock(&pollset_set->mu);
1507}
1508
1509static void pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx,
1510 grpc_pollset_set *bag,
1511 grpc_pollset_set *item) {
1512 size_t i, j;
1513 gpr_mu_lock(&bag->mu);
1514 if (bag->pollset_set_count == bag->pollset_set_capacity) {
1515 bag->pollset_set_capacity = GPR_MAX(8, 2 * bag->pollset_set_capacity);
1516 bag->pollset_sets =
1517 gpr_realloc(bag->pollset_sets,
1518 bag->pollset_set_capacity * sizeof(*bag->pollset_sets));
1519 }
1520 bag->pollset_sets[bag->pollset_set_count++] = item;
1521 for (i = 0, j = 0; i < bag->fd_count; i++) {
1522 if (fd_is_orphaned(bag->fds[i])) {
1523 GRPC_FD_UNREF(bag->fds[i], "pollset_set");
1524 } else {
1525 pollset_set_add_fd(exec_ctx, item, bag->fds[i]);
1526 bag->fds[j++] = bag->fds[i];
1527 }
1528 }
1529 bag->fd_count = j;
1530 gpr_mu_unlock(&bag->mu);
1531}
1532
1533static void pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx,
1534 grpc_pollset_set *bag,
1535 grpc_pollset_set *item) {
1536 size_t i;
1537 gpr_mu_lock(&bag->mu);
1538 for (i = 0; i < bag->pollset_set_count; i++) {
1539 if (bag->pollset_sets[i] == item) {
1540 bag->pollset_set_count--;
1541 GPR_SWAP(grpc_pollset_set *, bag->pollset_sets[i],
1542 bag->pollset_sets[bag->pollset_set_count]);
1543 break;
1544 }
1545 }
1546 gpr_mu_unlock(&bag->mu);
1547}
1548
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -07001549/* Test helper functions
1550 * */
1551void *grpc_fd_get_polling_island(grpc_fd *fd) {
1552 polling_island *pi;
1553
1554 gpr_mu_lock(&fd->pi_mu);
1555 pi = fd->polling_island;
1556 gpr_mu_unlock(&fd->pi_mu);
1557
1558 return pi;
1559}
1560
1561void *grpc_pollset_get_polling_island(grpc_pollset *ps) {
1562 polling_island *pi;
1563
1564 gpr_mu_lock(&ps->pi_mu);
1565 pi = ps->polling_island;
1566 gpr_mu_unlock(&ps->pi_mu);
1567
1568 return pi;
1569}
1570
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -07001571bool grpc_are_polling_islands_equal(void *p, void *q) {
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001572 polling_island *p1 = p;
1573 polling_island *p2 = q;
1574
1575 polling_island_lock_pair(&p1, &p2);
1576 if (p1 == p2) {
1577 gpr_mu_unlock(&p1->mu);
1578 } else {
1579 gpr_mu_unlock(&p1->mu);
1580 gpr_mu_unlock(&p2->mu);
1581 }
1582
1583 return p1 == p2;
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -07001584}
1585
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001586/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001587 * Event engine binding
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001588 */
1589
1590static void shutdown_engine(void) {
1591 fd_global_shutdown();
1592 pollset_global_shutdown();
Sree Kuchibhotlad627c102016-06-06 15:49:32 -07001593 polling_island_global_shutdown();
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001594}
1595
1596static const grpc_event_engine_vtable vtable = {
1597 .pollset_size = sizeof(grpc_pollset),
1598
1599 .fd_create = fd_create,
1600 .fd_wrapped_fd = fd_wrapped_fd,
1601 .fd_orphan = fd_orphan,
1602 .fd_shutdown = fd_shutdown,
1603 .fd_notify_on_read = fd_notify_on_read,
1604 .fd_notify_on_write = fd_notify_on_write,
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001605 .fd_get_read_notifier_pollset = fd_get_read_notifier_pollset,
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001606
1607 .pollset_init = pollset_init,
1608 .pollset_shutdown = pollset_shutdown,
1609 .pollset_reset = pollset_reset,
1610 .pollset_destroy = pollset_destroy,
1611 .pollset_work = pollset_work,
1612 .pollset_kick = pollset_kick,
1613 .pollset_add_fd = pollset_add_fd,
1614
1615 .pollset_set_create = pollset_set_create,
1616 .pollset_set_destroy = pollset_set_destroy,
1617 .pollset_set_add_pollset = pollset_set_add_pollset,
1618 .pollset_set_del_pollset = pollset_set_del_pollset,
1619 .pollset_set_add_pollset_set = pollset_set_add_pollset_set,
1620 .pollset_set_del_pollset_set = pollset_set_del_pollset_set,
1621 .pollset_set_add_fd = pollset_set_add_fd,
1622 .pollset_set_del_fd = pollset_set_del_fd,
1623
1624 .kick_poller = kick_poller,
1625
1626 .shutdown_engine = shutdown_engine,
1627};
1628
Sree Kuchibhotla72744022016-06-09 09:42:06 -07001629/* It is possible that GLIBC has epoll but the underlying kernel doesn't.
1630 * Create a dummy epoll_fd to make sure epoll support is available */
1631static bool is_epoll_available() {
1632 int fd = epoll_create1(EPOLL_CLOEXEC);
1633 if (fd < 0) {
1634 gpr_log(
1635 GPR_ERROR,
1636 "epoll_create1 failed with error: %d. Not using epoll polling engine",
1637 fd);
1638 return false;
1639 }
1640 close(fd);
1641 return true;
1642}
1643
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001644const grpc_event_engine_vtable *grpc_init_epoll_linux(void) {
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07001645 /* If use of signals is disabled, we cannot use epoll engine*/
1646 if (is_grpc_wakeup_signal_initialized && grpc_wakeup_signal < 0) {
1647 return NULL;
1648 }
1649
Sree Kuchibhotla72744022016-06-09 09:42:06 -07001650 if (!is_epoll_available()) {
1651 return NULL;
1652 }
1653
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07001654 if (!is_grpc_wakeup_signal_initialized) {
1655 grpc_use_signal(SIGRTMIN + 2);
1656 }
1657
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001658 fd_global_init();
1659 pollset_global_init();
1660 polling_island_global_init();
1661 return &vtable;
1662}
1663
Sree Kuchibhotla41622a82016-06-13 16:43:14 -07001664#else /* defined(GPR_LINUX_EPOLL) */
1665#if defined(GPR_POSIX_SOCKET)
1666#include "src/core/lib/iomgr/ev_posix.h"
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001667/* If GPR_LINUX_EPOLL is not defined, it means epoll is not available. Return
1668 * NULL */
1669const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { return NULL; }
Sree Kuchibhotla41622a82016-06-13 16:43:14 -07001670#endif /* defined(GPR_POSIX_SOCKET) */
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001671
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07001672void grpc_use_signal(int signum) {}
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001673#endif /* !defined(GPR_LINUX_EPOLL) */