Merge branch 'count-the-things' into we-dont-need-no-backup
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index ec31de2..8266b92 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -37,6 +37,7 @@
#include "src/core/iomgr/iomgr_internal.h"
#include "src/core/iomgr/alarm_internal.h"
+#include "src/core/support/string.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/thd.h>
@@ -54,8 +55,8 @@
static delayed_callback *g_cbs_head = NULL;
static delayed_callback *g_cbs_tail = NULL;
static int g_shutdown;
-static int g_refs;
static gpr_event g_background_callback_executor_done;
+static grpc_iomgr_object g_root_object;
/* Execute followup callbacks continuously.
Other threads may check in and help during pollset_work() */
@@ -96,40 +97,60 @@
gpr_mu_init(&g_mu);
gpr_cv_init(&g_rcv);
grpc_alarm_list_init(gpr_now());
- g_refs = 0;
+ g_root_object.next = g_root_object.prev = &g_root_object;
+ g_root_object.name = "root";
grpc_iomgr_platform_init();
gpr_event_init(&g_background_callback_executor_done);
gpr_thd_new(&id, background_callback_executor, NULL, NULL);
}
+static size_t count_objects(void) {
+ grpc_iomgr_object *obj;
+ size_t n = 0;
+ for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) {
+ n++;
+ }
+ return n;
+}
+
void grpc_iomgr_shutdown(void) {
delayed_callback *cb;
+ grpc_iomgr_object *obj;
gpr_timespec shutdown_deadline =
gpr_time_add(gpr_now(), gpr_time_from_seconds(10));
- grpc_alarm_list_shutdown();
-
gpr_mu_lock(&g_mu);
g_shutdown = 1;
- while (g_cbs_head != NULL || g_refs > 0) {
- if (g_cbs_head != NULL && g_refs > 0) {
- gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed and executing final callbacks", g_refs);
+ while (g_cbs_head != NULL || g_root_object.next != &g_root_object) {
+ if (g_cbs_head != NULL && g_root_object.next != &g_root_object) {
+ gpr_log(GPR_DEBUG,
+ "Waiting for %d iomgr objects to be destroyed and executing "
+ "final callbacks",
+ count_objects());
} else if (g_cbs_head != NULL) {
gpr_log(GPR_DEBUG, "Executing final iomgr callbacks");
} else {
- gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed", g_refs);
+ gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed",
+ count_objects());
}
- while (g_cbs_head) {
- cb = g_cbs_head;
- g_cbs_head = cb->next;
- if (!g_cbs_head) g_cbs_tail = NULL;
- gpr_mu_unlock(&g_mu);
+ if (g_cbs_head) {
+ do {
+ cb = g_cbs_head;
+ g_cbs_head = cb->next;
+ if (!g_cbs_head) g_cbs_tail = NULL;
+ gpr_mu_unlock(&g_mu);
- cb->cb(cb->cb_arg, 0);
- gpr_free(cb);
- gpr_mu_lock(&g_mu);
+ cb->cb(cb->cb_arg, 0);
+ gpr_free(cb);
+ gpr_mu_lock(&g_mu);
+ } while (g_cbs_head);
+ continue;
}
- if (g_refs) {
+ if (grpc_alarm_check(&g_mu, gpr_inf_future, NULL)) {
+ gpr_log(GPR_DEBUG, "got late alarm");
+ continue;
+ }
+ if (g_root_object.next != &g_root_object) {
int timeout = 0;
gpr_timespec short_deadline = gpr_time_add(gpr_now(),
gpr_time_from_millis(100));
@@ -143,7 +164,10 @@
gpr_log(GPR_DEBUG,
"Failed to free %d iomgr objects before shutdown deadline: "
"memory leaks are likely",
- g_refs);
+ count_objects());
+ for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) {
+ gpr_log(GPR_DEBUG, "LEAKED OBJECT: %s", obj->name);
+ }
break;
}
}
@@ -153,22 +177,28 @@
grpc_kick_poller();
gpr_event_wait(&g_background_callback_executor_done, gpr_inf_future);
+ grpc_alarm_list_shutdown();
+
grpc_iomgr_platform_shutdown();
gpr_mu_destroy(&g_mu);
gpr_cv_destroy(&g_rcv);
}
-void grpc_iomgr_ref(void) {
+void grpc_iomgr_register_object(grpc_iomgr_object *obj, const char *name) {
gpr_mu_lock(&g_mu);
- ++g_refs;
+ obj->name = gpr_strdup(name);
+ obj->next = &g_root_object;
+ obj->prev = obj->next->prev;
+ obj->next->prev = obj->prev->next = obj;
gpr_mu_unlock(&g_mu);
}
-void grpc_iomgr_unref(void) {
+void grpc_iomgr_unregister_object(grpc_iomgr_object *obj) {
gpr_mu_lock(&g_mu);
- if (0 == --g_refs) {
- gpr_cv_signal(&g_rcv);
- }
+ obj->next->prev = obj->prev;
+ obj->prev->next = obj->next;
+ gpr_free(obj->name);
+ gpr_cv_signal(&g_rcv);
gpr_mu_unlock(&g_mu);
}