|
|
|
@ -100,6 +100,7 @@ static grpc_fd *alloc_fd(int fd) { |
|
|
|
|
&r->inactive_watcher_root; |
|
|
|
|
r->freelist_next = NULL; |
|
|
|
|
r->read_watcher = r->write_watcher = NULL; |
|
|
|
|
r->on_done_closure = NULL; |
|
|
|
|
return r; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -138,9 +139,6 @@ static void unref_by(grpc_fd *fd, int n) { |
|
|
|
|
#endif |
|
|
|
|
old = gpr_atm_full_fetch_add(&fd->refst, -n); |
|
|
|
|
if (old == n) { |
|
|
|
|
if (fd->on_done_closure) { |
|
|
|
|
grpc_iomgr_add_callback(fd->on_done_closure); |
|
|
|
|
} |
|
|
|
|
grpc_iomgr_unregister_object(&fd->iomgr_object); |
|
|
|
|
freelist_fd(fd); |
|
|
|
|
} else { |
|
|
|
@ -199,13 +197,23 @@ static void wake_all_watchers_locked(grpc_fd *fd) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int has_watchers(grpc_fd *fd) { |
|
|
|
|
return fd->read_watcher != NULL || fd->write_watcher != NULL || fd->inactive_watcher_root.next != &fd->inactive_watcher_root; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void grpc_fd_orphan(grpc_fd *fd, grpc_iomgr_closure *on_done, |
|
|
|
|
const char *reason) { |
|
|
|
|
fd->on_done_closure = on_done; |
|
|
|
|
shutdown(fd->fd, SHUT_RDWR); |
|
|
|
|
REF_BY(fd, 1, reason); /* remove active status, but keep referenced */ |
|
|
|
|
gpr_mu_lock(&fd->watcher_mu); |
|
|
|
|
wake_all_watchers_locked(fd); |
|
|
|
|
if (!has_watchers(fd)) { |
|
|
|
|
if (fd->on_done_closure) { |
|
|
|
|
grpc_iomgr_add_callback(fd->on_done_closure); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
wake_all_watchers_locked(fd); |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&fd->watcher_mu); |
|
|
|
|
UNREF_BY(fd, 2, reason); /* drop the reference */ |
|
|
|
|
} |
|
|
|
@ -354,6 +362,13 @@ gpr_uint32 grpc_fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset, |
|
|
|
|
GRPC_FD_REF(fd, "poll"); |
|
|
|
|
|
|
|
|
|
gpr_mu_lock(&fd->watcher_mu); |
|
|
|
|
/* if we are shutdown, then don't add to the watcher set */ |
|
|
|
|
if (gpr_atm_no_barrier_load(&fd->shutdown)) { |
|
|
|
|
watcher->fd = NULL; |
|
|
|
|
watcher->pollset = NULL; |
|
|
|
|
gpr_mu_unlock(&fd->watcher_mu); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
/* if there is nobody polling for read, but we need to, then start doing so */ |
|
|
|
|
if (!fd->read_watcher && gpr_atm_acq_load(&fd->readst) > READY) { |
|
|
|
|
fd->read_watcher = watcher; |
|
|
|
@ -383,6 +398,10 @@ void grpc_fd_end_poll(grpc_fd_watcher *watcher, int got_read, int got_write) { |
|
|
|
|
int kick = 0; |
|
|
|
|
grpc_fd *fd = watcher->fd; |
|
|
|
|
|
|
|
|
|
if (fd == NULL) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
gpr_mu_lock(&fd->watcher_mu); |
|
|
|
|
if (watcher == fd->read_watcher) { |
|
|
|
|
/* remove read watcher, kick if we still need a read */ |
|
|
|
@ -404,6 +423,9 @@ void grpc_fd_end_poll(grpc_fd_watcher *watcher, int got_read, int got_write) { |
|
|
|
|
if (kick) { |
|
|
|
|
maybe_wake_one_watcher_locked(fd); |
|
|
|
|
} |
|
|
|
|
if (fd->on_done_closure != NULL && !has_watchers(fd)) { |
|
|
|
|
grpc_iomgr_add_callback(fd->on_done_closure); |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&fd->watcher_mu); |
|
|
|
|
|
|
|
|
|
GRPC_FD_UNREF(fd, "poll"); |
|
|
|
|