Mark D. Roth | 74e03a2 | 2016-07-13 10:12:17 -0700 | [diff] [blame] | 1 | /* |
| 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 | |
Mark D. Roth | 7c2a58c | 2016-07-14 11:53:47 -0700 | [diff] [blame] | 34 | #include <string.h> |
| 35 | |
David Garcia Quintas | 6b11462 | 2016-07-27 14:49:53 -0700 | [diff] [blame] | 36 | #include <grpc/support/alloc.h> |
David Garcia Quintas | c79b065 | 2016-07-27 21:11:58 -0700 | [diff] [blame] | 37 | #include <grpc/support/log.h> |
Mark D. Roth | 7c2a58c | 2016-07-14 11:53:47 -0700 | [diff] [blame] | 38 | |
Mark D. Roth | 45015dc | 2016-07-15 08:48:25 -0700 | [diff] [blame] | 39 | #include "src/core/lib/channel/channel_args.h" |
Mark D. Roth | 74e03a2 | 2016-07-13 10:12:17 -0700 | [diff] [blame] | 40 | #include "src/core/lib/channel/handshaker.h" |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 41 | #include "src/core/lib/iomgr/timer.h" |
Mark D. Roth | 74e03a2 | 2016-07-13 10:12:17 -0700 | [diff] [blame] | 42 | |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 43 | // |
| 44 | // grpc_handshaker |
| 45 | // |
| 46 | |
Mark D. Roth | 27588bb | 2016-11-11 15:03:39 -0800 | [diff] [blame] | 47 | void grpc_handshaker_init(const grpc_handshaker_vtable* vtable, |
Mark D. Roth | 7c2a58c | 2016-07-14 11:53:47 -0700 | [diff] [blame] | 48 | grpc_handshaker* handshaker) { |
Mark D. Roth | 74e03a2 | 2016-07-13 10:12:17 -0700 | [diff] [blame] | 49 | handshaker->vtable = vtable; |
| 50 | } |
| 51 | |
Mark D. Roth | 887e218 | 2016-12-07 08:19:34 -0800 | [diff] [blame] | 52 | void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, |
| 53 | grpc_handshaker* handshaker) { |
Mark D. Roth | 74e03a2 | 2016-07-13 10:12:17 -0700 | [diff] [blame] | 54 | handshaker->vtable->destroy(exec_ctx, handshaker); |
| 55 | } |
| 56 | |
Mark D. Roth | 887e218 | 2016-12-07 08:19:34 -0800 | [diff] [blame] | 57 | void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 58 | grpc_handshaker* handshaker, grpc_error* why) { |
| 59 | handshaker->vtable->shutdown(exec_ctx, handshaker, why); |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 60 | } |
| 61 | |
Mark D. Roth | 887e218 | 2016-12-07 08:19:34 -0800 | [diff] [blame] | 62 | void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, |
| 63 | grpc_handshaker* handshaker, |
| 64 | grpc_tcp_server_acceptor* acceptor, |
| 65 | grpc_closure* on_handshake_done, |
| 66 | grpc_handshaker_args* args) { |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 67 | handshaker->vtable->do_handshake(exec_ctx, handshaker, acceptor, |
Mark D. Roth | 27588bb | 2016-11-11 15:03:39 -0800 | [diff] [blame] | 68 | on_handshake_done, args); |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 69 | } |
| 70 | |
| 71 | // |
| 72 | // grpc_handshake_manager |
| 73 | // |
| 74 | |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 75 | struct grpc_handshake_manager { |
| 76 | gpr_mu mu; |
| 77 | gpr_refcount refs; |
Mark D. Roth | f6a046e | 2016-12-02 13:15:42 -0800 | [diff] [blame] | 78 | bool shutdown; |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 79 | // An array of handshakers added via grpc_handshake_manager_add(). |
| 80 | size_t count; |
| 81 | grpc_handshaker** handshakers; |
| 82 | // The index of the handshaker to invoke next and closure to invoke it. |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 83 | size_t index; |
Mark D. Roth | 4b5cdb7 | 2016-11-14 11:37:36 -0800 | [diff] [blame] | 84 | grpc_closure call_next_handshaker; |
Mark D. Roth | 5682a52 | 2016-07-20 09:54:41 -0700 | [diff] [blame] | 85 | // The acceptor to call the handshakers with. |
Mark D. Roth | ac8df65 | 2016-07-21 07:25:24 -0700 | [diff] [blame] | 86 | grpc_tcp_server_acceptor* acceptor; |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 87 | // Deadline timer across all handshakers. |
| 88 | grpc_timer deadline_timer; |
Masood Malekghassemi | b5b4372 | 2017-01-05 15:07:26 -0800 | [diff] [blame] | 89 | grpc_closure on_timeout; |
Mark D. Roth | 45015dc | 2016-07-15 08:48:25 -0700 | [diff] [blame] | 90 | // The final callback and user_data to invoke after the last handshaker. |
Mark D. Roth | 4b5cdb7 | 2016-11-14 11:37:36 -0800 | [diff] [blame] | 91 | grpc_closure on_handshake_done; |
Mark D. Roth | 27588bb | 2016-11-11 15:03:39 -0800 | [diff] [blame] | 92 | void* user_data; |
Mark D. Roth | f9b56b9 | 2016-11-16 14:58:05 -0800 | [diff] [blame] | 93 | // Handshaker args. |
| 94 | grpc_handshaker_args args; |
yang-g | 6da1e85 | 2017-02-16 10:34:06 -0800 | [diff] [blame] | 95 | // Links to the previous and next managers in a list of all pending handshakes |
| 96 | // Used at server side only. |
| 97 | grpc_handshake_manager* prev; |
| 98 | grpc_handshake_manager* next; |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 99 | }; |
| 100 | |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 101 | grpc_handshake_manager* grpc_handshake_manager_create() { |
| 102 | grpc_handshake_manager* mgr = gpr_malloc(sizeof(grpc_handshake_manager)); |
| 103 | memset(mgr, 0, sizeof(*mgr)); |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 104 | gpr_mu_init(&mgr->mu); |
| 105 | gpr_ref_init(&mgr->refs, 1); |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 106 | return mgr; |
| 107 | } |
| 108 | |
yang-g | 6da1e85 | 2017-02-16 10:34:06 -0800 | [diff] [blame] | 109 | void grpc_handshake_manager_pending_list_add(grpc_handshake_manager** head, |
| 110 | grpc_handshake_manager* mgr) { |
| 111 | GPR_ASSERT(mgr->prev == NULL); |
| 112 | GPR_ASSERT(mgr->next == NULL); |
| 113 | mgr->next = *head; |
| 114 | if (*head) { |
| 115 | (*head)->prev = mgr; |
| 116 | } |
| 117 | *head = mgr; |
| 118 | } |
| 119 | |
| 120 | void grpc_handshake_manager_pending_list_remove(grpc_handshake_manager** head, |
| 121 | grpc_handshake_manager* mgr) { |
| 122 | if (mgr->next != NULL) { |
| 123 | mgr->next->prev = mgr->prev; |
| 124 | } |
| 125 | if (mgr->prev != NULL) { |
| 126 | mgr->prev->next = mgr->next; |
| 127 | } else { |
| 128 | GPR_ASSERT(*head == mgr); |
| 129 | *head = mgr->next; |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | void grpc_handshake_manager_pending_list_shutdown_all( |
| 134 | grpc_exec_ctx* exec_ctx, grpc_handshake_manager* head, grpc_error* why) { |
| 135 | while (head != NULL) { |
| 136 | grpc_handshake_manager_shutdown(exec_ctx, head, GRPC_ERROR_REF(why)); |
| 137 | head = head->next; |
| 138 | } |
| 139 | GRPC_ERROR_UNREF(why); |
| 140 | } |
| 141 | |
Mark D. Roth | ac8df65 | 2016-07-21 07:25:24 -0700 | [diff] [blame] | 142 | static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; } |
Mark D. Roth | 0b84add | 2016-07-20 10:08:48 -0700 | [diff] [blame] | 143 | |
Mark D. Roth | 39377e9 | 2016-07-25 11:21:09 -0700 | [diff] [blame] | 144 | void grpc_handshake_manager_add(grpc_handshake_manager* mgr, |
| 145 | grpc_handshaker* handshaker) { |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 146 | gpr_mu_lock(&mgr->mu); |
Mark D. Roth | 0b84add | 2016-07-20 10:08:48 -0700 | [diff] [blame] | 147 | // To avoid allocating memory for each handshaker we add, we double |
| 148 | // the number of elements every time we need more. |
| 149 | size_t realloc_count = 0; |
| 150 | if (mgr->count == 0) { |
| 151 | realloc_count = 2; |
| 152 | } else if (mgr->count >= 2 && is_power_of_2(mgr->count)) { |
| 153 | realloc_count = mgr->count * 2; |
| 154 | } |
| 155 | if (realloc_count > 0) { |
Mark D. Roth | ac8df65 | 2016-07-21 07:25:24 -0700 | [diff] [blame] | 156 | mgr->handshakers = |
| 157 | gpr_realloc(mgr->handshakers, realloc_count * sizeof(grpc_handshaker*)); |
Mark D. Roth | 0b84add | 2016-07-20 10:08:48 -0700 | [diff] [blame] | 158 | } |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 159 | mgr->handshakers[mgr->count++] = handshaker; |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 160 | gpr_mu_unlock(&mgr->mu); |
| 161 | } |
| 162 | |
| 163 | static void grpc_handshake_manager_unref(grpc_exec_ctx* exec_ctx, |
| 164 | grpc_handshake_manager* mgr) { |
| 165 | if (gpr_unref(&mgr->refs)) { |
| 166 | for (size_t i = 0; i < mgr->count; ++i) { |
| 167 | grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); |
| 168 | } |
| 169 | gpr_free(mgr->handshakers); |
| 170 | gpr_mu_destroy(&mgr->mu); |
| 171 | gpr_free(mgr); |
| 172 | } |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 173 | } |
| 174 | |
Mark D. Roth | 1d3b2cc | 2016-07-14 09:18:12 -0700 | [diff] [blame] | 175 | void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, |
| 176 | grpc_handshake_manager* mgr) { |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 177 | grpc_handshake_manager_unref(exec_ctx, mgr); |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 178 | } |
| 179 | |
Mark D. Roth | 1d3b2cc | 2016-07-14 09:18:12 -0700 | [diff] [blame] | 180 | void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 181 | grpc_handshake_manager* mgr, |
| 182 | grpc_error* why) { |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 183 | gpr_mu_lock(&mgr->mu); |
Mark D. Roth | a9bd943 | 2016-11-30 09:38:55 -0800 | [diff] [blame] | 184 | // Shutdown the handshaker that's currently in progress, if any. |
Mark D. Roth | f6a046e | 2016-12-02 13:15:42 -0800 | [diff] [blame] | 185 | if (!mgr->shutdown && mgr->index > 0) { |
| 186 | mgr->shutdown = true; |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 187 | grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[mgr->index - 1], |
| 188 | GRPC_ERROR_REF(why)); |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 189 | } |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 190 | gpr_mu_unlock(&mgr->mu); |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 191 | GRPC_ERROR_UNREF(why); |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 192 | } |
| 193 | |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 194 | // Helper function to call either the next handshaker or the |
| 195 | // on_handshake_done callback. |
Mark D. Roth | a9bd943 | 2016-11-30 09:38:55 -0800 | [diff] [blame] | 196 | // Returns true if we've scheduled the on_handshake_done callback. |
| 197 | static bool call_next_handshaker_locked(grpc_exec_ctx* exec_ctx, |
Mark D. Roth | 2ea37e9 | 2016-11-14 12:31:22 -0800 | [diff] [blame] | 198 | grpc_handshake_manager* mgr, |
Mark D. Roth | 2ea37e9 | 2016-11-14 12:31:22 -0800 | [diff] [blame] | 199 | grpc_error* error) { |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 200 | GPR_ASSERT(mgr->index <= mgr->count); |
Mark D. Roth | cc527cf | 2016-12-06 10:43:12 -0800 | [diff] [blame] | 201 | // If we got an error or we've been shut down or we're exiting early or |
| 202 | // we've finished the last handshaker, invoke the on_handshake_done |
| 203 | // callback. Otherwise, call the next handshaker. |
| 204 | if (error != GRPC_ERROR_NONE || mgr->shutdown || mgr->args.exit_early || |
| 205 | mgr->index == mgr->count) { |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 206 | // Cancel deadline timer, since we're invoking the on_handshake_done |
| 207 | // callback now. |
| 208 | grpc_timer_cancel(exec_ctx, &mgr->deadline_timer); |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 209 | grpc_closure_sched(exec_ctx, &mgr->on_handshake_done, error); |
Mark D. Roth | f6a046e | 2016-12-02 13:15:42 -0800 | [diff] [blame] | 210 | mgr->shutdown = true; |
| 211 | } else { |
| 212 | grpc_handshaker_do_handshake(exec_ctx, mgr->handshakers[mgr->index], |
| 213 | mgr->acceptor, &mgr->call_next_handshaker, |
| 214 | &mgr->args); |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 215 | } |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 216 | ++mgr->index; |
Mark D. Roth | f6a046e | 2016-12-02 13:15:42 -0800 | [diff] [blame] | 217 | return mgr->shutdown; |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | // A function used as the handshaker-done callback when chaining |
| 221 | // handshakers together. |
Mark D. Roth | 27588bb | 2016-11-11 15:03:39 -0800 | [diff] [blame] | 222 | static void call_next_handshaker(grpc_exec_ctx* exec_ctx, void* arg, |
| 223 | grpc_error* error) { |
Mark D. Roth | 4475694 | 2016-11-29 12:43:55 -0800 | [diff] [blame] | 224 | grpc_handshake_manager* mgr = arg; |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 225 | gpr_mu_lock(&mgr->mu); |
Mark D. Roth | a9bd943 | 2016-11-30 09:38:55 -0800 | [diff] [blame] | 226 | bool done = call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_REF(error)); |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 227 | gpr_mu_unlock(&mgr->mu); |
Mark D. Roth | a9bd943 | 2016-11-30 09:38:55 -0800 | [diff] [blame] | 228 | // If we're invoked the final callback, we won't be coming back |
| 229 | // to this function, so we can release our reference to the |
| 230 | // handshake manager. |
| 231 | if (done) { |
| 232 | grpc_handshake_manager_unref(exec_ctx, mgr); |
| 233 | } |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 234 | } |
| 235 | |
| 236 | // Callback invoked when deadline is exceeded. |
| 237 | static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) { |
| 238 | grpc_handshake_manager* mgr = arg; |
| 239 | if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled. |
Craig Tiller | cda759d | 2017-01-27 11:37:37 -0800 | [diff] [blame] | 240 | grpc_handshake_manager_shutdown(exec_ctx, mgr, |
| 241 | GRPC_ERROR_CREATE("Handshake timed out")); |
Mark D. Roth | a228e5f | 2016-07-22 09:02:15 -0700 | [diff] [blame] | 242 | } |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 243 | grpc_handshake_manager_unref(exec_ctx, mgr); |
Mark D. Roth | c05539f | 2016-07-14 09:12:51 -0700 | [diff] [blame] | 244 | } |
| 245 | |
Mark D. Roth | b3ce178 | 2016-07-20 09:25:25 -0700 | [diff] [blame] | 246 | void grpc_handshake_manager_do_handshake( |
| 247 | grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, |
Mark D. Roth | 27588bb | 2016-11-11 15:03:39 -0800 | [diff] [blame] | 248 | grpc_endpoint* endpoint, const grpc_channel_args* channel_args, |
Mark D. Roth | ac8df65 | 2016-07-21 07:25:24 -0700 | [diff] [blame] | 249 | gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, |
Mark D. Roth | 27588bb | 2016-11-11 15:03:39 -0800 | [diff] [blame] | 250 | grpc_iomgr_cb_func on_handshake_done, void* user_data) { |
Mark D. Roth | 30f698f | 2016-11-29 14:02:32 -0800 | [diff] [blame] | 251 | gpr_mu_lock(&mgr->mu); |
| 252 | GPR_ASSERT(mgr->index == 0); |
Mark D. Roth | f6a046e | 2016-12-02 13:15:42 -0800 | [diff] [blame] | 253 | GPR_ASSERT(!mgr->shutdown); |
Mark D. Roth | 27588bb | 2016-11-11 15:03:39 -0800 | [diff] [blame] | 254 | // Construct handshaker args. These will be passed through all |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 255 | // handshakers and eventually be freed by the on_handshake_done callback. |
Mark D. Roth | f9b56b9 | 2016-11-16 14:58:05 -0800 | [diff] [blame] | 256 | mgr->args.endpoint = endpoint; |
| 257 | mgr->args.args = grpc_channel_args_copy(channel_args); |
Mark D. Roth | 4475694 | 2016-11-29 12:43:55 -0800 | [diff] [blame] | 258 | mgr->args.user_data = user_data; |
Mark D. Roth | f9b56b9 | 2016-11-16 14:58:05 -0800 | [diff] [blame] | 259 | mgr->args.read_buffer = gpr_malloc(sizeof(*mgr->args.read_buffer)); |
| 260 | grpc_slice_buffer_init(mgr->args.read_buffer); |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 261 | // Initialize state needed for calling handshakers. |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 262 | mgr->acceptor = acceptor; |
Craig Tiller | 91031da | 2016-12-28 15:44:25 -0800 | [diff] [blame] | 263 | grpc_closure_init(&mgr->call_next_handshaker, call_next_handshaker, mgr, |
| 264 | grpc_schedule_on_exec_ctx); |
| 265 | grpc_closure_init(&mgr->on_handshake_done, on_handshake_done, &mgr->args, |
| 266 | grpc_schedule_on_exec_ctx); |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 267 | // Start deadline timer, which owns a ref. |
| 268 | gpr_ref(&mgr->refs); |
Masood Malekghassemi | b5b4372 | 2017-01-05 15:07:26 -0800 | [diff] [blame] | 269 | grpc_closure_init(&mgr->on_timeout, on_timeout, mgr, |
| 270 | grpc_schedule_on_exec_ctx); |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 271 | grpc_timer_init(exec_ctx, &mgr->deadline_timer, |
| 272 | gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), |
Masood Malekghassemi | b5b4372 | 2017-01-05 15:07:26 -0800 | [diff] [blame] | 273 | &mgr->on_timeout, gpr_now(GPR_CLOCK_MONOTONIC)); |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 274 | // Start first handshaker, which also owns a ref. |
| 275 | gpr_ref(&mgr->refs); |
Mark D. Roth | a9bd943 | 2016-11-30 09:38:55 -0800 | [diff] [blame] | 276 | bool done = call_next_handshaker_locked(exec_ctx, mgr, GRPC_ERROR_NONE); |
Mark D. Roth | b16c1e3 | 2016-11-14 12:08:13 -0800 | [diff] [blame] | 277 | gpr_mu_unlock(&mgr->mu); |
Mark D. Roth | a9bd943 | 2016-11-30 09:38:55 -0800 | [diff] [blame] | 278 | if (done) { |
| 279 | grpc_handshake_manager_unref(exec_ctx, mgr); |
| 280 | } |
Mark D. Roth | 74e03a2 | 2016-07-13 10:12:17 -0700 | [diff] [blame] | 281 | } |