aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/surface
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-02-09 08:46:49 -0800
committerGravatar Craig Tiller <ctiller@google.com>2017-02-09 08:46:49 -0800
commit5e5ef30a0414c3dd1df95d4bb7ae274747f808bf (patch)
tree6b6400d53b3b89a05baa5b1d29e624f93b5ca8b1 /src/core/lib/surface
parent560371d8472b91cfe0423ad05252b86f868e5d9a (diff)
Add double-allocation protection
Diffstat (limited to 'src/core/lib/surface')
-rw-r--r--src/core/lib/surface/call.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 77ee6b7753..18509dadff 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -1016,13 +1016,20 @@ static batch_control *allocate_batch_control(grpc_call *call,
int op_slot = batch_slot_for_op(ops[i].op);
slot = GPR_MIN(slot, op_slot);
}
- return &call->active_batches[slot];
+ batch_control *bctl = &call->active_batches[slot];
+ if (bctl->call != NULL) {
+ return NULL;
+ }
+ memset(bctl, 0, sizeof(*bctl));
+ bctl->call = call;
+ return bctl;
}
static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_cq_completion *storage) {
batch_control *bctl = user_data;
grpc_call *call = bctl->call;
+ bctl->call = NULL;
GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion");
}
@@ -1351,8 +1358,9 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
/* TODO(ctiller): this feels like it could be made lock-free */
bctl = allocate_batch_control(call, ops, nops);
- memset(bctl, 0, sizeof(*bctl));
- bctl->call = call;
+ if (bctl == NULL) {
+ return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
+ }
bctl->notify_tag = notify_tag;
bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0);