Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2016 gRPC authors. |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 19 | #include "src/core/lib/surface/channel_init.h" |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 20 | |
| 21 | #include <grpc/support/alloc.h> |
| 22 | #include <grpc/support/useful.h> |
| 23 | |
| 24 | typedef struct stage_slot { |
| 25 | grpc_channel_init_stage fn; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 26 | void* arg; |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 27 | int priority; |
| 28 | size_t insertion_order; |
| 29 | } stage_slot; |
| 30 | |
| 31 | typedef struct stage_slots { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 32 | stage_slot* slots; |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 33 | size_t num_slots; |
| 34 | size_t cap_slots; |
| 35 | } stage_slots; |
| 36 | |
| 37 | static stage_slots g_slots[GRPC_NUM_CHANNEL_STACK_TYPES]; |
| 38 | static bool g_finalized; |
| 39 | |
| 40 | void grpc_channel_init_init(void) { |
| 41 | for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { |
Craig Tiller | 4782d92 | 2017-11-10 09:53:21 -0800 | [diff] [blame^] | 42 | g_slots[i].slots = nullptr; |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 43 | g_slots[i].num_slots = 0; |
| 44 | g_slots[i].cap_slots = 0; |
| 45 | } |
| 46 | g_finalized = false; |
| 47 | } |
| 48 | |
| 49 | void grpc_channel_init_register_stage(grpc_channel_stack_type type, |
| 50 | int priority, |
| 51 | grpc_channel_init_stage stage, |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 52 | void* stage_arg) { |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 53 | GPR_ASSERT(!g_finalized); |
| 54 | if (g_slots[type].cap_slots == g_slots[type].num_slots) { |
| 55 | g_slots[type].cap_slots = GPR_MAX(8, 3 * g_slots[type].cap_slots / 2); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 56 | g_slots[type].slots = (stage_slot*)gpr_realloc( |
Yash Tibrewal | ca3c1c0 | 2017-09-07 22:47:16 -0700 | [diff] [blame] | 57 | g_slots[type].slots, |
| 58 | g_slots[type].cap_slots * sizeof(*g_slots[type].slots)); |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 59 | } |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 60 | stage_slot* s = &g_slots[type].slots[g_slots[type].num_slots++]; |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 61 | s->insertion_order = g_slots[type].num_slots; |
| 62 | s->priority = priority; |
| 63 | s->fn = stage; |
| 64 | s->arg = stage_arg; |
| 65 | } |
| 66 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 67 | static int compare_slots(const void* a, const void* b) { |
| 68 | const stage_slot* sa = (const stage_slot*)a; |
| 69 | const stage_slot* sb = (const stage_slot*)b; |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 70 | |
| 71 | int c = GPR_ICMP(sa->priority, sb->priority); |
| 72 | if (c != 0) return c; |
| 73 | return GPR_ICMP(sa->insertion_order, sb->insertion_order); |
| 74 | } |
| 75 | |
| 76 | void grpc_channel_init_finalize(void) { |
| 77 | GPR_ASSERT(!g_finalized); |
| 78 | for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { |
| 79 | qsort(g_slots[i].slots, g_slots[i].num_slots, sizeof(*g_slots[i].slots), |
| 80 | compare_slots); |
| 81 | } |
| 82 | g_finalized = true; |
| 83 | } |
| 84 | |
| 85 | void grpc_channel_init_shutdown(void) { |
| 86 | for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) { |
| 87 | gpr_free(g_slots[i].slots); |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 88 | g_slots[i].slots = (stage_slot*)(void*)(uintptr_t)0xdeadbeef; |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 89 | } |
| 90 | } |
| 91 | |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 92 | bool grpc_channel_init_create_stack(grpc_exec_ctx* exec_ctx, |
| 93 | grpc_channel_stack_builder* builder, |
Craig Tiller | 839bebe | 2016-04-06 08:07:11 -0700 | [diff] [blame] | 94 | grpc_channel_stack_type type) { |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 95 | GPR_ASSERT(g_finalized); |
| 96 | |
Craig Tiller | 4f89b0b | 2017-04-03 10:00:17 -0700 | [diff] [blame] | 97 | grpc_channel_stack_builder_set_name(builder, |
| 98 | grpc_channel_stack_type_string(type)); |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 99 | |
| 100 | for (size_t i = 0; i < g_slots[type].num_slots; i++) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 101 | const stage_slot* slot = &g_slots[type].slots[i]; |
Craig Tiller | 87a7e1f | 2016-11-09 09:42:19 -0800 | [diff] [blame] | 102 | if (!slot->fn(exec_ctx, builder, slot->arg)) { |
Craig Tiller | 839bebe | 2016-04-06 08:07:11 -0700 | [diff] [blame] | 103 | return false; |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 104 | } |
| 105 | } |
| 106 | |
Craig Tiller | 839bebe | 2016-04-06 08:07:11 -0700 | [diff] [blame] | 107 | return true; |
Craig Tiller | 178edfa | 2016-02-17 20:54:46 -0800 | [diff] [blame] | 108 | } |