ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
ctiller | 58393c2 | 2015-01-07 14:03:30 -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 |
ctiller | 58393c2 | 2015-01-07 14:03:30 -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 |
ctiller | 58393c2 | 2015-01-07 14:03:30 -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. |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 19 | #include "src/core/lib/iomgr/iomgr.h" |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 20 | |
| 21 | #include <stdlib.h> |
Craig Tiller | 131f6ed | 2015-09-15 08:20:20 -0700 | [diff] [blame] | 22 | #include <string.h> |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 23 | |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 24 | #include <grpc/support/alloc.h> |
| 25 | #include <grpc/support/log.h> |
Masood Malekghassemi | 701af60 | 2015-06-03 15:01:17 -0700 | [diff] [blame] | 26 | #include <grpc/support/string_util.h> |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 27 | #include <grpc/support/sync.h> |
Masood Malekghassemi | 701af60 | 2015-06-03 15:01:17 -0700 | [diff] [blame] | 28 | #include <grpc/support/thd.h> |
Craig Tiller | 0cb803d | 2016-03-02 22:17:24 -0800 | [diff] [blame] | 29 | #include <grpc/support/useful.h> |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 30 | |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 31 | #include "src/core/lib/iomgr/exec_ctx.h" |
Craig Tiller | b9b01ce | 2017-05-12 13:47:10 -0700 | [diff] [blame] | 32 | #include "src/core/lib/iomgr/executor.h" |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 33 | #include "src/core/lib/iomgr/iomgr_internal.h" |
Craig Tiller | f11b333 | 2016-07-14 16:48:23 -0700 | [diff] [blame] | 34 | #include "src/core/lib/iomgr/network_status_tracker.h" |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 35 | #include "src/core/lib/iomgr/timer.h" |
Craig Tiller | c357179 | 2017-05-02 12:33:38 -0700 | [diff] [blame] | 36 | #include "src/core/lib/iomgr/timer_manager.h" |
Craig Tiller | 9533d04 | 2016-03-25 17:11:06 -0700 | [diff] [blame] | 37 | #include "src/core/lib/support/env.h" |
| 38 | #include "src/core/lib/support/string.h" |
Craig Tiller | 131f6ed | 2015-09-15 08:20:20 -0700 | [diff] [blame] | 39 | |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 40 | static gpr_mu g_mu; |
Nicolas "Pixel" Noble | ae7b45a | 2015-02-04 03:28:34 +0100 | [diff] [blame] | 41 | static gpr_cv g_rcv; |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 42 | static int g_shutdown; |
Craig Tiller | fa275a9 | 2015-06-01 13:55:54 -0700 | [diff] [blame] | 43 | static grpc_iomgr_object g_root_object; |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 44 | |
Craig Tiller | 5e56f00 | 2017-05-16 15:02:50 -0700 | [diff] [blame] | 45 | void grpc_iomgr_init(grpc_exec_ctx *exec_ctx) { |
Craig Tiller | 994c262 | 2015-07-23 14:00:58 -0700 | [diff] [blame] | 46 | g_shutdown = 0; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 47 | gpr_mu_init(&g_mu); |
| 48 | gpr_cv_init(&g_rcv); |
Craig Tiller | ef1bf87 | 2016-02-28 17:37:33 -0800 | [diff] [blame] | 49 | grpc_exec_ctx_global_init(); |
Craig Tiller | 5e56f00 | 2017-05-16 15:02:50 -0700 | [diff] [blame] | 50 | grpc_executor_init(exec_ctx); |
David Garcia Quintas | f747bbc | 2015-10-04 23:09:47 -0700 | [diff] [blame] | 51 | grpc_timer_list_init(gpr_now(GPR_CLOCK_MONOTONIC)); |
Craig Tiller | fa275a9 | 2015-06-01 13:55:54 -0700 | [diff] [blame] | 52 | g_root_object.next = g_root_object.prev = &g_root_object; |
Yash Tibrewal | 533d118 | 2017-09-18 10:48:22 -0700 | [diff] [blame^] | 53 | g_root_object.name = (char *)"root"; |
Craig Tiller | f11b333 | 2016-07-14 16:48:23 -0700 | [diff] [blame] | 54 | grpc_network_status_init(); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 55 | grpc_iomgr_platform_init(); |
Craig Tiller | 84f75d4 | 2017-05-03 13:06:35 -0700 | [diff] [blame] | 56 | } |
| 57 | |
Craig Tiller | 5e56f00 | 2017-05-16 15:02:50 -0700 | [diff] [blame] | 58 | void grpc_iomgr_start(grpc_exec_ctx *exec_ctx) { grpc_timer_manager_init(); } |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 59 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 60 | static size_t count_objects(void) { |
Craig Tiller | fa275a9 | 2015-06-01 13:55:54 -0700 | [diff] [blame] | 61 | grpc_iomgr_object *obj; |
| 62 | size_t n = 0; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 63 | for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) { |
| 64 | n++; |
| 65 | } |
Craig Tiller | fa275a9 | 2015-06-01 13:55:54 -0700 | [diff] [blame] | 66 | return n; |
| 67 | } |
| 68 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 69 | static void dump_objects(const char *kind) { |
Craig Tiller | fa275a9 | 2015-06-01 13:55:54 -0700 | [diff] [blame] | 70 | grpc_iomgr_object *obj; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 71 | for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) { |
| 72 | gpr_log(GPR_DEBUG, "%s OBJECT: %s %p", kind, obj->name, obj); |
| 73 | } |
Craig Tiller | 49d03c8 | 2015-09-03 14:34:30 -0700 | [diff] [blame] | 74 | } |
| 75 | |
Craig Tiller | 3cf7922 | 2016-11-14 08:02:45 -0800 | [diff] [blame] | 76 | void grpc_iomgr_shutdown(grpc_exec_ctx *exec_ctx) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 77 | gpr_timespec shutdown_deadline = gpr_time_add( |
| 78 | gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN)); |
| 79 | gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 80 | |
Craig Tiller | c357179 | 2017-05-02 12:33:38 -0700 | [diff] [blame] | 81 | grpc_timer_manager_shutdown(); |
Craig Tiller | 01be53d | 2015-09-30 08:36:03 -0700 | [diff] [blame] | 82 | grpc_iomgr_platform_flush(); |
Craig Tiller | 5e56f00 | 2017-05-16 15:02:50 -0700 | [diff] [blame] | 83 | grpc_executor_shutdown(exec_ctx); |
Craig Tiller | 01be53d | 2015-09-30 08:36:03 -0700 | [diff] [blame] | 84 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 85 | gpr_mu_lock(&g_mu); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 86 | g_shutdown = 1; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 87 | while (g_root_object.next != &g_root_object) { |
| 88 | if (gpr_time_cmp( |
| 89 | gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), last_warning_time), |
| 90 | gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) { |
| 91 | if (g_root_object.next != &g_root_object) { |
Yuchen Zeng | 64c0e8d | 2016-06-10 11:19:51 -0700 | [diff] [blame] | 92 | gpr_log(GPR_DEBUG, |
| 93 | "Waiting for %" PRIuPTR " iomgr objects to be destroyed", |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 94 | count_objects()); |
| 95 | } |
| 96 | last_warning_time = gpr_now(GPR_CLOCK_REALTIME); |
Craig Tiller | 29f741f | 2015-05-29 12:29:43 -0700 | [diff] [blame] | 97 | } |
Craig Tiller | b2ef1cf | 2017-05-30 09:25:48 -0700 | [diff] [blame] | 98 | if (grpc_timer_check(exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC), NULL) == |
| 99 | GRPC_TIMERS_FIRED) { |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 100 | gpr_mu_unlock(&g_mu); |
Craig Tiller | 3cf7922 | 2016-11-14 08:02:45 -0800 | [diff] [blame] | 101 | grpc_exec_ctx_flush(exec_ctx); |
Craig Tiller | da81d1a | 2016-11-28 15:00:53 -0800 | [diff] [blame] | 102 | grpc_iomgr_platform_flush(); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 103 | gpr_mu_lock(&g_mu); |
| 104 | continue; |
| 105 | } |
| 106 | if (g_root_object.next != &g_root_object) { |
Craig Tiller | fc2636d | 2016-09-12 09:57:07 -0700 | [diff] [blame] | 107 | if (grpc_iomgr_abort_on_leaks()) { |
| 108 | gpr_log(GPR_DEBUG, "Failed to free %" PRIuPTR |
| 109 | " iomgr objects before shutdown deadline: " |
| 110 | "memory leaks are likely", |
| 111 | count_objects()); |
| 112 | dump_objects("LEAKED"); |
| 113 | abort(); |
| 114 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 115 | gpr_timespec short_deadline = gpr_time_add( |
| 116 | gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(100, GPR_TIMESPAN)); |
| 117 | if (gpr_cv_wait(&g_rcv, &g_mu, short_deadline)) { |
| 118 | if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > 0) { |
Craig Tiller | 6301038 | 2015-09-24 15:00:58 -0700 | [diff] [blame] | 119 | if (g_root_object.next != &g_root_object) { |
Yuchen Zeng | 64c0e8d | 2016-06-10 11:19:51 -0700 | [diff] [blame] | 120 | gpr_log(GPR_DEBUG, "Failed to free %" PRIuPTR |
| 121 | " iomgr objects before shutdown deadline: " |
| 122 | "memory leaks are likely", |
Craig Tiller | 6301038 | 2015-09-24 15:00:58 -0700 | [diff] [blame] | 123 | count_objects()); |
| 124 | dump_objects("LEAKED"); |
| 125 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 126 | break; |
| 127 | } |
| 128 | } |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 129 | } |
| 130 | } |
| 131 | gpr_mu_unlock(&g_mu); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 132 | |
Craig Tiller | 3cf7922 | 2016-11-14 08:02:45 -0800 | [diff] [blame] | 133 | grpc_timer_list_shutdown(exec_ctx); |
| 134 | grpc_exec_ctx_flush(exec_ctx); |
Craig Tiller | 8e0b08a | 2015-06-01 17:04:17 -0700 | [diff] [blame] | 135 | |
Craig Tiller | 62aef62 | 2015-09-21 21:27:54 -0700 | [diff] [blame] | 136 | /* ensure all threads have left g_mu */ |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 137 | gpr_mu_lock(&g_mu); |
| 138 | gpr_mu_unlock(&g_mu); |
Craig Tiller | 62aef62 | 2015-09-21 21:27:54 -0700 | [diff] [blame] | 139 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 140 | grpc_iomgr_platform_shutdown(); |
Craig Tiller | ef1bf87 | 2016-02-28 17:37:33 -0800 | [diff] [blame] | 141 | grpc_exec_ctx_global_shutdown(); |
Craig Tiller | f11b333 | 2016-07-14 16:48:23 -0700 | [diff] [blame] | 142 | grpc_network_status_shutdown(); |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 143 | gpr_mu_destroy(&g_mu); |
| 144 | gpr_cv_destroy(&g_rcv); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 145 | } |
| 146 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 147 | void grpc_iomgr_register_object(grpc_iomgr_object *obj, const char *name) { |
| 148 | obj->name = gpr_strdup(name); |
| 149 | gpr_mu_lock(&g_mu); |
Craig Tiller | fa275a9 | 2015-06-01 13:55:54 -0700 | [diff] [blame] | 150 | obj->next = &g_root_object; |
Craig Tiller | 49d03c8 | 2015-09-03 14:34:30 -0700 | [diff] [blame] | 151 | obj->prev = g_root_object.prev; |
Craig Tiller | fa275a9 | 2015-06-01 13:55:54 -0700 | [diff] [blame] | 152 | obj->next->prev = obj->prev->next = obj; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 153 | gpr_mu_unlock(&g_mu); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 154 | } |
| 155 | |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 156 | void grpc_iomgr_unregister_object(grpc_iomgr_object *obj) { |
| 157 | gpr_mu_lock(&g_mu); |
Craig Tiller | fa275a9 | 2015-06-01 13:55:54 -0700 | [diff] [blame] | 158 | obj->next->prev = obj->prev; |
| 159 | obj->prev->next = obj->next; |
Craig Tiller | a82950e | 2015-09-22 12:33:20 -0700 | [diff] [blame] | 160 | gpr_cv_signal(&g_rcv); |
| 161 | gpr_mu_unlock(&g_mu); |
| 162 | gpr_free(obj->name); |
ctiller | 58393c2 | 2015-01-07 14:03:30 -0800 | [diff] [blame] | 163 | } |
Craig Tiller | 0cb803d | 2016-03-02 22:17:24 -0800 | [diff] [blame] | 164 | |
| 165 | bool grpc_iomgr_abort_on_leaks(void) { |
| 166 | char *env = gpr_getenv("GRPC_ABORT_ON_LEAKS"); |
Yuchen Zeng | 6514a0d | 2017-08-25 14:09:47 -0700 | [diff] [blame] | 167 | bool should_we = gpr_is_true(env); |
Yuchen Zeng | 4a11ecc | 2017-08-25 14:10:30 -0700 | [diff] [blame] | 168 | gpr_free(env); |
Craig Tiller | a3b54cd | 2016-03-25 15:59:55 -0700 | [diff] [blame] | 169 | return should_we; |
Craig Tiller | 0cb803d | 2016-03-02 22:17:24 -0800 | [diff] [blame] | 170 | } |