aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormurgatroid99 <mlumish@google.com>2017-04-04 13:43:49 -0700
committermurgatroid99 <mlumish@google.com>2017-04-04 13:55:00 -0700
commit130568e5151ed468d8b40362272104c10aa6488e (patch)
tree18bc3d6d91b739d9bcea57134a322fe22a6a54c9
parent81ff57f1c380ca7c8a727241beec5f9e7183a3fa (diff)
downloadgrpc-grpc-130568e5151ed468d8b40362272104c10aa6488e.tar.gz
Fix call destruction bug
-rw-r--r--src/node/ext/call.cc10
-rw-r--r--src/node/ext/call.h5
-rw-r--r--src/node/ext/channel.cc2
-rw-r--r--src/node/ext/server.cc4
-rw-r--r--src/node/ext/server_uv.cc3
5 files changed, 16 insertions, 8 deletions
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index 244546d3d7..62f0130d53 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -466,8 +466,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() {
@@ -521,6 +523,7 @@ Call::Call(grpc_call *call) : wrapped_call(call),
Call::~Call() {
if (wrapped_call != NULL) {
grpc_call_destroy(wrapped_call);
+ wrapped_call = NULL;
}
}
@@ -567,7 +570,8 @@ void Call::CompleteBatch(bool is_final_op) {
this->has_final_op_completed = true;
}
this->pending_batches--;
- if (this->has_final_op_completed && this->pending_batches == 0) {
+ if (this->has_final_op_completed && this->pending_batches == 0 &&
+ this->wrapped_call != NULL) {
grpc_call_destroy(this->wrapped_call);
this->wrapped_call = NULL;
}
@@ -721,7 +725,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));
}
diff --git a/src/node/ext/call.h b/src/node/ext/call.h
index cffff00fce..cceec9c45b 100644
--- a/src/node/ext/call.h
+++ b/src/node/ext/call.h
@@ -109,11 +109,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);
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index c795ff7f42..1263cc0d28 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -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();
}
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index ccb55aa54c..f0920c842a 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -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));
}
@@ -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();
}
diff --git a/src/node/ext/server_uv.cc b/src/node/ext/server_uv.cc
index c5e5ca9f42..82e7589fc8 100644
--- a/src/node/ext/server_uv.cc
+++ b/src/node/ext/server_uv.cc
@@ -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;