ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
murgatroid99 | 3466c4b | 2016-01-12 10:26:04 -0800 | [diff] [blame] | 3 | * Copyright 2015-2016, Google Inc. |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 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 | |
Craig Tiller | 9a4dddd | 2016-03-25 17:08:13 -0700 | [diff] [blame] | 34 | #ifndef GRPC_CORE_LIB_IOMGR_POLLSET_POSIX_H |
| 35 | #define GRPC_CORE_LIB_IOMGR_POLLSET_POSIX_H |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 36 | |
Craig Tiller | 69f90e6 | 2015-08-06 08:32:35 -0700 | [diff] [blame] | 37 | #include <poll.h> |
| 38 | |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 39 | #include <grpc/support/sync.h> |
Craig Tiller | 69b093b | 2016-02-25 19:04:07 -0800 | [diff] [blame] | 40 | |
Craig Tiller | 298751c | 2015-09-22 09:41:05 -0700 | [diff] [blame] | 41 | #include "src/core/iomgr/exec_ctx.h" |
Craig Tiller | 000cd8f | 2015-09-18 07:20:29 -0700 | [diff] [blame] | 42 | #include "src/core/iomgr/iomgr.h" |
Craig Tiller | 69b093b | 2016-02-25 19:04:07 -0800 | [diff] [blame] | 43 | #include "src/core/iomgr/pollset.h" |
Craig Tiller | 5ddbb9d | 2015-07-29 15:58:11 -0700 | [diff] [blame] | 44 | #include "src/core/iomgr/wakeup_fd_posix.h" |
David Klempner | 7f3ed1e | 2015-01-16 15:35:56 -0800 | [diff] [blame] | 45 | |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 46 | typedef struct grpc_pollset_vtable grpc_pollset_vtable; |
| 47 | |
| 48 | /* forward declare only in this file to avoid leaking impl details via |
| 49 | pollset.h; real users of grpc_fd should always include 'fd_posix.h' and not |
| 50 | use the struct tag */ |
| 51 | struct grpc_fd; |
| 52 | |
Craig Tiller | e8b5f62 | 2015-11-02 14:15:03 -0800 | [diff] [blame] | 53 | typedef struct grpc_cached_wakeup_fd { |
| 54 | grpc_wakeup_fd fd; |
| 55 | struct grpc_cached_wakeup_fd *next; |
| 56 | } grpc_cached_wakeup_fd; |
| 57 | |
Craig Tiller | 69b093b | 2016-02-25 19:04:07 -0800 | [diff] [blame] | 58 | struct grpc_pollset_worker { |
Craig Tiller | e8b5f62 | 2015-11-02 14:15:03 -0800 | [diff] [blame] | 59 | grpc_cached_wakeup_fd *wakeup_fd; |
Craig Tiller | 988e37f | 2015-10-01 07:53:56 -0700 | [diff] [blame] | 60 | int reevaluate_polling_on_wakeup; |
Craig Tiller | 66197ca | 2015-11-02 08:04:10 -0800 | [diff] [blame] | 61 | int kicked_specifically; |
Craig Tiller | 5ddbb9d | 2015-07-29 15:58:11 -0700 | [diff] [blame] | 62 | struct grpc_pollset_worker *next; |
| 63 | struct grpc_pollset_worker *prev; |
Craig Tiller | 69b093b | 2016-02-25 19:04:07 -0800 | [diff] [blame] | 64 | }; |
Craig Tiller | 5ddbb9d | 2015-07-29 15:58:11 -0700 | [diff] [blame] | 65 | |
Craig Tiller | 69b093b | 2016-02-25 19:04:07 -0800 | [diff] [blame] | 66 | struct grpc_pollset { |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 67 | /* pollsets under posix can mutate representation as fds are added and |
| 68 | removed. |
| 69 | For example, we may choose a poll() based implementation on linux for |
| 70 | few fds, and an epoll() based implementation for many fds */ |
| 71 | const grpc_pollset_vtable *vtable; |
Craig Tiller | 85371a2 | 2016-02-25 13:55:13 -0800 | [diff] [blame] | 72 | gpr_mu mu; |
Craig Tiller | 5ddbb9d | 2015-07-29 15:58:11 -0700 | [diff] [blame] | 73 | grpc_pollset_worker root_worker; |
David Klempner | b505661 | 2015-02-24 14:22:50 -0800 | [diff] [blame] | 74 | int in_flight_cbs; |
| 75 | int shutting_down; |
Jan Tattermusch | d6ca8b4 | 2015-06-10 15:58:39 -0700 | [diff] [blame] | 76 | int called_shutdown; |
Craig Tiller | 5ddbb9d | 2015-07-29 15:58:11 -0700 | [diff] [blame] | 77 | int kicked_without_pollers; |
Craig Tiller | d1bec03 | 2015-09-18 17:29:00 -0700 | [diff] [blame] | 78 | grpc_closure *shutdown_done; |
Craig Tiller | d9ccbbf | 2015-09-22 09:30:00 -0700 | [diff] [blame] | 79 | grpc_closure_list idle_jobs; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 80 | union { |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 81 | int fd; |
| 82 | void *ptr; |
| 83 | } data; |
Craig Tiller | e8b5f62 | 2015-11-02 14:15:03 -0800 | [diff] [blame] | 84 | /* Local cache of eventfds for workers */ |
| 85 | grpc_cached_wakeup_fd *local_wakeup_cache; |
Craig Tiller | 69b093b | 2016-02-25 19:04:07 -0800 | [diff] [blame] | 86 | }; |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 87 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 88 | struct grpc_pollset_vtable { |
| 89 | void (*add_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
| 90 | struct grpc_fd *fd, int and_unlock_pollset); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 91 | void (*maybe_work_and_unlock)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
| 92 | grpc_pollset_worker *worker, |
| 93 | gpr_timespec deadline, gpr_timespec now); |
| 94 | void (*finish_shutdown)(grpc_pollset *pollset); |
| 95 | void (*destroy)(grpc_pollset *pollset); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 96 | }; |
| 97 | |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 98 | /* Add an fd to a pollset */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 99 | void grpc_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
| 100 | struct grpc_fd *fd); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 101 | |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 102 | /* Returns the fd to listen on for kicks */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 103 | int grpc_kick_read_fd(grpc_pollset *p); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 104 | /* Call after polling has been kicked to leave the kicked state */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 105 | void grpc_kick_drain(grpc_pollset *p); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 106 | |
Craig Tiller | 6174b9a | 2015-06-18 08:13:05 -0700 | [diff] [blame] | 107 | /* Convert a timespec to milliseconds: |
Craig Tiller | 5ddbb9d | 2015-07-29 15:58:11 -0700 | [diff] [blame] | 108 | - very small or negative poll times are clamped to zero to do a |
Craig Tiller | 6174b9a | 2015-06-18 08:13:05 -0700 | [diff] [blame] | 109 | non-blocking poll (which becomes spin polling) |
| 110 | - other small values are rounded up to one millisecond |
Craig Tiller | 5ddbb9d | 2015-07-29 15:58:11 -0700 | [diff] [blame] | 111 | - longer than a millisecond polls are rounded up to the next nearest |
Craig Tiller | 6174b9a | 2015-06-18 08:13:05 -0700 | [diff] [blame] | 112 | millisecond to avoid spinning |
| 113 | - infinite timeouts are converted to -1 */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 114 | int grpc_poll_deadline_to_millis_timeout(gpr_timespec deadline, |
| 115 | gpr_timespec now); |
Craig Tiller | 6174b9a | 2015-06-18 08:13:05 -0700 | [diff] [blame] | 116 | |
Craig Tiller | 548735e | 2015-10-02 16:17:10 -0700 | [diff] [blame] | 117 | /* Allow kick to wakeup the currently polling worker */ |
Craig Tiller | 988e37f | 2015-10-01 07:53:56 -0700 | [diff] [blame] | 118 | #define GRPC_POLLSET_CAN_KICK_SELF 1 |
Craig Tiller | 548735e | 2015-10-02 16:17:10 -0700 | [diff] [blame] | 119 | /* Force the wakee to repoll when awoken */ |
Craig Tiller | 988e37f | 2015-10-01 07:53:56 -0700 | [diff] [blame] | 120 | #define GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP 2 |
Craig Tiller | 548735e | 2015-10-02 16:17:10 -0700 | [diff] [blame] | 121 | /* As per grpc_pollset_kick, with an extended set of flags (defined above) |
| 122 | -- mostly for fd_posix's use. */ |
Craig Tiller | d0a0000 | 2015-10-06 11:30:37 -0700 | [diff] [blame] | 123 | void grpc_pollset_kick_ext(grpc_pollset *p, |
| 124 | grpc_pollset_worker *specific_worker, |
Craig Tiller | 7536af0 | 2015-12-22 13:49:30 -0800 | [diff] [blame] | 125 | uint32_t flags); |
Craig Tiller | 988e37f | 2015-10-01 07:53:56 -0700 | [diff] [blame] | 126 | |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 127 | /* turn a pollset into a multipoller: platform specific */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 128 | typedef void (*grpc_platform_become_multipoller_type)(grpc_exec_ctx *exec_ctx, |
| 129 | grpc_pollset *pollset, |
| 130 | struct grpc_fd **fds, |
| 131 | size_t fd_count); |
Craig Tiller | 1a6f755 | 2015-05-29 13:56:44 -0700 | [diff] [blame] | 132 | extern grpc_platform_become_multipoller_type grpc_platform_become_multipoller; |
| 133 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 134 | void grpc_poll_become_multipoller(grpc_exec_ctx *exec_ctx, |
| 135 | grpc_pollset *pollset, struct grpc_fd **fds, |
| 136 | size_t fd_count); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 137 | |
Craig Tiller | e97c9b4 | 2015-07-30 14:10:03 -0700 | [diff] [blame] | 138 | /* Return 1 if the pollset has active threads in grpc_pollset_work (pollset must |
| 139 | * be locked) */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 140 | int grpc_pollset_has_workers(grpc_pollset *pollset); |
Craig Tiller | e97c9b4 | 2015-07-30 14:10:03 -0700 | [diff] [blame] | 141 | |
yang-g | 8fefe37 | 2016-01-07 16:24:55 -0800 | [diff] [blame] | 142 | void grpc_remove_fd_from_all_epoll_sets(int fd); |
| 143 | |
Craig Tiller | 69f90e6 | 2015-08-06 08:32:35 -0700 | [diff] [blame] | 144 | /* override to allow tests to hook poll() usage */ |
vjpai | cf4daeb | 2016-02-15 02:33:54 -0800 | [diff] [blame] | 145 | /* NOTE: Any changes to grpc_poll_function must take place when the gRPC |
| 146 | is certainly not doing any polling anywhere. |
| 147 | Otherwise, there might be a race between changing the variable and actually |
| 148 | doing a polling operation */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 149 | typedef int (*grpc_poll_function_type)(struct pollfd *, nfds_t, int); |
Craig Tiller | 69f90e6 | 2015-08-06 08:32:35 -0700 | [diff] [blame] | 150 | extern grpc_poll_function_type grpc_poll_function; |
Craig Tiller | 8afeec8 | 2015-09-28 17:03:34 -0700 | [diff] [blame] | 151 | extern grpc_wakeup_fd grpc_global_wakeup_fd; |
Craig Tiller | 69f90e6 | 2015-08-06 08:32:35 -0700 | [diff] [blame] | 152 | |
Craig Tiller | 9a4dddd | 2016-03-25 17:08:13 -0700 | [diff] [blame] | 153 | #endif /* GRPC_CORE_LIB_IOMGR_POLLSET_POSIX_H */ |