Skip to content
Snippets Groups Projects
Commit 8e368451 authored by Sree Kuchibhotla's avatar Sree Kuchibhotla
Browse files

Fix Tsan failures

parent 60b282e6
No related branches found
No related tags found
No related merge requests found
...@@ -496,6 +496,10 @@ void check_tag_in_cq(grpc_completion_queue *cc, void *tag, bool lock_cq) { ...@@ -496,6 +496,10 @@ void check_tag_in_cq(grpc_completion_queue *cc, void *tag, bool lock_cq) {
void check_tag_in_cq(grpc_completion_queue *cc, void *tag, bool lock_cq) {} void check_tag_in_cq(grpc_completion_queue *cc, void *tag, bool lock_cq) {}
#endif #endif
/* Forward declaration */
static void cq_finish_shutdown(grpc_exec_ctx *exec_ctx,
grpc_completion_queue *cc);
/* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a completion /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a completion
* type of GRPC_CQ_NEXT) */ * type of GRPC_CQ_NEXT) */
void grpc_cq_end_op_for_next(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, void grpc_cq_end_op_for_next(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
...@@ -533,9 +537,9 @@ void grpc_cq_end_op_for_next(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, ...@@ -533,9 +537,9 @@ void grpc_cq_end_op_for_next(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1); gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1);
int shutdown = gpr_unref(&cqd->pending_events); int shutdown = gpr_unref(&cqd->pending_events);
if (!shutdown) {
gpr_mu_lock(cqd->mu);
gpr_mu_lock(cqd->mu);
if (!shutdown) {
grpc_error *kick_error = cc->poller_vtable->kick(POLLSET_FROM_CQ(cc), NULL); grpc_error *kick_error = cc->poller_vtable->kick(POLLSET_FROM_CQ(cc), NULL);
gpr_mu_unlock(cqd->mu); gpr_mu_unlock(cqd->mu);
...@@ -546,14 +550,7 @@ void grpc_cq_end_op_for_next(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc, ...@@ -546,14 +550,7 @@ void grpc_cq_end_op_for_next(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
GRPC_ERROR_UNREF(kick_error); GRPC_ERROR_UNREF(kick_error);
} }
} else { } else {
GPR_ASSERT(!gpr_atm_no_barrier_load(&cqd->shutdown)); cq_finish_shutdown(exec_ctx, cc);
GPR_ASSERT(cqd->shutdown_called);
gpr_atm_no_barrier_store(&cqd->shutdown, 1);
gpr_mu_lock(cqd->mu);
cc->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
&cqd->pollset_shutdown_done);
gpr_mu_unlock(cqd->mu); gpr_mu_unlock(cqd->mu);
} }
...@@ -624,11 +621,7 @@ void grpc_cq_end_op_for_pluck(grpc_exec_ctx *exec_ctx, ...@@ -624,11 +621,7 @@ void grpc_cq_end_op_for_pluck(grpc_exec_ctx *exec_ctx,
GRPC_ERROR_UNREF(kick_error); GRPC_ERROR_UNREF(kick_error);
} }
} else { } else {
GPR_ASSERT(!gpr_atm_no_barrier_load(&cqd->shutdown)); cq_finish_shutdown(exec_ctx, cc);
GPR_ASSERT(cqd->shutdown_called);
gpr_atm_no_barrier_store(&cqd->shutdown, 1);
cc->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
&cqd->pollset_shutdown_done);
gpr_mu_unlock(cqd->mu); gpr_mu_unlock(cqd->mu);
} }
...@@ -959,7 +952,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, ...@@ -959,7 +952,7 @@ grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
} }
prev = c; prev = c;
} }
if (cqd->shutdown) { if (gpr_atm_no_barrier_load(&cqd->shutdown)) {
gpr_mu_unlock(cqd->mu); gpr_mu_unlock(cqd->mu);
memset(&ret, 0, sizeof(ret)); memset(&ret, 0, sizeof(ret));
ret.type = GRPC_QUEUE_SHUTDOWN; ret.type = GRPC_QUEUE_SHUTDOWN;
...@@ -1026,6 +1019,24 @@ done: ...@@ -1026,6 +1019,24 @@ done:
return ret; return ret;
} }
/* Finishes the completion queue shutdown. This means that there are no more
completion events / tags expected from the completion queue
- Must be called under completion queue lock
- Must be called only once in completion queue's lifetime
- grpc_completion_queue_shutdown() MUST have been called before calling this
function */
static void cq_finish_shutdown(grpc_exec_ctx *exec_ctx,
grpc_completion_queue *cc) {
cq_data *cqd = &cc->data;
GPR_ASSERT(cqd->shutdown_called);
GPR_ASSERT(!gpr_atm_no_barrier_load(&cqd->shutdown));
gpr_atm_no_barrier_store(&cqd->shutdown, 1);
cc->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
&cqd->pollset_shutdown_done);
}
/* Shutdown simply drops a ref that we reserved at creation time; if we drop /* Shutdown simply drops a ref that we reserved at creation time; if we drop
to zero here, then enter shutdown mode and wake up any waiters */ to zero here, then enter shutdown mode and wake up any waiters */
void grpc_completion_queue_shutdown(grpc_completion_queue *cc) { void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
...@@ -1042,10 +1053,7 @@ void grpc_completion_queue_shutdown(grpc_completion_queue *cc) { ...@@ -1042,10 +1053,7 @@ void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
} }
cqd->shutdown_called = 1; cqd->shutdown_called = 1;
if (gpr_unref(&cqd->pending_events)) { if (gpr_unref(&cqd->pending_events)) {
GPR_ASSERT(!cqd->shutdown); cq_finish_shutdown(&exec_ctx, cc);
cqd->shutdown = 1;
cc->poller_vtable->shutdown(&exec_ctx, POLLSET_FROM_CQ(cc),
&cqd->pollset_shutdown_done);
} }
gpr_mu_unlock(cqd->mu); gpr_mu_unlock(cqd->mu);
grpc_exec_ctx_finish(&exec_ctx); grpc_exec_ctx_finish(&exec_ctx);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment