fd refcount debugging
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 5a7180a..65dff84 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -109,12 +109,28 @@
gpr_free(fd);
}
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__)
+#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
+static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file, int line) {
+ gpr_log(GPR_DEBUG, "FD %d ref %d %d -> %d [%s; %s:%d]", fd->fd, n, fd->refst, fd->refst + n, reason, file, line);
+#else
+#define REF_BY(fd, n, reason) ref_by(fd, n)
+#define UNREF_BY(fd, n, reason) unref_by(fd, n)
static void ref_by(grpc_fd *fd, int n) {
+#endif
GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0);
}
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file, int line) {
+ gpr_atm old;
+ gpr_log(GPR_DEBUG, "FD %d unref %d %d -> %d [%s; %s:%d]", fd->fd, n, fd->refst, fd->refst - n, reason, file, line);
+#else
static void unref_by(grpc_fd *fd, int n) {
- gpr_atm old = gpr_atm_full_fetch_add(&fd->refst, -n);
+ gpr_atm old;
+#endif
+ old = gpr_atm_full_fetch_add(&fd->refst, -n);
if (old == n) {
close(fd->fd);
grpc_iomgr_add_callback(fd->on_done, fd->on_done_user_data);
@@ -182,17 +198,31 @@
fd->on_done = on_done ? on_done : do_nothing;
fd->on_done_user_data = user_data;
shutdown(fd->fd, SHUT_RDWR);
- ref_by(fd, 1); /* remove active status, but keep referenced */
+ REF_BY(fd, 1, "orphan"); /* remove active status, but keep referenced */
gpr_mu_lock(&fd->watcher_mu);
wake_all_watchers_locked(fd);
gpr_mu_unlock(&fd->watcher_mu);
- unref_by(fd, 2); /* drop the reference */
+ UNREF_BY(fd, 2, "orphan"); /* drop the reference */
}
/* increment refcount by two to avoid changing the orphan bit */
-void grpc_fd_ref(grpc_fd *fd) { ref_by(fd, 2); }
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+void grpc_fd_ref(grpc_fd *fd, const char *reason, const char *file, int line) {
+ ref_by(fd, 2, reason, file, line);
+}
-void grpc_fd_unref(grpc_fd *fd) { unref_by(fd, 2); }
+void grpc_fd_unref(grpc_fd *fd, const char *reason, const char *file, int line) {
+ unref_by(fd, 2, reason, file, line);
+}
+#else
+void grpc_fd_ref(grpc_fd *fd) {
+ ref_by(fd, 2);
+}
+
+void grpc_fd_unref(grpc_fd *fd) {
+ unref_by(fd, 2);
+}
+#endif
static void make_callback(grpc_iomgr_cb_func cb, void *arg, int success,
int allow_synchronous_callback) {
@@ -316,7 +346,7 @@
gpr_uint32 mask = 0;
/* keep track of pollers that have requested our events, in case they change
*/
- grpc_fd_ref(fd);
+ GRPC_FD_REF(fd, "poll");
gpr_mu_lock(&fd->watcher_mu);
/* if there is nobody polling for read, but we need to, then start doing so */
@@ -371,7 +401,7 @@
}
gpr_mu_unlock(&fd->watcher_mu);
- grpc_fd_unref(fd);
+ GRPC_FD_UNREF(fd, "poll");
}
void grpc_fd_become_readable(grpc_fd *fd, int allow_synchronous_callback) {