Skip to content

Commit

Permalink
Merge pull request #10468 from murgatroid99/node_call_destruction_bug
Browse files Browse the repository at this point in the history
Fix call destruction bug
  • Loading branch information
murgatroid99 authored Apr 7, 2017
2 parents a075688 + 2a4ea2d commit bbf4e5b
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 12 deletions.
20 changes: 13 additions & 7 deletions src/node/ext/call.cc
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,10 @@ class ServerCloseResponseOp : public Op {
int cancelled;
};

tag::tag(Callback *callback, OpVec *ops, Call *call) :
tag::tag(Callback *callback, OpVec *ops, Call *call, Local<Value> call_value) :
callback(callback), ops(ops), call(call){
HandleScope scope;
call_persist.Reset(call_value);
}

tag::~tag() {
Expand Down Expand Up @@ -535,15 +537,20 @@ void DestroyTag(void *tag) {
delete tag_struct;
}

void Call::DestroyCall() {
if (this->wrapped_call != NULL) {
grpc_call_destroy(this->wrapped_call);
this->wrapped_call = NULL;
}
}

Call::Call(grpc_call *call) : wrapped_call(call),
pending_batches(0),
has_final_op_completed(false) {
}

Call::~Call() {
if (wrapped_call != NULL) {
grpc_call_destroy(wrapped_call);
}
DestroyCall();
}

void Call::Init(Local<Object> exports) {
Expand Down Expand Up @@ -590,8 +597,7 @@ void Call::CompleteBatch(bool is_final_op) {
}
this->pending_batches--;
if (this->has_final_op_completed && this->pending_batches == 0) {
grpc_call_destroy(this->wrapped_call);
this->wrapped_call = NULL;
this->DestroyCall();
}
}

Expand Down Expand Up @@ -752,7 +758,7 @@ NAN_METHOD(Call::StartBatch) {
Callback *callback = new Callback(callback_func);
grpc_call_error error = grpc_call_start_batch(
call->wrapped_call, &ops[0], nops, new struct tag(
callback, op_vector.release(), call), NULL);
callback, op_vector.release(), call, info.This()), NULL);
if (error != GRPC_CALL_OK) {
return Nan::ThrowError(nanErrorWithCode("startBatch failed", error));
}
Expand Down
7 changes: 6 additions & 1 deletion src/node/ext/call.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class Call : public Nan::ObjectWrap {
Call(const Call &);
Call &operator=(const Call &);

void DestroyCall();

static NAN_METHOD(New);
static NAN_METHOD(StartBatch);
static NAN_METHOD(Cancel);
Expand Down Expand Up @@ -111,11 +113,14 @@ class Op {

typedef std::vector<unique_ptr<Op>> OpVec;
struct tag {
tag(Nan::Callback *callback, OpVec *ops, Call *call);
tag(Nan::Callback *callback, OpVec *ops, Call *call,
v8::Local<v8::Value> call_value);
~tag();
Nan::Callback *callback;
OpVec *ops;
Call *call;
Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>>
call_persist;
};

v8::Local<v8::Value> GetTagNodeValue(void *tag);
Expand Down
2 changes: 1 addition & 1 deletion src/node/ext/channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ NAN_METHOD(Channel::WatchConnectivityState) {
channel->wrapped_channel, last_state, MillisecondsToTimespec(deadline),
GetCompletionQueue(),
new struct tag(callback,
ops.release(), NULL));
ops.release(), NULL, Nan::Null()));
CompletionQueueNext();
}

Expand Down
4 changes: 2 additions & 2 deletions src/node/ext/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ NAN_METHOD(Server::RequestCall) {
GetCompletionQueue(),
GetCompletionQueue(),
new struct tag(new Callback(info[0].As<Function>()), ops.release(),
NULL));
NULL, Nan::Null()));
if (error != GRPC_CALL_OK) {
return Nan::ThrowError(nanErrorWithCode("requestCall failed", error));
}
Expand Down Expand Up @@ -246,7 +246,7 @@ NAN_METHOD(Server::TryShutdown) {
grpc_server_shutdown_and_notify(
server->wrapped_server, GetCompletionQueue(),
new struct tag(new Nan::Callback(info[0].As<Function>()), ops.release(),
NULL));
NULL, Nan::Null()));
CompletionQueueNext();
}

Expand Down
3 changes: 2 additions & 1 deletion src/node/ext/server_uv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ void Server::ShutdownServer() {

grpc_server_shutdown_and_notify(
this->wrapped_server, GetCompletionQueue(),
new struct tag(new Callback(**shutdown_callback), ops.release(), NULL));
new struct tag(new Callback(**shutdown_callback), ops.release(), NULL,
Nan::Null()));
grpc_server_cancel_all_calls(this->wrapped_server);
CompletionQueueNext();
this->wrapped_server = NULL;
Expand Down

0 comments on commit bbf4e5b

Please sign in to comment.