|
|
|
@ -265,7 +265,8 @@ static gpr_mu fd_freelist_mu; |
|
|
|
|
|
|
|
|
|
#ifdef GRPC_FD_REF_COUNT_DEBUG |
|
|
|
|
#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__) |
|
|
|
|
#define UNREF_BY(ec, fd, n, reason) unref_by(ec, fd, n, reason, __FILE__, __LINE__) |
|
|
|
|
#define UNREF_BY(ec, fd, n, reason) \ |
|
|
|
|
unref_by(ec, 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 %p ref %d %ld -> %ld [%s; %s:%d]", fd->fd, |
|
|
|
@ -280,23 +281,23 @@ static void ref_by(grpc_fd *fd, int n) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void fd_destroy(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { |
|
|
|
|
grpc_fd *fd = arg; |
|
|
|
|
/* Add the fd to the freelist */ |
|
|
|
|
grpc_iomgr_unregister_object(&fd->iomgr_object); |
|
|
|
|
pollable_destroy(&fd->pollable); |
|
|
|
|
gpr_mu_lock(&fd_freelist_mu); |
|
|
|
|
fd->freelist_next = fd_freelist; |
|
|
|
|
fd_freelist = fd; |
|
|
|
|
grpc_fd *fd = arg; |
|
|
|
|
/* Add the fd to the freelist */ |
|
|
|
|
grpc_iomgr_unregister_object(&fd->iomgr_object); |
|
|
|
|
pollable_destroy(&fd->pollable); |
|
|
|
|
gpr_mu_lock(&fd_freelist_mu); |
|
|
|
|
fd->freelist_next = fd_freelist; |
|
|
|
|
fd_freelist = fd; |
|
|
|
|
|
|
|
|
|
grpc_lfev_destroy(&fd->read_closure); |
|
|
|
|
grpc_lfev_destroy(&fd->write_closure); |
|
|
|
|
grpc_lfev_destroy(&fd->read_closure); |
|
|
|
|
grpc_lfev_destroy(&fd->write_closure); |
|
|
|
|
|
|
|
|
|
gpr_mu_unlock(&fd_freelist_mu); |
|
|
|
|
gpr_mu_unlock(&fd_freelist_mu); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef GRPC_FD_REF_COUNT_DEBUG |
|
|
|
|
static void unref_by(grpc_exec_ctx *exec_ctx, grpc_fd *fd, int n, const char *reason, const char *file, |
|
|
|
|
int line) { |
|
|
|
|
static void unref_by(grpc_exec_ctx *exec_ctx, grpc_fd *fd, int n, |
|
|
|
|
const char *reason, const char *file, int line) { |
|
|
|
|
gpr_atm old; |
|
|
|
|
gpr_log(GPR_DEBUG, "FD %d %p unref %d %ld -> %ld [%s; %s:%d]", fd->fd, |
|
|
|
|
(void *)fd, n, gpr_atm_no_barrier_load(&fd->refst), |
|
|
|
@ -307,7 +308,9 @@ static void unref_by(grpc_exec_ctx *exec_ctx, grpc_fd *fd, int n) { |
|
|
|
|
#endif |
|
|
|
|
old = gpr_atm_full_fetch_add(&fd->refst, -n); |
|
|
|
|
if (old == n) { |
|
|
|
|
grpc_closure_sched(exec_ctx, grpc_closure_create(fd_destroy, fd, grpc_schedule_on_exec_ctx), GRPC_ERROR_NONE); |
|
|
|
|
grpc_closure_sched(exec_ctx, grpc_closure_create(fd_destroy, fd, |
|
|
|
|
grpc_schedule_on_exec_ctx), |
|
|
|
|
GRPC_ERROR_NONE); |
|
|
|
|
} else { |
|
|
|
|
GPR_ASSERT(old > n); |
|
|
|
|
} |
|
|
|
@ -660,7 +663,8 @@ static grpc_error *pollset_kick_all(grpc_pollset *pollset) { |
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static grpc_error *pollset_kick_inner(grpc_pollset *pollset, pollable *p, grpc_pollset_worker *specific_worker) { |
|
|
|
|
static grpc_error *pollset_kick_inner(grpc_pollset *pollset, pollable *p, |
|
|
|
|
grpc_pollset_worker *specific_worker) { |
|
|
|
|
if (grpc_polling_trace) { |
|
|
|
|
gpr_log(GPR_DEBUG, |
|
|
|
|
"PS:%p kick %p tls_pollset=%p tls_worker=%p " |
|
|
|
@ -711,7 +715,6 @@ static grpc_error *pollset_kick_inner(grpc_pollset *pollset, pollable *p, grpc_p |
|
|
|
|
gpr_cv_signal(&specific_worker->cv); |
|
|
|
|
return GRPC_ERROR_NONE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* p->po.mu must be held before calling this function */ |
|
|
|
@ -816,7 +819,8 @@ static bool pollset_is_pollable_fd(grpc_pollset *pollset, pollable *p) { |
|
|
|
|
static void pollset_destroy(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) { |
|
|
|
|
pollable_destroy(&pollset->pollable); |
|
|
|
|
if (pollset_is_pollable_fd(pollset, pollset->current_pollable)) { |
|
|
|
|
UNREF_BY(exec_ctx, (grpc_fd *)pollset->current_pollable, 2, "pollset_pollable"); |
|
|
|
|
UNREF_BY(exec_ctx, (grpc_fd *)pollset->current_pollable, 2, |
|
|
|
|
"pollset_pollable"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -967,7 +971,8 @@ static bool begin_worker(grpc_pollset *pollset, grpc_pollset_worker *worker, |
|
|
|
|
return pollset->shutdown_closure == NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void end_worker(grpc_pollset *pollset, grpc_pollset_worker *worker, |
|
|
|
|
static void end_worker(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
grpc_pollset_worker *worker, |
|
|
|
|
grpc_pollset_worker **worker_hdl) { |
|
|
|
|
worker_remove(&pollset->root_worker, PWL_POLLSET, worker); |
|
|
|
|
if (NEW_ROOT == |
|
|
|
@ -1027,21 +1032,23 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
gpr_tls_set(&g_current_thread_worker, 0); |
|
|
|
|
pollset_maybe_finish_shutdown(exec_ctx, pollset); |
|
|
|
|
} |
|
|
|
|
end_worker(pollset, &worker, worker_hdl); |
|
|
|
|
end_worker(exec_ctx, pollset, &worker, worker_hdl); |
|
|
|
|
if (worker.pollable != &pollset->pollable) { |
|
|
|
|
gpr_mu_unlock(&worker.pollable->po.mu); |
|
|
|
|
} |
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void unref_fd_no_longer_poller(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { |
|
|
|
|
static void unref_fd_no_longer_poller(grpc_exec_ctx *exec_ctx, void *arg, |
|
|
|
|
grpc_error *error) { |
|
|
|
|
grpc_fd *fd = arg; |
|
|
|
|
UNREF_BY(exec_ctx, fd, 2, "pollset_pollable"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* expects pollsets locked, flag whether fd is locked or not */ |
|
|
|
|
static grpc_error *pollset_add_fd_locked(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, |
|
|
|
|
grpc_fd *fd, bool fd_locked) { |
|
|
|
|
static grpc_error *pollset_add_fd_locked(grpc_exec_ctx *exec_ctx, |
|
|
|
|
grpc_pollset *pollset, grpc_fd *fd, |
|
|
|
|
bool fd_locked) { |
|
|
|
|
static const char *err_desc = "pollset_add_fd"; |
|
|
|
|
grpc_error *error = GRPC_ERROR_NONE; |
|
|
|
|
if (pollset->current_pollable == &g_empty_pollable) { |
|
|
|
@ -1063,7 +1070,10 @@ static grpc_error *pollset_add_fd_locked(grpc_exec_ctx *exec_ctx, grpc_pollset * |
|
|
|
|
pollable_add_fd(&pollset->pollable, had_fd); |
|
|
|
|
pollable_add_fd(&pollset->pollable, fd); |
|
|
|
|
} |
|
|
|
|
grpc_closure_sched(exec_ctx, grpc_closure_create(unref_fd_no_longer_poller, had_fd, grpc_schedule_on_exec_ctx), GRPC_ERROR_NONE); |
|
|
|
|
grpc_closure_sched(exec_ctx, |
|
|
|
|
grpc_closure_create(unref_fd_no_longer_poller, had_fd, |
|
|
|
|
grpc_schedule_on_exec_ctx), |
|
|
|
|
GRPC_ERROR_NONE); |
|
|
|
|
} |
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
@ -1226,13 +1236,16 @@ static void pg_broadcast(grpc_exec_ctx *exec_ctx, polling_group *from, |
|
|
|
|
for (polling_obj *a = from->po.next; a != &from->po; a = a->next) { |
|
|
|
|
for (polling_obj *b = to->po.next; b != &to->po; b = b->next) { |
|
|
|
|
if (po_cmp(a, b) < 0) { |
|
|
|
|
gpr_mu_lock(&a->mu); gpr_mu_lock(&b->mu); |
|
|
|
|
gpr_mu_lock(&a->mu); |
|
|
|
|
gpr_mu_lock(&b->mu); |
|
|
|
|
} else { |
|
|
|
|
GPR_ASSERT(po_cmp(a, b) != 0); |
|
|
|
|
gpr_mu_lock(&b->mu); gpr_mu_lock(&a->mu); |
|
|
|
|
gpr_mu_lock(&b->mu); |
|
|
|
|
gpr_mu_lock(&a->mu); |
|
|
|
|
} |
|
|
|
|
pg_notify(exec_ctx, a, b); |
|
|
|
|
gpr_mu_unlock(&a->mu); gpr_mu_unlock(&b->mu); |
|
|
|
|
gpr_mu_unlock(&a->mu); |
|
|
|
|
gpr_mu_unlock(&b->mu); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|