diff options
author | David Klempner <klempner@google.com> | 2015-02-24 17:33:05 -0800 |
---|---|---|
committer | David Klempner <klempner@google.com> | 2015-02-24 17:33:05 -0800 |
commit | c6bccc24d39cf651219e96e91ccc7767943272b8 (patch) | |
tree | 1386582589327f4dd59d4de9d760342be67c15ee | |
parent | b505661b1ae833154deebb689c2c1ba415bc1c11 (diff) |
Move close() to when the fd refcount goes to zero
Instead, we do a shutdown() at the point we are currently closing, to
kick off socket teardown while ensuring an fd ref is sufficient to make
concurrent syscalls like epoll_ctl safe.
-rw-r--r-- | src/core/iomgr/fd_posix.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c index 41fd24e05a..abdd49bbda 100644 --- a/src/core/iomgr/fd_posix.c +++ b/src/core/iomgr/fd_posix.c @@ -38,6 +38,7 @@ #include "src/core/iomgr/fd_posix.h" #include <assert.h> +#include <sys/socket.h> #include <unistd.h> #include "src/core/iomgr/iomgr_internal.h" @@ -113,6 +114,7 @@ static void ref_by(grpc_fd *fd, int n) { static void unref_by(grpc_fd *fd, int n) { gpr_atm 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); freelist_fd(fd); grpc_iomgr_unref(); @@ -158,9 +160,9 @@ static void wake_watchers(grpc_fd *fd) { void grpc_fd_orphan(grpc_fd *fd, grpc_iomgr_cb_func on_done, void *user_data) { 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 */ wake_watchers(fd); - close(fd->fd); unref_by(fd, 2); /* drop the reference */ } |