blob: c60ff85898f6de15359a6753c8a055f4c84fd9c9 [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
murgatroid9954070892016-08-08 17:01:18 -070034#include "src/core/lib/iomgr/port.h"
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070035
Sree Kuchibhotla76a07952016-06-22 15:09:06 -070036/* This polling engine is only relevant on linux kernels supporting epoll() */
murgatroid99623dd4f2016-08-08 17:31:27 -070037#ifdef GRPC_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>
Sree Kuchibhotla4998e302016-08-16 07:26:31 -070044#include <pthread.h>
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070045#include <signal.h>
46#include <string.h>
47#include <sys/epoll.h>
48#include <sys/socket.h>
49#include <unistd.h>
50
51#include <grpc/support/alloc.h>
52#include <grpc/support/log.h>
53#include <grpc/support/string_util.h>
54#include <grpc/support/tls.h>
55#include <grpc/support/useful.h>
56
57#include "src/core/lib/iomgr/ev_posix.h"
58#include "src/core/lib/iomgr/iomgr_internal.h"
59#include "src/core/lib/iomgr/wakeup_fd_posix.h"
Craig Tillerb39307d2016-06-30 15:39:13 -070060#include "src/core/lib/iomgr/workqueue.h"
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070061#include "src/core/lib/profiling/timers.h"
62#include "src/core/lib/support/block_annotate.h"
63
Sree Kuchibhotla34217242016-06-29 00:19:07 -070064/* TODO: sreek - Move this to init.c and initialize this like other tracers. */
65static int grpc_polling_trace = 0; /* Disabled by default */
Sree Kuchibhotla1e776682016-06-28 14:09:26 -070066#define GRPC_POLLING_TRACE(fmt, ...) \
67 if (grpc_polling_trace) { \
68 gpr_log(GPR_INFO, (fmt), __VA_ARGS__); \
69 }
70
Sree Kuchibhotla82d73412017-02-09 18:27:45 -080071/* Uncomment the following to enable extra checks on poll_object operations */
Sree Kuchibhotlae6f516e2016-12-08 12:20:23 -080072/* #define PO_DEBUG */
73
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -070074static int grpc_wakeup_signal = -1;
75static bool is_grpc_wakeup_signal_initialized = false;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -070076
Craig Tillerb4b8e1e2016-11-28 07:33:13 -080077/* TODO: sreek: Right now, this wakes up all pollers. In future we should make
78 * sure to wake up one polling thread (which can wake up other threads if
79 * needed) */
80static grpc_wakeup_fd global_wakeup_fd;
81
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -070082/* Implements the function defined in grpc_posix.h. This function might be
83 * called before even calling grpc_init() to set either a different signal to
84 * use. If signum == -1, then the use of signals is disabled */
85void grpc_use_signal(int signum) {
86 grpc_wakeup_signal = signum;
87 is_grpc_wakeup_signal_initialized = true;
88
89 if (grpc_wakeup_signal < 0) {
90 gpr_log(GPR_INFO,
91 "Use of signals is disabled. Epoll engine will not be used");
92 } else {
93 gpr_log(GPR_INFO, "epoll engine will be using signal: %d",
94 grpc_wakeup_signal);
95 }
96}
97
98struct polling_island;
Sree Kuchibhotla5855c472016-06-08 12:56:56 -070099
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800100typedef enum {
101 POLL_OBJ_FD,
102 POLL_OBJ_POLLSET,
103 POLL_OBJ_POLLSET_SET
104} poll_obj_type;
105
106typedef struct poll_obj {
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -0800107#ifdef PO_DEBUG
108 poll_obj_type obj_type;
109#endif
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800110 gpr_mu mu;
111 struct polling_island *pi;
112} poll_obj;
113
114const char *poll_obj_string(poll_obj_type po_type) {
115 switch (po_type) {
116 case POLL_OBJ_FD:
117 return "fd";
118 case POLL_OBJ_POLLSET:
119 return "pollset";
120 case POLL_OBJ_POLLSET_SET:
121 return "pollset_set";
122 }
123
124 GPR_UNREACHABLE_CODE(return "UNKNOWN");
125}
126
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700127/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700128 * Fd Declarations
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700129 */
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800130
131#define FD_FROM_PO(po) ((grpc_fd *)(po))
132
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700133struct grpc_fd {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800134 poll_obj po;
135
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700136 int fd;
137 /* refst format:
Sree Kuchibhotla5098f912016-05-31 10:58:17 -0700138 bit 0 : 1=Active / 0=Orphaned
139 bits 1-n : refcount
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700140 Ref/Unref by two to avoid altering the orphaned bit */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700141 gpr_atm refst;
142
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700143 /* Indicates that the fd is shutdown and that any pending read/write closures
Sree Kuchibhotla82d73412017-02-09 18:27:45 -0800144 should fail. */
145 // TODO: sreek storing bool and grpc_error*
146 gpr_atm shutdown1;
147 gpr_atm shutdown_error1; /* reason for shutdown: set iff shutdown==true */
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700148
149 /* The fd is either closed or we relinquished control of it. In either cases,
150 this indicates that the 'fd' on this structure is no longer valid */
151 bool orphaned;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700152
Sree Kuchibhotla82d73412017-02-09 18:27:45 -0800153 /* Closures to call when the fd is readable or writable. The actual type
154 stored in these is (grpc_closure *) */
155 gpr_atm read_closure;
156 gpr_atm write_closure;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700157
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700158 struct grpc_fd *freelist_next;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700159 grpc_closure *on_done_closure;
160
Sree Kuchibhotla82d73412017-02-09 18:27:45 -0800161 /* The pollset that last noticed that the fd is readable. The actual type
162 * stored in this is (grpc_pollset *) */
163 gpr_atm read_notifier_pollset;
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700164
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700165 grpc_iomgr_object iomgr_object;
166};
167
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700168/* Reference counting for fds */
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700169// #define GRPC_FD_REF_COUNT_DEBUG
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700170#ifdef GRPC_FD_REF_COUNT_DEBUG
171static void fd_ref(grpc_fd *fd, const char *reason, const char *file, int line);
172static void fd_unref(grpc_fd *fd, const char *reason, const char *file,
173 int line);
174#define GRPC_FD_REF(fd, reason) fd_ref(fd, reason, __FILE__, __LINE__)
175#define GRPC_FD_UNREF(fd, reason) fd_unref(fd, reason, __FILE__, __LINE__)
176#else
177static void fd_ref(grpc_fd *fd);
178static void fd_unref(grpc_fd *fd);
179#define GRPC_FD_REF(fd, reason) fd_ref(fd)
180#define GRPC_FD_UNREF(fd, reason) fd_unref(fd)
181#endif
182
183static void fd_global_init(void);
184static void fd_global_shutdown(void);
185
Sree Kuchibhotla82d73412017-02-09 18:27:45 -0800186#define CLOSURE_NOT_READY ((gpr_atm)0)
187#define CLOSURE_READY ((gpr_atm)1)
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700188
189/*******************************************************************************
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700190 * Polling island Declarations
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700191 */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700192
Craig Tillerd8a3c042016-09-09 12:42:37 -0700193#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700194
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700195#define PI_ADD_REF(p, r) pi_add_ref_dbg((p), (r), __FILE__, __LINE__)
Craig Tillerb39307d2016-06-30 15:39:13 -0700196#define PI_UNREF(exec_ctx, p, r) \
197 pi_unref_dbg((exec_ctx), (p), (r), __FILE__, __LINE__)
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700198
Craig Tillerd8a3c042016-09-09 12:42:37 -0700199#else /* defined(GRPC_WORKQUEUE_REFCOUNT_DEBUG) */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700200
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700201#define PI_ADD_REF(p, r) pi_add_ref((p))
Craig Tillerb39307d2016-06-30 15:39:13 -0700202#define PI_UNREF(exec_ctx, p, r) pi_unref((exec_ctx), (p))
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700203
Yuchen Zeng362ac1b2016-09-13 16:01:31 -0700204#endif /* !defined(GRPC_PI_REF_COUNT_DEBUG) */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700205
Craig Tiller460502e2016-10-13 10:02:08 -0700206/* This is also used as grpc_workqueue (by directly casing it) */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700207typedef struct polling_island {
Craig Tiller91031da2016-12-28 15:44:25 -0800208 grpc_closure_scheduler workqueue_scheduler;
209
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700210 gpr_mu mu;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700211 /* Ref count. Use PI_ADD_REF() and PI_UNREF() macros to increment/decrement
212 the refcount.
213 Once the ref count becomes zero, this structure is destroyed which means
214 we should ensure that there is never a scenario where a PI_ADD_REF() is
215 racing with a PI_UNREF() that just made the ref_count zero. */
Craig Tiller15007612016-07-06 09:36:16 -0700216 gpr_atm ref_count;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700217
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700218 /* Pointer to the polling_island this merged into.
219 * merged_to value is only set once in polling_island's lifetime (and that too
220 * only if the island is merged with another island). Because of this, we can
221 * use gpr_atm type here so that we can do atomic access on this and reduce
222 * lock contention on 'mu' mutex.
223 *
224 * Note that if this field is not NULL (i.e not 0), all the remaining fields
225 * (except mu and ref_count) are invalid and must be ignored. */
226 gpr_atm merged_to;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700227
Craig Tiller460502e2016-10-13 10:02:08 -0700228 /* Number of threads currently polling on this island */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700229 gpr_atm poller_count;
Craig Tiller460502e2016-10-13 10:02:08 -0700230 /* Mutex guarding the read end of the workqueue (must be held to pop from
231 * workqueue_items) */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700232 gpr_mu workqueue_read_mu;
Craig Tiller460502e2016-10-13 10:02:08 -0700233 /* Queue of closures to be executed */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700234 gpr_mpscq workqueue_items;
Craig Tiller460502e2016-10-13 10:02:08 -0700235 /* Count of items in workqueue_items */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700236 gpr_atm workqueue_item_count;
Craig Tiller460502e2016-10-13 10:02:08 -0700237 /* Wakeup fd used to wake pollers to check the contents of workqueue_items */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700238 grpc_wakeup_fd workqueue_wakeup_fd;
Craig Tillerb39307d2016-06-30 15:39:13 -0700239
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700240 /* The fd of the underlying epoll set */
241 int epoll_fd;
242
243 /* The file descriptors in the epoll set */
244 size_t fd_cnt;
245 size_t fd_capacity;
246 grpc_fd **fds;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700247} polling_island;
248
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700249/*******************************************************************************
250 * Pollset Declarations
251 */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700252struct grpc_pollset_worker {
Sree Kuchibhotla34217242016-06-29 00:19:07 -0700253 /* Thread id of this worker */
254 pthread_t pt_id;
255
256 /* Used to prevent a worker from getting kicked multiple times */
257 gpr_atm is_kicked;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700258 struct grpc_pollset_worker *next;
259 struct grpc_pollset_worker *prev;
260};
261
262struct grpc_pollset {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800263 poll_obj po;
264
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700265 grpc_pollset_worker root_worker;
266 bool kicked_without_pollers;
267
268 bool shutting_down; /* Is the pollset shutting down ? */
269 bool finish_shutdown_called; /* Is the 'finish_shutdown_locked()' called ? */
270 grpc_closure *shutdown_done; /* Called after after shutdown is complete */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700271};
272
273/*******************************************************************************
274 * Pollset-set Declarations
275 */
276struct grpc_pollset_set {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800277 poll_obj po;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700278};
279
280/*******************************************************************************
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700281 * Common helpers
282 */
283
Craig Tillerf975f742016-07-01 14:56:27 -0700284static bool append_error(grpc_error **composite, grpc_error *error,
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700285 const char *desc) {
Craig Tillerf975f742016-07-01 14:56:27 -0700286 if (error == GRPC_ERROR_NONE) return true;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700287 if (*composite == GRPC_ERROR_NONE) {
288 *composite = GRPC_ERROR_CREATE(desc);
289 }
290 *composite = grpc_error_add_child(*composite, error);
Craig Tillerf975f742016-07-01 14:56:27 -0700291 return false;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700292}
293
294/*******************************************************************************
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700295 * Polling island Definitions
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700296 */
297
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700298/* The wakeup fd that is used to wake up all threads in a Polling island. This
299 is useful in the polling island merge operation where we need to wakeup all
300 the threads currently polling the smaller polling island (so that they can
301 start polling the new/merged polling island)
302
303 NOTE: This fd is initialized to be readable and MUST NOT be consumed i.e the
304 threads that woke up MUST NOT call grpc_wakeup_fd_consume_wakeup() */
305static grpc_wakeup_fd polling_island_wakeup_fd;
306
Craig Tiller2e620132016-10-10 15:27:44 -0700307/* The polling island being polled right now.
308 See comments in workqueue_maybe_wakeup for why this is tracked. */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700309static __thread polling_island *g_current_thread_polling_island;
310
Craig Tillerb39307d2016-06-30 15:39:13 -0700311/* Forward declaration */
Craig Tiller2b49ea92016-07-01 13:21:27 -0700312static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi);
Craig Tiller91031da2016-12-28 15:44:25 -0800313static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
314 grpc_error *error);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700315
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -0700316#ifdef GRPC_TSAN
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700317/* Currently TSAN may incorrectly flag data races between epoll_ctl and
318 epoll_wait for any grpc_fd structs that are added to the epoll set via
319 epoll_ctl and are returned (within a very short window) via epoll_wait().
320
321 To work-around this race, we establish a happens-before relation between
322 the code just-before epoll_ctl() and the code after epoll_wait() by using
323 this atomic */
324gpr_atm g_epoll_sync;
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -0700325#endif /* defined(GRPC_TSAN) */
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700326
Craig Tiller91031da2016-12-28 15:44:25 -0800327static const grpc_closure_scheduler_vtable workqueue_scheduler_vtable = {
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800328 workqueue_enqueue, workqueue_enqueue, "workqueue"};
Craig Tiller91031da2016-12-28 15:44:25 -0800329
Craig Tillerb39307d2016-06-30 15:39:13 -0700330static void pi_add_ref(polling_island *pi);
331static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700332
Craig Tillerd8a3c042016-09-09 12:42:37 -0700333#ifdef GRPC_WORKQUEUE_REFCOUNT_DEBUG
Craig Tillera10b0b12016-09-09 16:20:07 -0700334static void pi_add_ref_dbg(polling_island *pi, const char *reason,
335 const char *file, int line) {
Craig Tiller15007612016-07-06 09:36:16 -0700336 long old_cnt = gpr_atm_acq_load(&pi->ref_count);
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700337 pi_add_ref(pi);
338 gpr_log(GPR_DEBUG, "Add ref pi: %p, old: %ld -> new:%ld (%s) - (%s, %d)",
339 (void *)pi, old_cnt, old_cnt + 1, reason, file, line);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700340}
341
Craig Tillerb39307d2016-06-30 15:39:13 -0700342static void pi_unref_dbg(grpc_exec_ctx *exec_ctx, polling_island *pi,
Craig Tillera10b0b12016-09-09 16:20:07 -0700343 const char *reason, const char *file, int line) {
Craig Tiller15007612016-07-06 09:36:16 -0700344 long old_cnt = gpr_atm_acq_load(&pi->ref_count);
Craig Tillerb39307d2016-06-30 15:39:13 -0700345 pi_unref(exec_ctx, pi);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700346 gpr_log(GPR_DEBUG, "Unref pi: %p, old:%ld -> new:%ld (%s) - (%s, %d)",
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700347 (void *)pi, old_cnt, (old_cnt - 1), reason, file, line);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700348}
Craig Tillerd8a3c042016-09-09 12:42:37 -0700349
350static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue,
351 const char *file, int line,
352 const char *reason) {
353 if (workqueue != NULL) {
Craig Tillera10b0b12016-09-09 16:20:07 -0700354 pi_add_ref_dbg((polling_island *)workqueue, reason, file, line);
Craig Tillerd8a3c042016-09-09 12:42:37 -0700355 }
356 return workqueue;
357}
358
359static void workqueue_unref(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue,
360 const char *file, int line, const char *reason) {
361 if (workqueue != NULL) {
Craig Tillera10b0b12016-09-09 16:20:07 -0700362 pi_unref_dbg(exec_ctx, (polling_island *)workqueue, reason, file, line);
Craig Tillerd8a3c042016-09-09 12:42:37 -0700363 }
364}
365#else
366static grpc_workqueue *workqueue_ref(grpc_workqueue *workqueue) {
367 if (workqueue != NULL) {
368 pi_add_ref((polling_island *)workqueue);
369 }
370 return workqueue;
371}
372
373static void workqueue_unref(grpc_exec_ctx *exec_ctx,
374 grpc_workqueue *workqueue) {
375 if (workqueue != NULL) {
376 pi_unref(exec_ctx, (polling_island *)workqueue);
377 }
378}
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700379#endif
380
Craig Tiller15007612016-07-06 09:36:16 -0700381static void pi_add_ref(polling_island *pi) {
382 gpr_atm_no_barrier_fetch_add(&pi->ref_count, 1);
383}
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700384
Craig Tillerb39307d2016-06-30 15:39:13 -0700385static void pi_unref(grpc_exec_ctx *exec_ctx, polling_island *pi) {
Craig Tillerd8a3c042016-09-09 12:42:37 -0700386 /* If ref count went to zero, delete the polling island.
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700387 Note that this deletion not be done under a lock. Once the ref count goes
388 to zero, we are guaranteed that no one else holds a reference to the
389 polling island (and that there is no racing pi_add_ref() call either).
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700390
391 Also, if we are deleting the polling island and the merged_to field is
392 non-empty, we should remove a ref to the merged_to polling island
393 */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700394 if (1 == gpr_atm_full_fetch_add(&pi->ref_count, -1)) {
395 polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
396 polling_island_delete(exec_ctx, pi);
397 if (next != NULL) {
398 PI_UNREF(exec_ctx, next, "pi_delete"); /* Recursive call */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700399 }
400 }
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700401}
402
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700403/* The caller is expected to hold pi->mu lock before calling this function */
404static void polling_island_add_fds_locked(polling_island *pi, grpc_fd **fds,
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700405 size_t fd_count, bool add_fd_refs,
406 grpc_error **error) {
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700407 int err;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700408 size_t i;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700409 struct epoll_event ev;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700410 char *err_msg;
411 const char *err_desc = "polling_island_add_fds";
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700412
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -0700413#ifdef GRPC_TSAN
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700414 /* See the definition of g_epoll_sync for more context */
Sree Kuchibhotla0224dcc2016-06-22 18:04:00 -0700415 gpr_atm_rel_store(&g_epoll_sync, (gpr_atm)0);
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -0700416#endif /* defined(GRPC_TSAN) */
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700417
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700418 for (i = 0; i < fd_count; i++) {
419 ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
420 ev.data.ptr = fds[i];
421 err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_ADD, fds[i]->fd, &ev);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700422
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700423 if (err < 0) {
424 if (errno != EEXIST) {
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700425 gpr_asprintf(
426 &err_msg,
427 "epoll_ctl (epoll_fd: %d) add fd: %d failed with error: %d (%s)",
428 pi->epoll_fd, fds[i]->fd, errno, strerror(errno));
429 append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
430 gpr_free(err_msg);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700431 }
432
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700433 continue;
434 }
435
436 if (pi->fd_cnt == pi->fd_capacity) {
437 pi->fd_capacity = GPR_MAX(pi->fd_capacity + 8, pi->fd_cnt * 3 / 2);
438 pi->fds = gpr_realloc(pi->fds, sizeof(grpc_fd *) * pi->fd_capacity);
439 }
440
441 pi->fds[pi->fd_cnt++] = fds[i];
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700442 if (add_fd_refs) {
443 GRPC_FD_REF(fds[i], "polling_island");
444 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700445 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700446}
447
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700448/* The caller is expected to hold pi->mu before calling this */
449static void polling_island_add_wakeup_fd_locked(polling_island *pi,
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700450 grpc_wakeup_fd *wakeup_fd,
451 grpc_error **error) {
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700452 struct epoll_event ev;
453 int err;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700454 char *err_msg;
455 const char *err_desc = "polling_island_add_wakeup_fd";
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700456
457 ev.events = (uint32_t)(EPOLLIN | EPOLLET);
458 ev.data.ptr = wakeup_fd;
459 err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_ADD,
460 GRPC_WAKEUP_FD_GET_READ_FD(wakeup_fd), &ev);
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700461 if (err < 0 && errno != EEXIST) {
462 gpr_asprintf(&err_msg,
463 "epoll_ctl (epoll_fd: %d) add wakeup fd: %d failed with "
464 "error: %d (%s)",
Craig Tiller1fa9ddb2016-11-28 08:19:37 -0800465 pi->epoll_fd, GRPC_WAKEUP_FD_GET_READ_FD(&global_wakeup_fd),
466 errno, strerror(errno));
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700467 append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
468 gpr_free(err_msg);
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700469 }
470}
471
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700472/* The caller is expected to hold pi->mu lock before calling this function */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700473static void polling_island_remove_all_fds_locked(polling_island *pi,
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700474 bool remove_fd_refs,
475 grpc_error **error) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700476 int err;
477 size_t i;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700478 char *err_msg;
479 const char *err_desc = "polling_island_remove_fds";
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700480
481 for (i = 0; i < pi->fd_cnt; i++) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700482 err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_DEL, pi->fds[i]->fd, NULL);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700483 if (err < 0 && errno != ENOENT) {
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700484 gpr_asprintf(&err_msg,
485 "epoll_ctl (epoll_fd: %d) delete fds[%zu]: %d failed with "
486 "error: %d (%s)",
487 pi->epoll_fd, i, pi->fds[i]->fd, errno, strerror(errno));
488 append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
489 gpr_free(err_msg);
Sree Kuchibhotlaad162ba2016-06-06 16:23:37 -0700490 }
491
492 if (remove_fd_refs) {
493 GRPC_FD_UNREF(pi->fds[i], "polling_island");
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700494 }
495 }
496
497 pi->fd_cnt = 0;
498}
499
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700500/* The caller is expected to hold pi->mu lock before calling this function */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700501static void polling_island_remove_fd_locked(polling_island *pi, grpc_fd *fd,
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700502 bool is_fd_closed,
503 grpc_error **error) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700504 int err;
505 size_t i;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700506 char *err_msg;
507 const char *err_desc = "polling_island_remove_fd";
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700508
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700509 /* If fd is already closed, then it would have been automatically been removed
510 from the epoll set */
511 if (!is_fd_closed) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700512 err = epoll_ctl(pi->epoll_fd, EPOLL_CTL_DEL, fd->fd, NULL);
513 if (err < 0 && errno != ENOENT) {
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700514 gpr_asprintf(
515 &err_msg,
516 "epoll_ctl (epoll_fd: %d) del fd: %d failed with error: %d (%s)",
517 pi->epoll_fd, fd->fd, errno, strerror(errno));
518 append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
519 gpr_free(err_msg);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700520 }
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700521 }
522
523 for (i = 0; i < pi->fd_cnt; i++) {
524 if (pi->fds[i] == fd) {
525 pi->fds[i] = pi->fds[--pi->fd_cnt];
Sree Kuchibhotla79a62332016-06-04 14:01:03 -0700526 GRPC_FD_UNREF(fd, "polling_island");
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700527 break;
528 }
529 }
530}
531
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700532/* Might return NULL in case of an error */
Craig Tillerb39307d2016-06-30 15:39:13 -0700533static polling_island *polling_island_create(grpc_exec_ctx *exec_ctx,
534 grpc_fd *initial_fd,
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700535 grpc_error **error) {
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700536 polling_island *pi = NULL;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700537 const char *err_desc = "polling_island_create";
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700538
Craig Tillerb39307d2016-06-30 15:39:13 -0700539 *error = GRPC_ERROR_NONE;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700540
Craig Tillerb39307d2016-06-30 15:39:13 -0700541 pi = gpr_malloc(sizeof(*pi));
Craig Tiller91031da2016-12-28 15:44:25 -0800542 pi->workqueue_scheduler.vtable = &workqueue_scheduler_vtable;
Craig Tillerb39307d2016-06-30 15:39:13 -0700543 gpr_mu_init(&pi->mu);
544 pi->fd_cnt = 0;
545 pi->fd_capacity = 0;
546 pi->fds = NULL;
547 pi->epoll_fd = -1;
Craig Tillerd8a3c042016-09-09 12:42:37 -0700548
549 gpr_mu_init(&pi->workqueue_read_mu);
550 gpr_mpscq_init(&pi->workqueue_items);
551 gpr_atm_rel_store(&pi->workqueue_item_count, 0);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700552
Craig Tiller15007612016-07-06 09:36:16 -0700553 gpr_atm_rel_store(&pi->ref_count, 0);
Craig Tillerd8a3c042016-09-09 12:42:37 -0700554 gpr_atm_rel_store(&pi->poller_count, 0);
Sree Kuchibhotla0224dcc2016-06-22 18:04:00 -0700555 gpr_atm_rel_store(&pi->merged_to, (gpr_atm)NULL);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700556
Craig Tillerd8a3c042016-09-09 12:42:37 -0700557 if (!append_error(error, grpc_wakeup_fd_init(&pi->workqueue_wakeup_fd),
558 err_desc)) {
559 goto done;
560 }
561
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700562 pi->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
Sree Kuchibhotla41622a82016-06-13 16:43:14 -0700563
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700564 if (pi->epoll_fd < 0) {
Craig Tillerb39307d2016-06-30 15:39:13 -0700565 append_error(error, GRPC_OS_ERROR(errno, "epoll_create1"), err_desc);
566 goto done;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700567 }
568
Craig Tillerb4b8e1e2016-11-28 07:33:13 -0800569 polling_island_add_wakeup_fd_locked(pi, &global_wakeup_fd, error);
Craig Tillerd8a3c042016-09-09 12:42:37 -0700570 polling_island_add_wakeup_fd_locked(pi, &pi->workqueue_wakeup_fd, error);
Craig Tillerb39307d2016-06-30 15:39:13 -0700571
572 if (initial_fd != NULL) {
Craig Tillerb39307d2016-06-30 15:39:13 -0700573 polling_island_add_fds_locked(pi, &initial_fd, 1, true, error);
Craig Tillerb39307d2016-06-30 15:39:13 -0700574 }
575
Craig Tillerb39307d2016-06-30 15:39:13 -0700576done:
577 if (*error != GRPC_ERROR_NONE) {
Craig Tiller0a06cd72016-07-14 13:21:24 -0700578 polling_island_delete(exec_ctx, pi);
Craig Tillerb39307d2016-06-30 15:39:13 -0700579 pi = NULL;
580 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700581 return pi;
582}
583
Craig Tillerb39307d2016-06-30 15:39:13 -0700584static void polling_island_delete(grpc_exec_ctx *exec_ctx, polling_island *pi) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700585 GPR_ASSERT(pi->fd_cnt == 0);
586
Craig Tiller0a06cd72016-07-14 13:21:24 -0700587 if (pi->epoll_fd >= 0) {
588 close(pi->epoll_fd);
589 }
Craig Tillerd8a3c042016-09-09 12:42:37 -0700590 GPR_ASSERT(gpr_atm_no_barrier_load(&pi->workqueue_item_count) == 0);
591 gpr_mu_destroy(&pi->workqueue_read_mu);
592 gpr_mpscq_destroy(&pi->workqueue_items);
Craig Tillerb39307d2016-06-30 15:39:13 -0700593 gpr_mu_destroy(&pi->mu);
Craig Tillerd8a3c042016-09-09 12:42:37 -0700594 grpc_wakeup_fd_destroy(&pi->workqueue_wakeup_fd);
Craig Tillerb39307d2016-06-30 15:39:13 -0700595 gpr_free(pi->fds);
596 gpr_free(pi);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700597}
598
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700599/* Attempts to gets the last polling island in the linked list (liked by the
600 * 'merged_to' field). Since this does not lock the polling island, there are no
601 * guarantees that the island returned is the last island */
602static polling_island *polling_island_maybe_get_latest(polling_island *pi) {
603 polling_island *next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
604 while (next != NULL) {
605 pi = next;
606 next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
607 }
608
609 return pi;
610}
611
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700612/* Gets the lock on the *latest* polling island i.e the last polling island in
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700613 the linked list (linked by the 'merged_to' field). Call gpr_mu_unlock on the
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700614 returned polling island's mu.
615 Usage: To lock/unlock polling island "pi", do the following:
616 polling_island *pi_latest = polling_island_lock(pi);
617 ...
618 ... critical section ..
619 ...
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700620 gpr_mu_unlock(&pi_latest->mu); // NOTE: use pi_latest->mu. NOT pi->mu */
621static polling_island *polling_island_lock(polling_island *pi) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700622 polling_island *next = NULL;
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700623
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700624 while (true) {
625 next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
626 if (next == NULL) {
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700627 /* Looks like 'pi' is the last node in the linked list but unless we check
628 this by holding the pi->mu lock, we cannot be sure (i.e without the
629 pi->mu lock, we don't prevent island merges).
630 To be absolutely sure, check once more by holding the pi->mu lock */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700631 gpr_mu_lock(&pi->mu);
632 next = (polling_island *)gpr_atm_acq_load(&pi->merged_to);
633 if (next == NULL) {
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700634 /* pi is infact the last node and we have the pi->mu lock. we're done */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700635 break;
636 }
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700637
638 /* pi->merged_to is not NULL i.e pi isn't the last node anymore. pi->mu
639 * isn't the lock we are interested in. Continue traversing the list */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700640 gpr_mu_unlock(&pi->mu);
641 }
642
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700643 pi = next;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700644 }
645
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700646 return pi;
647}
648
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700649/* Gets the lock on the *latest* polling islands in the linked lists pointed by
650 *p and *q (and also updates *p and *q to point to the latest polling islands)
651
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700652 This function is needed because calling the following block of code to obtain
653 locks on polling islands (*p and *q) is prone to deadlocks.
654 {
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700655 polling_island_lock(*p, true);
656 polling_island_lock(*q, true);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700657 }
658
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700659 Usage/example:
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700660 polling_island *p1;
661 polling_island *p2;
662 ..
663 polling_island_lock_pair(&p1, &p2);
664 ..
665 .. Critical section with both p1 and p2 locked
666 ..
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700667 // Release locks: Always call polling_island_unlock_pair() to release locks
668 polling_island_unlock_pair(p1, p2);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700669*/
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700670static void polling_island_lock_pair(polling_island **p, polling_island **q) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700671 polling_island *pi_1 = *p;
672 polling_island *pi_2 = *q;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700673 polling_island *next_1 = NULL;
674 polling_island *next_2 = NULL;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700675
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700676 /* The algorithm is simple:
677 - Go to the last polling islands in the linked lists *pi_1 and *pi_2 (and
678 keep updating pi_1 and pi_2)
679 - Then obtain locks on the islands by following a lock order rule of
680 locking polling_island with lower address first
681 Special case: Before obtaining the locks, check if pi_1 and pi_2 are
682 pointing to the same island. If that is the case, we can just call
683 polling_island_lock()
684 - After obtaining both the locks, double check that the polling islands
685 are still the last polling islands in their respective linked lists
686 (this is because there might have been polling island merges before
687 we got the lock)
688 - If the polling islands are the last islands, we are done. If not,
689 release the locks and continue the process from the first step */
690 while (true) {
691 next_1 = (polling_island *)gpr_atm_acq_load(&pi_1->merged_to);
692 while (next_1 != NULL) {
693 pi_1 = next_1;
694 next_1 = (polling_island *)gpr_atm_acq_load(&pi_1->merged_to);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700695 }
696
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700697 next_2 = (polling_island *)gpr_atm_acq_load(&pi_2->merged_to);
698 while (next_2 != NULL) {
699 pi_2 = next_2;
700 next_2 = (polling_island *)gpr_atm_acq_load(&pi_2->merged_to);
701 }
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700702
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700703 if (pi_1 == pi_2) {
704 pi_1 = pi_2 = polling_island_lock(pi_1);
705 break;
706 }
707
708 if (pi_1 < pi_2) {
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700709 gpr_mu_lock(&pi_1->mu);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700710 gpr_mu_lock(&pi_2->mu);
711 } else {
712 gpr_mu_lock(&pi_2->mu);
713 gpr_mu_lock(&pi_1->mu);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700714 }
715
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700716 next_1 = (polling_island *)gpr_atm_acq_load(&pi_1->merged_to);
717 next_2 = (polling_island *)gpr_atm_acq_load(&pi_2->merged_to);
718 if (next_1 == NULL && next_2 == NULL) {
719 break;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700720 }
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700721
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700722 gpr_mu_unlock(&pi_1->mu);
723 gpr_mu_unlock(&pi_2->mu);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700724 }
725
726 *p = pi_1;
727 *q = pi_2;
728}
729
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700730static void polling_island_unlock_pair(polling_island *p, polling_island *q) {
731 if (p == q) {
732 gpr_mu_unlock(&p->mu);
733 } else {
734 gpr_mu_unlock(&p->mu);
735 gpr_mu_unlock(&q->mu);
736 }
737}
738
Craig Tillerd8a3c042016-09-09 12:42:37 -0700739static void workqueue_maybe_wakeup(polling_island *pi) {
Craig Tiller2e620132016-10-10 15:27:44 -0700740 /* If this thread is the current poller, then it may be that it's about to
741 decrement the current poller count, so we need to look past this thread */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700742 bool is_current_poller = (g_current_thread_polling_island == pi);
743 gpr_atm min_current_pollers_for_wakeup = is_current_poller ? 1 : 0;
744 gpr_atm current_pollers = gpr_atm_no_barrier_load(&pi->poller_count);
Craig Tiller2e620132016-10-10 15:27:44 -0700745 /* Only issue a wakeup if it's likely that some poller could come in and take
746 it right now. Note that since we do an anticipatory mpscq_pop every poll
747 loop, it's ok if we miss the wakeup here, as we'll get the work item when
748 the next poller enters anyway. */
749 if (current_pollers > min_current_pollers_for_wakeup) {
Craig Tillerd8a3c042016-09-09 12:42:37 -0700750 GRPC_LOG_IF_ERROR("workqueue_wakeup_fd",
751 grpc_wakeup_fd_wakeup(&pi->workqueue_wakeup_fd));
752 }
753}
754
755static void workqueue_move_items_to_parent(polling_island *q) {
756 polling_island *p = (polling_island *)gpr_atm_no_barrier_load(&q->merged_to);
757 if (p == NULL) {
758 return;
759 }
760 gpr_mu_lock(&q->workqueue_read_mu);
761 int num_added = 0;
762 while (gpr_atm_no_barrier_load(&q->workqueue_item_count) > 0) {
763 gpr_mpscq_node *n = gpr_mpscq_pop(&q->workqueue_items);
764 if (n != NULL) {
765 gpr_atm_no_barrier_fetch_add(&q->workqueue_item_count, -1);
766 gpr_atm_no_barrier_fetch_add(&p->workqueue_item_count, 1);
767 gpr_mpscq_push(&p->workqueue_items, n);
768 num_added++;
769 }
770 }
771 gpr_mu_unlock(&q->workqueue_read_mu);
772 if (num_added > 0) {
773 workqueue_maybe_wakeup(p);
774 }
775 workqueue_move_items_to_parent(p);
776}
777
Sree Kuchibhotla229533b12016-06-21 20:42:52 -0700778static polling_island *polling_island_merge(polling_island *p,
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700779 polling_island *q,
780 grpc_error **error) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700781 /* Get locks on both the polling islands */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700782 polling_island_lock_pair(&p, &q);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700783
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700784 if (p != q) {
785 /* Make sure that p points to the polling island with fewer fds than q */
786 if (p->fd_cnt > q->fd_cnt) {
787 GPR_SWAP(polling_island *, p, q);
788 }
789
790 /* Merge p with q i.e move all the fds from p (The one with fewer fds) to q
791 Note that the refcounts on the fds being moved will not change here.
792 This is why the last param in the following two functions is 'false') */
793 polling_island_add_fds_locked(q, p->fds, p->fd_cnt, false, error);
794 polling_island_remove_all_fds_locked(p, false, error);
795
796 /* Wakeup all the pollers (if any) on p so that they pickup this change */
797 polling_island_add_wakeup_fd_locked(p, &polling_island_wakeup_fd, error);
798
799 /* Add the 'merged_to' link from p --> q */
800 gpr_atm_rel_store(&p->merged_to, (gpr_atm)q);
801 PI_ADD_REF(q, "pi_merge"); /* To account for the new incoming ref from p */
Craig Tillerd8a3c042016-09-09 12:42:37 -0700802
Harvey Tuchdaa9f452016-11-21 15:42:49 -0500803 workqueue_move_items_to_parent(p);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700804 }
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700805 /* else if p == q, nothing needs to be done */
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700806
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700807 polling_island_unlock_pair(p, q);
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700808
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -0700809 /* Return the merged polling island (Note that no merge would have happened
810 if p == q which is ok) */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700811 return q;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -0700812}
813
Craig Tiller91031da2016-12-28 15:44:25 -0800814static void workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
Craig Tillerd8a3c042016-09-09 12:42:37 -0700815 grpc_error *error) {
Craig Tillerd8a3c042016-09-09 12:42:37 -0700816 GPR_TIMER_BEGIN("workqueue.enqueue", 0);
Craig Tiller91031da2016-12-28 15:44:25 -0800817 grpc_workqueue *workqueue = (grpc_workqueue *)closure->scheduler;
Craig Tiller1dc5dbb2016-09-09 17:09:39 -0700818 /* take a ref to the workqueue: otherwise it can happen that whatever events
819 * this kicks off ends up destroying the workqueue before this function
820 * completes */
821 GRPC_WORKQUEUE_REF(workqueue, "enqueue");
822 polling_island *pi = (polling_island *)workqueue;
Craig Tillerd8a3c042016-09-09 12:42:37 -0700823 gpr_atm last = gpr_atm_no_barrier_fetch_add(&pi->workqueue_item_count, 1);
824 closure->error_data.error = error;
825 gpr_mpscq_push(&pi->workqueue_items, &closure->next_data.atm_next);
826 if (last == 0) {
827 workqueue_maybe_wakeup(pi);
828 }
Craig Tillerd8a3c042016-09-09 12:42:37 -0700829 workqueue_move_items_to_parent(pi);
Craig Tiller1dc5dbb2016-09-09 17:09:39 -0700830 GRPC_WORKQUEUE_UNREF(exec_ctx, workqueue, "enqueue");
831 GPR_TIMER_END("workqueue.enqueue", 0);
Craig Tillerd8a3c042016-09-09 12:42:37 -0700832}
833
Craig Tiller91031da2016-12-28 15:44:25 -0800834static grpc_closure_scheduler *workqueue_scheduler(grpc_workqueue *workqueue) {
835 polling_island *pi = (polling_island *)workqueue;
Craig Tiller801c6cc2017-01-03 08:13:13 -0800836 return workqueue == NULL ? grpc_schedule_on_exec_ctx
837 : &pi->workqueue_scheduler;
Craig Tiller91031da2016-12-28 15:44:25 -0800838}
839
Sree Kuchibhotla3131c262016-06-21 17:28:28 -0700840static grpc_error *polling_island_global_init() {
841 grpc_error *error = GRPC_ERROR_NONE;
842
Sree Kuchibhotla3131c262016-06-21 17:28:28 -0700843 error = grpc_wakeup_fd_init(&polling_island_wakeup_fd);
844 if (error == GRPC_ERROR_NONE) {
845 error = grpc_wakeup_fd_wakeup(&polling_island_wakeup_fd);
846 }
847
848 return error;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700849}
850
Sree Kuchibhotlad627c102016-06-06 15:49:32 -0700851static void polling_island_global_shutdown() {
Sree Kuchibhotla24b10622016-06-08 15:20:17 -0700852 grpc_wakeup_fd_destroy(&polling_island_wakeup_fd);
Sree Kuchibhotlad627c102016-06-06 15:49:32 -0700853}
854
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700855/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700856 * Fd Definitions
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700857 */
858
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700859/* We need to keep a freelist not because of any concerns of malloc performance
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700860 * but instead so that implementations with multiple threads in (for example)
861 * epoll_wait deal with the race between pollset removal and incoming poll
862 * notifications.
863 *
864 * The problem is that the poller ultimately holds a reference to this
865 * object, so it is very difficult to know when is safe to free it, at least
866 * without some expensive synchronization.
867 *
868 * If we keep the object freelisted, in the worst case losing this race just
869 * becomes a spurious read notification on a reused fd.
870 */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700871
872/* The alarm system needs to be able to wakeup 'some poller' sometimes
873 * (specifically when a new alarm needs to be triggered earlier than the next
874 * alarm 'epoch'). This wakeup_fd gives us something to alert on when such a
875 * case occurs. */
Sree Kuchibhotla9bc3d2d2016-06-06 10:27:56 -0700876
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700877static grpc_fd *fd_freelist = NULL;
878static gpr_mu fd_freelist_mu;
879
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700880#ifdef GRPC_FD_REF_COUNT_DEBUG
881#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__)
882#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
883static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file,
884 int line) {
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700885 gpr_log(GPR_DEBUG, "FD %d %p ref %d %ld -> %ld [%s; %s:%d]", fd->fd,
886 (void *)fd, n, gpr_atm_no_barrier_load(&fd->refst),
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700887 gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line);
888#else
889#define REF_BY(fd, n, reason) ref_by(fd, n)
890#define UNREF_BY(fd, n, reason) unref_by(fd, n)
891static void ref_by(grpc_fd *fd, int n) {
892#endif
893 GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0);
894}
895
896#ifdef GRPC_FD_REF_COUNT_DEBUG
897static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file,
898 int line) {
899 gpr_atm old;
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700900 gpr_log(GPR_DEBUG, "FD %d %p unref %d %ld -> %ld [%s; %s:%d]", fd->fd,
901 (void *)fd, n, gpr_atm_no_barrier_load(&fd->refst),
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700902 gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line);
903#else
904static void unref_by(grpc_fd *fd, int n) {
905 gpr_atm old;
906#endif
907 old = gpr_atm_full_fetch_add(&fd->refst, -n);
908 if (old == n) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700909 /* Add the fd to the freelist */
910 gpr_mu_lock(&fd_freelist_mu);
911 fd->freelist_next = fd_freelist;
912 fd_freelist = fd;
913 grpc_iomgr_unregister_object(&fd->iomgr_object);
Sree Kuchibhotla82d73412017-02-09 18:27:45 -0800914
915 if ((bool)gpr_atm_acq_load(&fd->shutdown1)) {
916 grpc_error *err =
917 (grpc_error *)gpr_atm_acq_load(&fd->shutdown_error1);
918 GRPC_ERROR_UNREF(err);
919 }
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -0700920
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700921 gpr_mu_unlock(&fd_freelist_mu);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700922 } else {
923 GPR_ASSERT(old > n);
924 }
925}
926
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700927/* Increment refcount by two to avoid changing the orphan bit */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700928#ifdef GRPC_FD_REF_COUNT_DEBUG
929static void fd_ref(grpc_fd *fd, const char *reason, const char *file,
930 int line) {
931 ref_by(fd, 2, reason, file, line);
932}
933
934static void fd_unref(grpc_fd *fd, const char *reason, const char *file,
935 int line) {
936 unref_by(fd, 2, reason, file, line);
937}
938#else
939static void fd_ref(grpc_fd *fd) { ref_by(fd, 2); }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -0700940static void fd_unref(grpc_fd *fd) { unref_by(fd, 2); }
941#endif
942
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700943static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); }
944
945static void fd_global_shutdown(void) {
946 gpr_mu_lock(&fd_freelist_mu);
947 gpr_mu_unlock(&fd_freelist_mu);
948 while (fd_freelist != NULL) {
949 grpc_fd *fd = fd_freelist;
950 fd_freelist = fd_freelist->freelist_next;
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800951 gpr_mu_destroy(&fd->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700952 gpr_free(fd);
953 }
954 gpr_mu_destroy(&fd_freelist_mu);
955}
956
957static grpc_fd *fd_create(int fd, const char *name) {
958 grpc_fd *new_fd = NULL;
959
960 gpr_mu_lock(&fd_freelist_mu);
961 if (fd_freelist != NULL) {
962 new_fd = fd_freelist;
963 fd_freelist = fd_freelist->freelist_next;
964 }
965 gpr_mu_unlock(&fd_freelist_mu);
966
967 if (new_fd == NULL) {
968 new_fd = gpr_malloc(sizeof(grpc_fd));
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800969 gpr_mu_init(&new_fd->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700970 }
971
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800972 /* Note: It is not really needed to get the new_fd->po.mu lock here. If this
973 * is a newly created fd (or an fd we got from the freelist), no one else
974 * would be holding a lock to it anyway. */
975 gpr_mu_lock(&new_fd->po.mu);
976 new_fd->po.pi = NULL;
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -0800977#ifdef PO_DEBUG
978 new_fd->po.obj_type = POLL_OBJ_FD;
979#endif
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700980
Sree Kuchibhotla0224dcc2016-06-22 18:04:00 -0700981 gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1);
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700982 new_fd->fd = fd;
Sree Kuchibhotla82d73412017-02-09 18:27:45 -0800983 gpr_atm_rel_store(&new_fd->shutdown1, (gpr_atm) false);
984 gpr_atm_rel_store(&new_fd->shutdown_error1, (gpr_atm)GRPC_ERROR_NONE);
Sree Kuchibhotla5855c472016-06-08 12:56:56 -0700985 new_fd->orphaned = false;
Sree Kuchibhotla82d73412017-02-09 18:27:45 -0800986 gpr_atm_rel_store(&new_fd->read_closure, CLOSURE_NOT_READY);
987 gpr_atm_rel_store(&new_fd->write_closure, CLOSURE_NOT_READY);
988 gpr_atm_rel_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
989
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700990 new_fd->freelist_next = NULL;
991 new_fd->on_done_closure = NULL;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700992
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -0800993 gpr_mu_unlock(&new_fd->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700994
995 char *fd_name;
996 gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
997 grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -0700998#ifdef GRPC_FD_REF_COUNT_DEBUG
Sree Kuchibhotla6a295452016-06-23 15:53:10 -0700999 gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, (void *)new_fd, fd_name);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001000#endif
Sree Kuchibhotla6a295452016-06-23 15:53:10 -07001001 gpr_free(fd_name);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001002 return new_fd;
1003}
1004
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001005static int fd_wrapped_fd(grpc_fd *fd) {
1006 int ret_fd = -1;
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001007 gpr_mu_lock(&fd->po.mu);
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001008 if (!fd->orphaned) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001009 ret_fd = fd->fd;
1010 }
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001011 gpr_mu_unlock(&fd->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001012
1013 return ret_fd;
1014}
1015
1016static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1017 grpc_closure *on_done, int *release_fd,
1018 const char *reason) {
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001019 bool is_fd_closed = false;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001020 grpc_error *error = GRPC_ERROR_NONE;
Craig Tiller15007612016-07-06 09:36:16 -07001021 polling_island *unref_pi = NULL;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001022
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001023 gpr_mu_lock(&fd->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001024 fd->on_done_closure = on_done;
1025
1026 /* If release_fd is not NULL, we should be relinquishing control of the file
1027 descriptor fd->fd (but we still own the grpc_fd structure). */
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001028 if (release_fd != NULL) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001029 *release_fd = fd->fd;
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001030 } else {
1031 close(fd->fd);
1032 is_fd_closed = true;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001033 }
1034
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001035 fd->orphaned = true;
1036
1037 /* Remove the active status but keep referenced. We want this grpc_fd struct
1038 to be alive (and not added to freelist) until the end of this function */
1039 REF_BY(fd, 1, reason);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001040
1041 /* Remove the fd from the polling island:
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001042 - Get a lock on the latest polling island (i.e the last island in the
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001043 linked list pointed by fd->po.pi). This is the island that
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001044 would actually contain the fd
1045 - Remove the fd from the latest polling island
1046 - Unlock the latest polling island
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001047 - Set fd->po.pi to NULL (but remove the ref on the polling island
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001048 before doing this.) */
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001049 if (fd->po.pi != NULL) {
1050 polling_island *pi_latest = polling_island_lock(fd->po.pi);
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001051 polling_island_remove_fd_locked(pi_latest, fd, is_fd_closed, &error);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001052 gpr_mu_unlock(&pi_latest->mu);
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001053
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001054 unref_pi = fd->po.pi;
1055 fd->po.pi = NULL;
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -07001056 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001057
Craig Tiller91031da2016-12-28 15:44:25 -08001058 grpc_closure_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error));
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001059
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001060 gpr_mu_unlock(&fd->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001061 UNREF_BY(fd, 2, reason); /* Drop the reference */
Craig Tiller15007612016-07-06 09:36:16 -07001062 if (unref_pi != NULL) {
Craig Tiller0a06cd72016-07-14 13:21:24 -07001063 /* Unref stale polling island here, outside the fd lock above.
1064 The polling island owns a workqueue which owns an fd, and unreffing
1065 inside the lock can cause an eventual lock loop that makes TSAN very
1066 unhappy. */
Craig Tiller15007612016-07-06 09:36:16 -07001067 PI_UNREF(exec_ctx, unref_pi, "fd_orphan");
1068 }
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001069 GRPC_LOG_IF_ERROR("fd_orphan", GRPC_ERROR_REF(error));
Yuchen Zenga0399f22016-08-04 17:52:53 -07001070 GRPC_ERROR_UNREF(error);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001071}
1072
Craig Tillercda759d2017-01-27 11:37:37 -08001073static grpc_error *fd_shutdown_error(grpc_fd *fd) {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001074 grpc_error *err = (grpc_error *)gpr_atm_acq_load(&fd->shutdown_error1);
1075 if (err != GRPC_ERROR_NONE) {
1076 err = GRPC_ERROR_CREATE_REFERENCING("FD Shutdown", &err, 1);
1077 }
1078
1079 return err;
1080
1081 /* TODO sreek - delete this */
1082 /*
Craig Tillercda759d2017-01-27 11:37:37 -08001083 if (!fd->shutdown) {
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001084 return GRPC_ERROR_NONE;
1085 } else {
Craig Tillercda759d2017-01-27 11:37:37 -08001086 return GRPC_ERROR_CREATE_REFERENCING("FD shutdown", &fd->shutdown_error, 1);
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001087 }
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001088 */
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001089}
1090
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001091static void notify_on(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_atm *state,
1092 grpc_closure *closure) {
1093 bool is_done = false;
1094 while (!is_done) {
1095 is_done = true;
1096 if (!gpr_atm_acq_cas(state, CLOSURE_NOT_READY, (gpr_atm)closure)) {
1097 // CAS failed because the current value of 'state' is not
1098 // 'CLOSURE_NOT_READY'
1099 gpr_atm curr = gpr_atm_acq_load(state);
1100
1101 switch (curr) {
1102 case CLOSURE_NOT_READY: {
1103 // The CAS above failed because the state was not 'CLOSURE_NOT_READY'
1104 // but it seems to be back to 'CLOSURE_NOT_READY'. Lets retry CAS
1105 // again
1106 is_done = false;
1107 break;
1108 }
1109
1110 case CLOSURE_READY: {
1111 // Change the state to CLOSURE_NOT_READY and if successful, schedule
1112 // the closure
1113 if (gpr_atm_rel_cas(state, CLOSURE_READY, CLOSURE_NOT_READY)) {
1114 grpc_closure_sched(exec_ctx, closure, fd_shutdown_error(fd));
1115 } else {
1116 // Looks like the current state is not CLOSURE_READY anymore. Retry
1117 // from the beginning
1118 is_done = false;
1119 }
1120 }
1121
1122 default: {
1123 // The current state already contains a closure. This is a fatal error
1124 gpr_log(
1125 GPR_ERROR,
1126 "User called notify_on function with a previous callback still "
1127 "pending");
1128 abort();
1129 break;
1130 }
1131 }
1132 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001133 }
1134}
1135
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001136static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, gpr_atm *state) {
1137 /* Try the fast-path first (i.e expect current value to be CLOSURE_NOT_READY
1138 * and then try to change it to CLOSURE_READY) */
1139 if (!gpr_atm_acq_cas(state, CLOSURE_NOT_READY, CLOSURE_READY)) {
1140 /* CAS failed since the current state is not CLOSURE_NOT_READY. Find out
1141 what is the current state */
1142 gpr_atm curr = gpr_atm_acq_load(state);
1143 switch (curr) {
1144 case CLOSURE_READY: {
1145 /* Already ready. We are done here */
1146 break;
1147 }
1148
1149 case CLOSURE_NOT_READY: {
1150 /* The state was not CLOSURE_NOT_READY when we checked initially at the
1151 beginning of this function but now it is CLOSURE_NOT_READY. This is
1152 only possible if the state transitioned out of CLOSURE_NOT_READY to
1153 either CLOSURE_READY or <some closure> and then back to
1154 CLOSURE_NOT_READY again. So there is no need to make the state
1155 CLOSURE_READY now */
1156 break;
1157 }
1158
1159 default: {
1160 /* 'curr' is a closure. This closure should be enqueued and the current
1161 state should be changed to CLOSURE_NOT_READY */
1162 if (gpr_atm_rel_cas(state, curr, CLOSURE_NOT_READY)) {
1163 grpc_closure_sched(exec_ctx, (grpc_closure *)*state,
1164 fd_shutdown_error(fd));
1165 } /* else the state changed again. This can only happen due to another
1166 racing set_ready function (which means, we do not have to do
1167 anything else here */
1168 break;
1169 }
1170 }
1171 } /* else fast-path succeeded. We are done */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001172}
1173
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001174static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
1175 grpc_fd *fd) {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001176 gpr_atm notifier = gpr_atm_no_barrier_load(&fd->read_closure);
1177 return (grpc_pollset *)notifier;
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001178}
1179
Sree Kuchibhotla24b6eae2016-06-21 18:01:14 -07001180static bool fd_is_shutdown(grpc_fd *fd) {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001181 return (bool)gpr_atm_acq_load(&fd->shutdown1);
Sree Kuchibhotla24b6eae2016-06-21 18:01:14 -07001182}
1183
Sree Kuchibhotla0100b2f2016-06-21 17:38:13 -07001184/* Might be called multiple times */
Craig Tillercda759d2017-01-27 11:37:37 -08001185static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_error *why) {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001186 if (gpr_atm_acq_cas(&fd->shutdown1, (gpr_atm) false, (gpr_atm) true)) {
1187 gpr_atm_rel_store(&fd->shutdown_error1, (gpr_atm)why);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001188
Sree Kuchibhotla0100b2f2016-06-21 17:38:13 -07001189 shutdown(fd->fd, SHUT_RDWR);
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001190
1191 /* Flush any pending read and write closures at this point. Since
1192 fd->shutdown_error1 is set, both the closures would be called with
1193 success = false */
1194 set_ready(exec_ctx, fd, &fd->read_closure);
1195 set_ready(exec_ctx, fd, &fd->write_closure);
1196
Craig Tillercda759d2017-01-27 11:37:37 -08001197 } else {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001198 // Shutdown already called
Craig Tillercda759d2017-01-27 11:37:37 -08001199 GRPC_ERROR_UNREF(why);
Sree Kuchibhotla0100b2f2016-06-21 17:38:13 -07001200 }
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001201
1202 // gpr_mu_lock(&fd->po.mu);
1203 /* Do the actual shutdown only once */
1204 // if (!fd->shutdown) {
1205 // fd->shutdown = true;
1206 // fd->shutdown_error = why;
1207
1208 // shutdown(fd->fd, SHUT_RDWR);
1209 /* Flush any pending read and write closures. Since fd->shutdown is 'true'
1210 at this point, the closures would be called with 'success = false' */
1211 // set_ready(exec_ctx, fd, &fd->read_closure);
1212 // set_ready(exec_ctx, fd, &fd->write_closure);
1213 // } else {
1214 // GRPC_ERROR_UNREF(why);
1215 // }
1216 // gpr_mu_unlock(&fd->po.mu);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001217}
1218
1219static void fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1220 grpc_closure *closure) {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001221 notify_on(exec_ctx, fd, &fd->read_closure, closure);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001222}
1223
1224static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1225 grpc_closure *closure) {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001226 notify_on(exec_ctx, fd, &fd->write_closure, closure);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001227}
1228
Craig Tillerd6ba6192016-06-30 15:42:41 -07001229static grpc_workqueue *fd_get_workqueue(grpc_fd *fd) {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001230 gpr_mu_lock(&fd->po.mu);
Sree Kuchibhotla499b94b2016-11-18 14:35:47 -08001231 grpc_workqueue *workqueue =
1232 GRPC_WORKQUEUE_REF((grpc_workqueue *)fd->po.pi, "fd_get_workqueue");
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001233 gpr_mu_unlock(&fd->po.mu);
Craig Tillerd6ba6192016-06-30 15:42:41 -07001234 return workqueue;
1235}
Craig Tiller70bd4832016-06-30 14:20:46 -07001236
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001237/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001238 * Pollset Definitions
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001239 */
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001240GPR_TLS_DECL(g_current_thread_pollset);
1241GPR_TLS_DECL(g_current_thread_worker);
Craig Tiller19196992016-06-27 18:45:56 -07001242static __thread bool g_initialized_sigmask;
1243static __thread sigset_t g_orig_sigmask;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001244
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001245static void sig_handler(int sig_num) {
Sree Kuchibhotlad627c102016-06-06 15:49:32 -07001246#ifdef GRPC_EPOLL_DEBUG
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001247 gpr_log(GPR_INFO, "Received signal %d", sig_num);
Sree Kuchibhotla9bc3d2d2016-06-06 10:27:56 -07001248#endif
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001249}
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001250
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07001251static void poller_kick_init() { signal(grpc_wakeup_signal, sig_handler); }
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001252
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001253/* Global state management */
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001254static grpc_error *pollset_global_init(void) {
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001255 gpr_tls_init(&g_current_thread_pollset);
1256 gpr_tls_init(&g_current_thread_worker);
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001257 poller_kick_init();
Craig Tillerb4b8e1e2016-11-28 07:33:13 -08001258 return grpc_wakeup_fd_init(&global_wakeup_fd);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001259}
1260
1261static void pollset_global_shutdown(void) {
Craig Tillerb4b8e1e2016-11-28 07:33:13 -08001262 grpc_wakeup_fd_destroy(&global_wakeup_fd);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001263 gpr_tls_destroy(&g_current_thread_pollset);
1264 gpr_tls_destroy(&g_current_thread_worker);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001265}
1266
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001267static grpc_error *pollset_worker_kick(grpc_pollset_worker *worker) {
1268 grpc_error *err = GRPC_ERROR_NONE;
Sree Kuchibhotla34217242016-06-29 00:19:07 -07001269
1270 /* Kick the worker only if it was not already kicked */
1271 if (gpr_atm_no_barrier_cas(&worker->is_kicked, (gpr_atm)0, (gpr_atm)1)) {
1272 GRPC_POLLING_TRACE(
1273 "pollset_worker_kick: Kicking worker: %p (thread id: %ld)",
1274 (void *)worker, worker->pt_id);
1275 int err_num = pthread_kill(worker->pt_id, grpc_wakeup_signal);
1276 if (err_num != 0) {
1277 err = GRPC_OS_ERROR(err_num, "pthread_kill");
1278 }
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001279 }
1280 return err;
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001281}
1282
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001283/* Return 1 if the pollset has active threads in pollset_work (pollset must
1284 * be locked) */
1285static int pollset_has_workers(grpc_pollset *p) {
1286 return p->root_worker.next != &p->root_worker;
1287}
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001288
1289static void remove_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
1290 worker->prev->next = worker->next;
1291 worker->next->prev = worker->prev;
1292}
1293
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001294static grpc_pollset_worker *pop_front_worker(grpc_pollset *p) {
1295 if (pollset_has_workers(p)) {
1296 grpc_pollset_worker *w = p->root_worker.next;
1297 remove_worker(p, w);
1298 return w;
1299 } else {
1300 return NULL;
1301 }
1302}
1303
1304static void push_back_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
1305 worker->next = &p->root_worker;
1306 worker->prev = worker->next->prev;
1307 worker->prev->next = worker->next->prev = worker;
1308}
1309
1310static void push_front_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
1311 worker->prev = &p->root_worker;
1312 worker->next = worker->prev->next;
1313 worker->prev->next = worker->next->prev = worker;
1314}
1315
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001316/* p->mu must be held before calling this function */
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001317static grpc_error *pollset_kick(grpc_pollset *p,
1318 grpc_pollset_worker *specific_worker) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001319 GPR_TIMER_BEGIN("pollset_kick", 0);
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001320 grpc_error *error = GRPC_ERROR_NONE;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001321 const char *err_desc = "Kick Failure";
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001322 grpc_pollset_worker *worker = specific_worker;
1323 if (worker != NULL) {
1324 if (worker == GRPC_POLLSET_KICK_BROADCAST) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001325 if (pollset_has_workers(p)) {
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001326 GPR_TIMER_BEGIN("pollset_kick.broadcast", 0);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001327 for (worker = p->root_worker.next; worker != &p->root_worker;
1328 worker = worker->next) {
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001329 if (gpr_tls_get(&g_current_thread_worker) != (intptr_t)worker) {
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001330 append_error(&error, pollset_worker_kick(worker), err_desc);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001331 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001332 }
Craig Tillera218a062016-06-26 09:58:37 -07001333 GPR_TIMER_END("pollset_kick.broadcast", 0);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001334 } else {
1335 p->kicked_without_pollers = true;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001336 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001337 } else {
1338 GPR_TIMER_MARK("kicked_specifically", 0);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001339 if (gpr_tls_get(&g_current_thread_worker) != (intptr_t)worker) {
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001340 append_error(&error, pollset_worker_kick(worker), err_desc);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001341 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001342 }
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001343 } else if (gpr_tls_get(&g_current_thread_pollset) != (intptr_t)p) {
1344 /* Since worker == NULL, it means that we can kick "any" worker on this
1345 pollset 'p'. If 'p' happens to be the same pollset this thread is
1346 currently polling (i.e in pollset_work() function), then there is no need
1347 to kick any other worker since the current thread can just absorb the
1348 kick. This is the reason why we enter this case only when
1349 g_current_thread_pollset is != p */
1350
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001351 GPR_TIMER_MARK("kick_anonymous", 0);
1352 worker = pop_front_worker(p);
1353 if (worker != NULL) {
1354 GPR_TIMER_MARK("finally_kick", 0);
1355 push_back_worker(p, worker);
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001356 append_error(&error, pollset_worker_kick(worker), err_desc);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001357 } else {
1358 GPR_TIMER_MARK("kicked_no_pollers", 0);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001359 p->kicked_without_pollers = true;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001360 }
1361 }
1362
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001363 GPR_TIMER_END("pollset_kick", 0);
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001364 GRPC_LOG_IF_ERROR("pollset_kick", GRPC_ERROR_REF(error));
1365 return error;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001366}
1367
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001368static grpc_error *kick_poller(void) {
Craig Tillerb4b8e1e2016-11-28 07:33:13 -08001369 return grpc_wakeup_fd_wakeup(&global_wakeup_fd);
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001370}
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001371
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001372static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001373 gpr_mu_init(&pollset->po.mu);
1374 *mu = &pollset->po.mu;
1375 pollset->po.pi = NULL;
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -08001376#ifdef PO_DEBUG
1377 pollset->po.obj_type = POLL_OBJ_POLLSET;
1378#endif
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001379
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001380 pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001381 pollset->kicked_without_pollers = false;
1382
1383 pollset->shutting_down = false;
1384 pollset->finish_shutdown_called = false;
1385 pollset->shutdown_done = NULL;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001386}
1387
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001388/* Convert a timespec to milliseconds:
1389 - Very small or negative poll times are clamped to zero to do a non-blocking
1390 poll (which becomes spin polling)
1391 - Other small values are rounded up to one millisecond
1392 - Longer than a millisecond polls are rounded up to the next nearest
1393 millisecond to avoid spinning
1394 - Infinite timeouts are converted to -1 */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001395static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
1396 gpr_timespec now) {
1397 gpr_timespec timeout;
1398 static const int64_t max_spin_polling_us = 10;
1399 if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) == 0) {
1400 return -1;
1401 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001402
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001403 if (gpr_time_cmp(deadline, gpr_time_add(now, gpr_time_from_micros(
1404 max_spin_polling_us,
1405 GPR_TIMESPAN))) <= 0) {
1406 return 0;
1407 }
1408 timeout = gpr_time_sub(deadline, now);
1409 return gpr_time_to_millis(gpr_time_add(
1410 timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN)));
1411}
1412
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001413static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
1414 grpc_pollset *notifier) {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001415 set_ready(exec_ctx, fd, &fd->read_closure);
1416
1417 // Note, it is possible that fd_become_readable might be called twice with
1418 // different 'notifier's when an fd becomes readable and it is in two epoll
1419 // sets (This can happen briefly during polling island merges). In such cases
1420 // it does not really matter which notifer is set as the read_notifier_pollset
1421 // (They would both point to the same polling island anyway)
1422 gpr_atm_no_barrier_store(&fd->read_notifier_pollset, (gpr_atm)notifier);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001423}
1424
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001425static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
Sree Kuchibhotla82d73412017-02-09 18:27:45 -08001426 set_ready(exec_ctx, fd, &fd->write_closure);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001427}
1428
Craig Tillerb39307d2016-06-30 15:39:13 -07001429static void pollset_release_polling_island(grpc_exec_ctx *exec_ctx,
1430 grpc_pollset *ps, char *reason) {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001431 if (ps->po.pi != NULL) {
1432 PI_UNREF(exec_ctx, ps->po.pi, reason);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001433 }
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001434 ps->po.pi = NULL;
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001435}
1436
1437static void finish_shutdown_locked(grpc_exec_ctx *exec_ctx,
1438 grpc_pollset *pollset) {
1439 /* The pollset cannot have any workers if we are at this stage */
1440 GPR_ASSERT(!pollset_has_workers(pollset));
1441
1442 pollset->finish_shutdown_called = true;
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001443
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001444 /* Release the ref and set pollset->po.pi to NULL */
Craig Tillerb39307d2016-06-30 15:39:13 -07001445 pollset_release_polling_island(exec_ctx, pollset, "ps_shutdown");
Craig Tiller91031da2016-12-28 15:44:25 -08001446 grpc_closure_sched(exec_ctx, pollset->shutdown_done, GRPC_ERROR_NONE);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001447}
1448
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001449/* pollset->po.mu lock must be held by the caller before calling this */
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001450static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1451 grpc_closure *closure) {
1452 GPR_TIMER_BEGIN("pollset_shutdown", 0);
1453 GPR_ASSERT(!pollset->shutting_down);
1454 pollset->shutting_down = true;
1455 pollset->shutdown_done = closure;
1456 pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST);
1457
1458 /* If the pollset has any workers, we cannot call finish_shutdown_locked()
1459 because it would release the underlying polling island. In such a case, we
1460 let the last worker call finish_shutdown_locked() from pollset_work() */
1461 if (!pollset_has_workers(pollset)) {
1462 GPR_ASSERT(!pollset->finish_shutdown_called);
1463 GPR_TIMER_MARK("pollset_shutdown.finish_shutdown_locked", 0);
1464 finish_shutdown_locked(exec_ctx, pollset);
1465 }
1466 GPR_TIMER_END("pollset_shutdown", 0);
1467}
1468
1469/* pollset_shutdown is guaranteed to be called before pollset_destroy. So other
1470 * than destroying the mutexes, there is nothing special that needs to be done
1471 * here */
1472static void pollset_destroy(grpc_pollset *pollset) {
1473 GPR_ASSERT(!pollset_has_workers(pollset));
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001474 gpr_mu_destroy(&pollset->po.mu);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001475}
1476
Craig Tiller2b49ea92016-07-01 13:21:27 -07001477static void pollset_reset(grpc_pollset *pollset) {
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001478 GPR_ASSERT(pollset->shutting_down);
1479 GPR_ASSERT(!pollset_has_workers(pollset));
1480 pollset->shutting_down = false;
1481 pollset->finish_shutdown_called = false;
1482 pollset->kicked_without_pollers = false;
1483 pollset->shutdown_done = NULL;
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001484 GPR_ASSERT(pollset->po.pi == NULL);
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001485}
1486
Craig Tillerd8a3c042016-09-09 12:42:37 -07001487static bool maybe_do_workqueue_work(grpc_exec_ctx *exec_ctx,
1488 polling_island *pi) {
1489 if (gpr_mu_trylock(&pi->workqueue_read_mu)) {
1490 gpr_mpscq_node *n = gpr_mpscq_pop(&pi->workqueue_items);
1491 gpr_mu_unlock(&pi->workqueue_read_mu);
1492 if (n != NULL) {
1493 if (gpr_atm_full_fetch_add(&pi->workqueue_item_count, -1) > 1) {
1494 workqueue_maybe_wakeup(pi);
1495 }
1496 grpc_closure *c = (grpc_closure *)n;
Craig Tiller061ef742016-12-29 10:54:09 -08001497 grpc_error *error = c->error_data.error;
1498 c->cb(exec_ctx, c->cb_arg, error);
1499 GRPC_ERROR_UNREF(error);
Craig Tillerd8a3c042016-09-09 12:42:37 -07001500 return true;
1501 } else if (gpr_atm_no_barrier_load(&pi->workqueue_item_count) > 0) {
Craig Tiller460502e2016-10-13 10:02:08 -07001502 /* n == NULL might mean there's work but it's not available to be popped
1503 * yet - try to ensure another workqueue wakes up to check shortly if so
1504 */
Craig Tillerd8a3c042016-09-09 12:42:37 -07001505 workqueue_maybe_wakeup(pi);
1506 }
1507 }
1508 return false;
1509}
1510
Craig Tiller84ea3412016-09-08 14:57:56 -07001511#define GRPC_EPOLL_MAX_EVENTS 100
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001512/* Note: sig_mask contains the signal mask to use *during* epoll_wait() */
1513static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx,
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001514 grpc_pollset *pollset,
1515 grpc_pollset_worker *worker, int timeout_ms,
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001516 sigset_t *sig_mask, grpc_error **error) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001517 struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS];
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -07001518 int epoll_fd = -1;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001519 int ep_rv;
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001520 polling_island *pi = NULL;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001521 char *err_msg;
1522 const char *err_desc = "pollset_work_and_unlock";
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001523 GPR_TIMER_BEGIN("pollset_work_and_unlock", 0);
1524
1525 /* We need to get the epoll_fd to wait on. The epoll_fd is in inside the
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001526 latest polling island pointed by pollset->po.pi
Sree Kuchibhotla229533b12016-06-21 20:42:52 -07001527
1528 Since epoll_fd is immutable, we can read it without obtaining the polling
1529 island lock. There is however a possibility that the polling island (from
1530 which we got the epoll_fd) got merged with another island while we are
1531 in this function. This is still okay because in such a case, we will wakeup
1532 right-away from epoll_wait() and pick up the latest polling_island the next
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001533 this function (i.e pollset_work_and_unlock()) is called */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001534
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001535 if (pollset->po.pi == NULL) {
1536 pollset->po.pi = polling_island_create(exec_ctx, NULL, error);
1537 if (pollset->po.pi == NULL) {
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001538 GPR_TIMER_END("pollset_work_and_unlock", 0);
1539 return; /* Fatal error. We cannot continue */
1540 }
1541
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001542 PI_ADD_REF(pollset->po.pi, "ps");
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001543 GRPC_POLLING_TRACE("pollset_work: pollset: %p created new pi: %p",
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001544 (void *)pollset, (void *)pollset->po.pi);
Sree Kuchibhotla88ee12f2016-06-03 19:26:48 -07001545 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001546
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001547 pi = polling_island_maybe_get_latest(pollset->po.pi);
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001548 epoll_fd = pi->epoll_fd;
1549
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001550 /* Update the pollset->po.pi since the island being pointed by
1551 pollset->po.pi maybe older than the one pointed by pi) */
1552 if (pollset->po.pi != pi) {
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001553 /* Always do PI_ADD_REF before PI_UNREF because PI_UNREF may cause the
1554 polling island to be deleted */
1555 PI_ADD_REF(pi, "ps");
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001556 PI_UNREF(exec_ctx, pollset->po.pi, "ps");
1557 pollset->po.pi = pi;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001558 }
Sree Kuchibhotlad627c102016-06-06 15:49:32 -07001559
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001560 /* Add an extra ref so that the island does not get destroyed (which means
1561 the epoll_fd won't be closed) while we are are doing an epoll_wait() on the
1562 epoll_fd */
1563 PI_ADD_REF(pi, "ps_work");
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001564 gpr_mu_unlock(&pollset->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001565
Craig Tiller460502e2016-10-13 10:02:08 -07001566 /* If we get some workqueue work to do, it might end up completing an item on
1567 the completion queue, so there's no need to poll... so we skip that and
1568 redo the complete loop to verify */
Craig Tillerd8a3c042016-09-09 12:42:37 -07001569 if (!maybe_do_workqueue_work(exec_ctx, pi)) {
1570 gpr_atm_no_barrier_fetch_add(&pi->poller_count, 1);
1571 g_current_thread_polling_island = pi;
1572
Vijay Paicef54012016-08-28 23:05:31 -07001573 GRPC_SCHEDULING_START_BLOCKING_REGION;
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001574 ep_rv = epoll_pwait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, timeout_ms,
1575 sig_mask);
Vijay Paicef54012016-08-28 23:05:31 -07001576 GRPC_SCHEDULING_END_BLOCKING_REGION;
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001577 if (ep_rv < 0) {
1578 if (errno != EINTR) {
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001579 gpr_asprintf(&err_msg,
1580 "epoll_wait() epoll fd: %d failed with error: %d (%s)",
1581 epoll_fd, errno, strerror(errno));
1582 append_error(error, GRPC_OS_ERROR(errno, err_msg), err_desc);
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001583 } else {
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001584 /* We were interrupted. Save an interation by doing a zero timeout
1585 epoll_wait to see if there are any other events of interest */
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001586 GRPC_POLLING_TRACE(
1587 "pollset_work: pollset: %p, worker: %p received kick",
1588 (void *)pollset, (void *)worker);
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001589 ep_rv = epoll_wait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0);
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001590 }
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001591 }
Sree Kuchibhotla79a62332016-06-04 14:01:03 -07001592
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -07001593#ifdef GRPC_TSAN
Sree Kuchibhotla41622a82016-06-13 16:43:14 -07001594 /* See the definition of g_poll_sync for more details */
1595 gpr_atm_acq_load(&g_epoll_sync);
Sree Kuchibhotlaad2c4772016-06-13 19:06:54 -07001596#endif /* defined(GRPC_TSAN) */
Sree Kuchibhotla41622a82016-06-13 16:43:14 -07001597
Sree Kuchibhotla58e58962016-06-13 00:52:56 -07001598 for (int i = 0; i < ep_rv; ++i) {
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001599 void *data_ptr = ep_ev[i].data.ptr;
Craig Tillerb4b8e1e2016-11-28 07:33:13 -08001600 if (data_ptr == &global_wakeup_fd) {
Craig Tiller1fa9ddb2016-11-28 08:19:37 -08001601 append_error(error, grpc_wakeup_fd_consume_wakeup(&global_wakeup_fd),
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001602 err_desc);
Craig Tillerd8a3c042016-09-09 12:42:37 -07001603 } else if (data_ptr == &pi->workqueue_wakeup_fd) {
Craig Tillere49959d2017-01-26 08:39:38 -08001604 append_error(error,
1605 grpc_wakeup_fd_consume_wakeup(&pi->workqueue_wakeup_fd),
Craig Tillerd8a3c042016-09-09 12:42:37 -07001606 err_desc);
1607 maybe_do_workqueue_work(exec_ctx, pi);
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001608 } else if (data_ptr == &polling_island_wakeup_fd) {
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001609 GRPC_POLLING_TRACE(
1610 "pollset_work: pollset: %p, worker: %p polling island (epoll_fd: "
1611 "%d) got merged",
1612 (void *)pollset, (void *)worker, epoll_fd);
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001613 /* This means that our polling island is merged with a different
1614 island. We do not have to do anything here since the subsequent call
1615 to the function pollset_work_and_unlock() will pick up the correct
1616 epoll_fd */
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001617 } else {
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001618 grpc_fd *fd = data_ptr;
1619 int cancel = ep_ev[i].events & (EPOLLERR | EPOLLHUP);
1620 int read_ev = ep_ev[i].events & (EPOLLIN | EPOLLPRI);
1621 int write_ev = ep_ev[i].events & EPOLLOUT;
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001622 if (read_ev || cancel) {
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07001623 fd_become_readable(exec_ctx, fd, pollset);
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001624 }
1625 if (write_ev || cancel) {
1626 fd_become_writable(exec_ctx, fd);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001627 }
1628 }
Sree Kuchibhotlae5012ba2016-06-06 16:01:45 -07001629 }
Craig Tillerd8a3c042016-09-09 12:42:37 -07001630
1631 g_current_thread_polling_island = NULL;
1632 gpr_atm_no_barrier_fetch_add(&pi->poller_count, -1);
1633 }
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001634
1635 GPR_ASSERT(pi != NULL);
1636
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001637 /* Before leaving, release the extra ref we added to the polling island. It
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001638 is important to use "pi" here (i.e our old copy of pollset->po.pi
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001639 that we got before releasing the polling island lock). This is because
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001640 pollset->po.pi pointer might get udpated in other parts of the
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001641 code when there is an island merge while we are doing epoll_wait() above */
Craig Tillerb39307d2016-06-30 15:39:13 -07001642 PI_UNREF(exec_ctx, pi, "ps_work");
Sree Kuchibhotla24b10622016-06-08 15:20:17 -07001643
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001644 GPR_TIMER_END("pollset_work_and_unlock", 0);
1645}
1646
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001647/* pollset->po.mu lock must be held by the caller before calling this.
1648 The function pollset_work() may temporarily release the lock (pollset->po.mu)
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001649 during the course of its execution but it will always re-acquire the lock and
1650 ensure that it is held by the time the function returns */
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001651static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1652 grpc_pollset_worker **worker_hdl,
1653 gpr_timespec now, gpr_timespec deadline) {
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001654 GPR_TIMER_BEGIN("pollset_work", 0);
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001655 grpc_error *error = GRPC_ERROR_NONE;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001656 int timeout_ms = poll_deadline_to_millis_timeout(deadline, now);
1657
1658 sigset_t new_mask;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001659
1660 grpc_pollset_worker worker;
1661 worker.next = worker.prev = NULL;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001662 worker.pt_id = pthread_self();
Sree Kuchibhotla34217242016-06-29 00:19:07 -07001663 gpr_atm_no_barrier_store(&worker.is_kicked, (gpr_atm)0);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001664
1665 *worker_hdl = &worker;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001666
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001667 gpr_tls_set(&g_current_thread_pollset, (intptr_t)pollset);
1668 gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001669
1670 if (pollset->kicked_without_pollers) {
1671 /* If the pollset was kicked without pollers, pretend that the current
1672 worker got the kick and skip polling. A kick indicates that there is some
1673 work that needs attention like an event on the completion queue or an
1674 alarm */
1675 GPR_TIMER_MARK("pollset_work.kicked_without_pollers", 0);
1676 pollset->kicked_without_pollers = 0;
1677 } else if (!pollset->shutting_down) {
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001678 /* We use the posix-signal with number 'grpc_wakeup_signal' for waking up
Sree Kuchibhotla34217242016-06-29 00:19:07 -07001679 (i.e 'kicking') a worker in the pollset. A 'kick' is a way to inform the
1680 worker that there is some pending work that needs immediate attention
1681 (like an event on the completion queue, or a polling island merge that
1682 results in a new epoll-fd to wait on) and that the worker should not
1683 spend time waiting in epoll_pwait().
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001684
Sree Kuchibhotla34217242016-06-29 00:19:07 -07001685 A worker can be kicked anytime from the point it is added to the pollset
1686 via push_front_worker() (or push_back_worker()) to the point it is
1687 removed via remove_worker().
1688 If the worker is kicked before/during it calls epoll_pwait(), it should
1689 immediately exit from epoll_wait(). If the worker is kicked after it
1690 returns from epoll_wait(), then nothing really needs to be done.
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001691
Sree Kuchibhotla34217242016-06-29 00:19:07 -07001692 To accomplish this, we mask 'grpc_wakeup_signal' on this thread at all
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001693 times *except* when it is in epoll_pwait(). This way, the worker never
1694 misses acting on a kick */
1695
Craig Tiller19196992016-06-27 18:45:56 -07001696 if (!g_initialized_sigmask) {
1697 sigemptyset(&new_mask);
1698 sigaddset(&new_mask, grpc_wakeup_signal);
1699 pthread_sigmask(SIG_BLOCK, &new_mask, &g_orig_sigmask);
1700 sigdelset(&g_orig_sigmask, grpc_wakeup_signal);
1701 g_initialized_sigmask = true;
1702 /* new_mask: The new thread mask which blocks 'grpc_wakeup_signal'.
1703 This is the mask used at all times *except during
1704 epoll_wait()*"
1705 g_orig_sigmask: The thread mask which allows 'grpc_wakeup_signal' and
Craig Tiller510ff692016-06-27 20:31:49 -07001706 this is the mask to use *during epoll_wait()*
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001707
Craig Tiller19196992016-06-27 18:45:56 -07001708 The new_mask is set on the worker before it is added to the pollset
Craig Tiller510ff692016-06-27 20:31:49 -07001709 (i.e before it can be kicked) */
Craig Tiller19196992016-06-27 18:45:56 -07001710 }
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001711
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001712 push_front_worker(pollset, &worker); /* Add worker to pollset */
1713
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001714 pollset_work_and_unlock(exec_ctx, pollset, &worker, timeout_ms,
1715 &g_orig_sigmask, &error);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001716 grpc_exec_ctx_flush(exec_ctx);
1717
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001718 gpr_mu_lock(&pollset->po.mu);
Sree Kuchibhotla34217242016-06-29 00:19:07 -07001719
1720 /* Note: There is no need to reset worker.is_kicked to 0 since we are no
1721 longer going to use this worker */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001722 remove_worker(pollset, &worker);
1723 }
1724
1725 /* If we are the last worker on the pollset (i.e pollset_has_workers() is
1726 false at this point) and the pollset is shutting down, we may have to
1727 finish the shutdown process by calling finish_shutdown_locked().
1728 See pollset_shutdown() for more details.
1729
1730 Note: Continuing to access pollset here is safe; it is the caller's
1731 responsibility to not destroy a pollset when it has outstanding calls to
1732 pollset_work() */
1733 if (pollset->shutting_down && !pollset_has_workers(pollset) &&
1734 !pollset->finish_shutdown_called) {
1735 GPR_TIMER_MARK("pollset_work.finish_shutdown_locked", 0);
1736 finish_shutdown_locked(exec_ctx, pollset);
1737
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001738 gpr_mu_unlock(&pollset->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001739 grpc_exec_ctx_flush(exec_ctx);
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001740 gpr_mu_lock(&pollset->po.mu);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001741 }
1742
1743 *worker_hdl = NULL;
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001744
Sree Kuchibhotla8e4926c2016-06-08 20:33:19 -07001745 gpr_tls_set(&g_current_thread_pollset, (intptr_t)0);
1746 gpr_tls_set(&g_current_thread_worker, (intptr_t)0);
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001747
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001748 GPR_TIMER_END("pollset_work", 0);
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001749
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07001750 GRPC_LOG_IF_ERROR("pollset_work", GRPC_ERROR_REF(error));
1751 return error;
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001752}
1753
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001754static void add_poll_object(grpc_exec_ctx *exec_ctx, poll_obj *bag,
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -08001755 poll_obj_type bag_type, poll_obj *item,
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001756 poll_obj_type item_type) {
1757 GPR_TIMER_BEGIN("add_poll_object", 0);
1758
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -08001759#ifdef PO_DEBUG
1760 GPR_ASSERT(item->obj_type == item_type);
1761 GPR_ASSERT(bag->obj_type == bag_type);
1762#endif
Craig Tiller57726ca2016-09-12 11:59:45 -07001763
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001764 grpc_error *error = GRPC_ERROR_NONE;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001765 polling_island *pi_new = NULL;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001766
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001767 gpr_mu_lock(&bag->mu);
1768 gpr_mu_lock(&item->mu);
1769
Craig Tiller7212c232016-07-06 13:11:09 -07001770retry:
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001771 /*
1772 * 1) If item->pi and bag->pi are both non-NULL and equal, do nothing
1773 * 2) If item->pi and bag->pi are both NULL, create a new polling island (with
1774 * a refcount of 2) and point item->pi and bag->pi to the new island
1775 * 3) If exactly one of item->pi or bag->pi is NULL, update it to point to
1776 * the other's non-NULL pi
1777 * 4) Finally if item->pi and bag-pi are non-NULL and not-equal, merge the
1778 * polling islands and update item->pi and bag->pi to point to the new
1779 * island
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001780 */
Craig Tiller8e8027b2016-07-07 10:42:09 -07001781
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001782 /* Early out if we are trying to add an 'fd' to a 'bag' but the fd is already
1783 * orphaned */
1784 if (item_type == POLL_OBJ_FD && (FD_FROM_PO(item))->orphaned) {
1785 gpr_mu_unlock(&item->mu);
1786 gpr_mu_unlock(&bag->mu);
Craig Tiller42ac6db2016-07-06 17:13:56 -07001787 return;
1788 }
1789
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001790 if (item->pi == bag->pi) {
1791 pi_new = item->pi;
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001792 if (pi_new == NULL) {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001793 /* GPR_ASSERT(item->pi == bag->pi == NULL) */
Sree Kuchibhotlaa129adf2016-10-26 16:44:44 -07001794
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001795 /* If we are adding an fd to a bag (i.e pollset or pollset_set), then
1796 * we need to do some extra work to make TSAN happy */
1797 if (item_type == POLL_OBJ_FD) {
1798 /* Unlock before creating a new polling island: the polling island will
1799 create a workqueue which creates a file descriptor, and holding an fd
1800 lock here can eventually cause a loop to appear to TSAN (making it
1801 unhappy). We don't think it's a real loop (there's an epoch point
1802 where that loop possibility disappears), but the advantages of
1803 keeping TSAN happy outweigh any performance advantage we might have
1804 by keeping the lock held. */
1805 gpr_mu_unlock(&item->mu);
1806 pi_new = polling_island_create(exec_ctx, FD_FROM_PO(item), &error);
1807 gpr_mu_lock(&item->mu);
Sree Kuchibhotlaa129adf2016-10-26 16:44:44 -07001808
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001809 /* Need to reverify any assumptions made between the initial lock and
1810 getting to this branch: if they've changed, we need to throw away our
1811 work and figure things out again. */
1812 if (item->pi != NULL) {
Sree Kuchibhotla499b94b2016-11-18 14:35:47 -08001813 GRPC_POLLING_TRACE(
1814 "add_poll_object: Raced creating new polling island. pi_new: %p "
1815 "(fd: %d, %s: %p)",
1816 (void *)pi_new, FD_FROM_PO(item)->fd, poll_obj_string(bag_type),
1817 (void *)bag);
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001818 /* No need to lock 'pi_new' here since this is a new polling island
Sree Kuchibhotla499b94b2016-11-18 14:35:47 -08001819 * and no one has a reference to it yet */
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001820 polling_island_remove_all_fds_locked(pi_new, true, &error);
1821
1822 /* Ref and unref so that the polling island gets deleted during unref
1823 */
1824 PI_ADD_REF(pi_new, "dance_of_destruction");
1825 PI_UNREF(exec_ctx, pi_new, "dance_of_destruction");
1826 goto retry;
1827 }
Craig Tiller27da6422016-07-06 13:14:46 -07001828 } else {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001829 pi_new = polling_island_create(exec_ctx, NULL, &error);
Craig Tiller7212c232016-07-06 13:11:09 -07001830 }
Sree Kuchibhotla499b94b2016-11-18 14:35:47 -08001831
1832 GRPC_POLLING_TRACE(
1833 "add_poll_object: Created new polling island. pi_new: %p (%s: %p, "
1834 "%s: %p)",
1835 (void *)pi_new, poll_obj_string(item_type), (void *)item,
1836 poll_obj_string(bag_type), (void *)bag);
1837 } else {
1838 GRPC_POLLING_TRACE(
1839 "add_poll_object: Same polling island. pi: %p (%s, %s)",
1840 (void *)pi_new, poll_obj_string(item_type),
1841 poll_obj_string(bag_type));
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001842 }
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001843 } else if (item->pi == NULL) {
1844 /* GPR_ASSERT(bag->pi != NULL) */
1845 /* Make pi_new point to latest pi*/
1846 pi_new = polling_island_lock(bag->pi);
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001847
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001848 if (item_type == POLL_OBJ_FD) {
1849 grpc_fd *fd = FD_FROM_PO(item);
1850 polling_island_add_fds_locked(pi_new, &fd, 1, true, &error);
1851 }
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001852
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001853 gpr_mu_unlock(&pi_new->mu);
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001854 GRPC_POLLING_TRACE(
Sree Kuchibhotla499b94b2016-11-18 14:35:47 -08001855 "add_poll_obj: item->pi was NULL. pi_new: %p (item(%s): %p, "
1856 "bag(%s): %p)",
1857 (void *)pi_new, poll_obj_string(item_type), (void *)item,
1858 poll_obj_string(bag_type), (void *)bag);
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001859 } else if (bag->pi == NULL) {
1860 /* GPR_ASSERT(item->pi != NULL) */
1861 /* Make pi_new to point to latest pi */
1862 pi_new = polling_island_lock(item->pi);
1863 gpr_mu_unlock(&pi_new->mu);
Sree Kuchibhotla499b94b2016-11-18 14:35:47 -08001864 GRPC_POLLING_TRACE(
1865 "add_poll_obj: bag->pi was NULL. pi_new: %p (item(%s): %p, "
1866 "bag(%s): %p)",
1867 (void *)pi_new, poll_obj_string(item_type), (void *)item,
1868 poll_obj_string(bag_type), (void *)bag);
Sree Kuchibhotla5098f912016-05-31 10:58:17 -07001869 } else {
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001870 pi_new = polling_island_merge(item->pi, bag->pi, &error);
Sree Kuchibhotla1e776682016-06-28 14:09:26 -07001871 GRPC_POLLING_TRACE(
Sree Kuchibhotla499b94b2016-11-18 14:35:47 -08001872 "add_poll_obj: polling islands merged. pi_new: %p (item(%s): %p, "
1873 "bag(%s): %p)",
1874 (void *)pi_new, poll_obj_string(item_type), (void *)item,
1875 poll_obj_string(bag_type), (void *)bag);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001876 }
1877
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001878 /* At this point, pi_new is the polling island that both item->pi and bag->pi
1879 MUST be pointing to */
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001880
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001881 if (item->pi != pi_new) {
1882 PI_ADD_REF(pi_new, poll_obj_string(item_type));
1883 if (item->pi != NULL) {
1884 PI_UNREF(exec_ctx, item->pi, poll_obj_string(item_type));
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001885 }
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001886 item->pi = pi_new;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001887 }
1888
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001889 if (bag->pi != pi_new) {
1890 PI_ADD_REF(pi_new, poll_obj_string(bag_type));
1891 if (bag->pi != NULL) {
1892 PI_UNREF(exec_ctx, bag->pi, poll_obj_string(bag_type));
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001893 }
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001894 bag->pi = pi_new;
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001895 }
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001896
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001897 gpr_mu_unlock(&item->mu);
1898 gpr_mu_unlock(&bag->mu);
Craig Tiller15007612016-07-06 09:36:16 -07001899
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001900 GRPC_LOG_IF_ERROR("add_poll_object", error);
1901 GPR_TIMER_END("add_poll_object", 0);
1902}
Craig Tiller57726ca2016-09-12 11:59:45 -07001903
Sree Kuchibhotla9442bab2016-05-20 17:54:06 -07001904static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1905 grpc_fd *fd) {
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -08001906 add_poll_object(exec_ctx, &pollset->po, POLL_OBJ_POLLSET, &fd->po,
Sree Kuchibhotla499b94b2016-11-18 14:35:47 -08001907 POLL_OBJ_FD);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001908}
1909
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001910/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001911 * Pollset-set Definitions
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001912 */
1913
1914static grpc_pollset_set *pollset_set_create(void) {
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001915 grpc_pollset_set *pss = gpr_malloc(sizeof(*pss));
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001916 gpr_mu_init(&pss->po.mu);
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -08001917 pss->po.pi = NULL;
1918#ifdef PO_DEBUG
1919 pss->po.obj_type = POLL_OBJ_POLLSET_SET;
1920#endif
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001921 return pss;
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001922}
1923
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001924static void pollset_set_destroy(grpc_pollset_set *pss) {
1925 gpr_mu_destroy(&pss->po.mu);
1926
1927 if (pss->po.pi != NULL) {
1928 grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
1929 PI_UNREF(&exec_ctx, pss->po.pi, "pss_destroy");
1930 grpc_exec_ctx_finish(&exec_ctx);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001931 }
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001932
1933 gpr_free(pss);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001934}
1935
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001936static void pollset_set_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset_set *pss,
1937 grpc_fd *fd) {
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -08001938 add_poll_object(exec_ctx, &pss->po, POLL_OBJ_POLLSET_SET, &fd->po,
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001939 POLL_OBJ_FD);
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001940}
1941
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001942static void pollset_set_del_fd(grpc_exec_ctx *exec_ctx, grpc_pollset_set *pss,
1943 grpc_fd *fd) {
1944 /* Nothing to do */
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07001945}
1946
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001947static void pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001948 grpc_pollset_set *pss, grpc_pollset *ps) {
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -08001949 add_poll_object(exec_ctx, &pss->po, POLL_OBJ_POLLSET_SET, &ps->po,
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001950 POLL_OBJ_POLLSET);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001951}
1952
1953static void pollset_set_del_pollset(grpc_exec_ctx *exec_ctx,
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001954 grpc_pollset_set *pss, grpc_pollset *ps) {
1955 /* Nothing to do */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001956}
1957
1958static void pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx,
1959 grpc_pollset_set *bag,
1960 grpc_pollset_set *item) {
Sree Kuchibhotlaa0749a62016-11-18 20:22:09 -08001961 add_poll_object(exec_ctx, &bag->po, POLL_OBJ_POLLSET_SET, &item->po,
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001962 POLL_OBJ_POLLSET_SET);
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001963}
1964
1965static void pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx,
1966 grpc_pollset_set *bag,
1967 grpc_pollset_set *item) {
Sree Kuchibhotla2385fd72016-11-18 16:30:41 -08001968 /* Nothing to do */
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07001969}
1970
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -07001971/* Test helper functions
1972 * */
1973void *grpc_fd_get_polling_island(grpc_fd *fd) {
1974 polling_island *pi;
1975
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001976 gpr_mu_lock(&fd->po.mu);
1977 pi = fd->po.pi;
1978 gpr_mu_unlock(&fd->po.mu);
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -07001979
1980 return pi;
1981}
1982
1983void *grpc_pollset_get_polling_island(grpc_pollset *ps) {
1984 polling_island *pi;
1985
Sree Kuchibhotlaf6f33d72016-11-18 11:38:52 -08001986 gpr_mu_lock(&ps->po.mu);
1987 pi = ps->po.pi;
1988 gpr_mu_unlock(&ps->po.mu);
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -07001989
1990 return pi;
1991}
1992
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -07001993bool grpc_are_polling_islands_equal(void *p, void *q) {
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001994 polling_island *p1 = p;
1995 polling_island *p2 = q;
1996
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07001997 /* Note: polling_island_lock_pair() may change p1 and p2 to point to the
1998 latest polling islands in their respective linked lists */
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07001999 polling_island_lock_pair(&p1, &p2);
Sree Kuchibhotla20d0a162016-06-23 15:14:03 -07002000 polling_island_unlock_pair(p1, p2);
Sree Kuchibhotla2f8ade02016-06-17 13:28:38 -07002001
2002 return p1 == p2;
Sree Kuchibhotla2e12db92016-06-16 16:53:59 -07002003}
2004
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002005/*******************************************************************************
Sree Kuchibhotla0bcbd792016-06-01 15:43:03 -07002006 * Event engine binding
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002007 */
2008
2009static void shutdown_engine(void) {
2010 fd_global_shutdown();
2011 pollset_global_shutdown();
Sree Kuchibhotlad627c102016-06-06 15:49:32 -07002012 polling_island_global_shutdown();
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002013}
2014
2015static const grpc_event_engine_vtable vtable = {
2016 .pollset_size = sizeof(grpc_pollset),
2017
2018 .fd_create = fd_create,
2019 .fd_wrapped_fd = fd_wrapped_fd,
2020 .fd_orphan = fd_orphan,
2021 .fd_shutdown = fd_shutdown,
Sree Kuchibhotla24b6eae2016-06-21 18:01:14 -07002022 .fd_is_shutdown = fd_is_shutdown,
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002023 .fd_notify_on_read = fd_notify_on_read,
2024 .fd_notify_on_write = fd_notify_on_write,
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07002025 .fd_get_read_notifier_pollset = fd_get_read_notifier_pollset,
Craig Tiller70bd4832016-06-30 14:20:46 -07002026 .fd_get_workqueue = fd_get_workqueue,
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002027
2028 .pollset_init = pollset_init,
2029 .pollset_shutdown = pollset_shutdown,
2030 .pollset_reset = pollset_reset,
2031 .pollset_destroy = pollset_destroy,
2032 .pollset_work = pollset_work,
2033 .pollset_kick = pollset_kick,
2034 .pollset_add_fd = pollset_add_fd,
2035
2036 .pollset_set_create = pollset_set_create,
2037 .pollset_set_destroy = pollset_set_destroy,
2038 .pollset_set_add_pollset = pollset_set_add_pollset,
2039 .pollset_set_del_pollset = pollset_set_del_pollset,
2040 .pollset_set_add_pollset_set = pollset_set_add_pollset_set,
2041 .pollset_set_del_pollset_set = pollset_set_del_pollset_set,
2042 .pollset_set_add_fd = pollset_set_add_fd,
2043 .pollset_set_del_fd = pollset_set_del_fd,
2044
2045 .kick_poller = kick_poller,
2046
Craig Tillerd8a3c042016-09-09 12:42:37 -07002047 .workqueue_ref = workqueue_ref,
2048 .workqueue_unref = workqueue_unref,
Craig Tiller91031da2016-12-28 15:44:25 -08002049 .workqueue_scheduler = workqueue_scheduler,
Craig Tillerd8a3c042016-09-09 12:42:37 -07002050
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002051 .shutdown_engine = shutdown_engine,
2052};
2053
Sree Kuchibhotla72744022016-06-09 09:42:06 -07002054/* It is possible that GLIBC has epoll but the underlying kernel doesn't.
2055 * Create a dummy epoll_fd to make sure epoll support is available */
2056static bool is_epoll_available() {
2057 int fd = epoll_create1(EPOLL_CLOEXEC);
2058 if (fd < 0) {
2059 gpr_log(
2060 GPR_ERROR,
2061 "epoll_create1 failed with error: %d. Not using epoll polling engine",
2062 fd);
2063 return false;
2064 }
2065 close(fd);
2066 return true;
2067}
2068
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002069const grpc_event_engine_vtable *grpc_init_epoll_linux(void) {
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07002070 /* If use of signals is disabled, we cannot use epoll engine*/
2071 if (is_grpc_wakeup_signal_initialized && grpc_wakeup_signal < 0) {
2072 return NULL;
2073 }
2074
Ken Paysoncd7d0472016-10-11 12:24:20 -07002075 if (!grpc_has_wakeup_fd()) {
Ken Paysonbc544be2016-10-06 19:23:47 -07002076 return NULL;
2077 }
2078
Sree Kuchibhotla72744022016-06-09 09:42:06 -07002079 if (!is_epoll_available()) {
2080 return NULL;
2081 }
2082
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07002083 if (!is_grpc_wakeup_signal_initialized) {
Sree Kuchibhotlabd48c912016-09-27 16:48:25 -07002084 grpc_use_signal(SIGRTMIN + 6);
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07002085 }
2086
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002087 fd_global_init();
Sree Kuchibhotla3131c262016-06-21 17:28:28 -07002088
2089 if (!GRPC_LOG_IF_ERROR("pollset_global_init", pollset_global_init())) {
2090 return NULL;
2091 }
2092
2093 if (!GRPC_LOG_IF_ERROR("polling_island_global_init",
2094 polling_island_global_init())) {
2095 return NULL;
2096 }
2097
Sree Kuchibhotlaf448c342016-05-19 10:51:24 -07002098 return &vtable;
2099}
2100
murgatroid99623dd4f2016-08-08 17:31:27 -07002101#else /* defined(GRPC_LINUX_EPOLL) */
2102#if defined(GRPC_POSIX_SOCKET)
Sree Kuchibhotla41622a82016-06-13 16:43:14 -07002103#include "src/core/lib/iomgr/ev_posix.h"
murgatroid99623dd4f2016-08-08 17:31:27 -07002104/* If GRPC_LINUX_EPOLL is not defined, it means epoll is not available. Return
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07002105 * NULL */
2106const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { return NULL; }
murgatroid99623dd4f2016-08-08 17:31:27 -07002107#endif /* defined(GRPC_POSIX_SOCKET) */
Sree Kuchibhotla5855c472016-06-08 12:56:56 -07002108
Sree Kuchibhotlac7be7c62016-06-09 17:08:50 -07002109void grpc_use_signal(int signum) {}
murgatroid99623dd4f2016-08-08 17:31:27 -07002110#endif /* !defined(GRPC_LINUX_EPOLL) */