mirror of https://github.com/grpc/grpc-node.git
Merge pull request #10468 from murgatroid99/node_call_destruction_bug
Fix call destruction bug
This commit is contained in:
commit
836687cd26
20
ext/call.cc
20
ext/call.cc
|
@ -488,8 +488,10 @@ class ServerCloseResponseOp : public Op {
|
||||||
int cancelled;
|
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){
|
callback(callback), ops(ops), call(call){
|
||||||
|
HandleScope scope;
|
||||||
|
call_persist.Reset(call_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
tag::~tag() {
|
tag::~tag() {
|
||||||
|
@ -535,15 +537,20 @@ void DestroyTag(void *tag) {
|
||||||
delete tag_struct;
|
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),
|
Call::Call(grpc_call *call) : wrapped_call(call),
|
||||||
pending_batches(0),
|
pending_batches(0),
|
||||||
has_final_op_completed(false) {
|
has_final_op_completed(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Call::~Call() {
|
Call::~Call() {
|
||||||
if (wrapped_call != NULL) {
|
DestroyCall();
|
||||||
grpc_call_destroy(wrapped_call);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Call::Init(Local<Object> exports) {
|
void Call::Init(Local<Object> exports) {
|
||||||
|
@ -590,8 +597,7 @@ void Call::CompleteBatch(bool is_final_op) {
|
||||||
}
|
}
|
||||||
this->pending_batches--;
|
this->pending_batches--;
|
||||||
if (this->has_final_op_completed && this->pending_batches == 0) {
|
if (this->has_final_op_completed && this->pending_batches == 0) {
|
||||||
grpc_call_destroy(this->wrapped_call);
|
this->DestroyCall();
|
||||||
this->wrapped_call = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,7 +758,7 @@ NAN_METHOD(Call::StartBatch) {
|
||||||
Callback *callback = new Callback(callback_func);
|
Callback *callback = new Callback(callback_func);
|
||||||
grpc_call_error error = grpc_call_start_batch(
|
grpc_call_error error = grpc_call_start_batch(
|
||||||
call->wrapped_call, &ops[0], nops, new struct tag(
|
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) {
|
if (error != GRPC_CALL_OK) {
|
||||||
return Nan::ThrowError(nanErrorWithCode("startBatch failed", error));
|
return Nan::ThrowError(nanErrorWithCode("startBatch failed", error));
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,8 @@ class Call : public Nan::ObjectWrap {
|
||||||
Call(const Call &);
|
Call(const Call &);
|
||||||
Call &operator=(const Call &);
|
Call &operator=(const Call &);
|
||||||
|
|
||||||
|
void DestroyCall();
|
||||||
|
|
||||||
static NAN_METHOD(New);
|
static NAN_METHOD(New);
|
||||||
static NAN_METHOD(StartBatch);
|
static NAN_METHOD(StartBatch);
|
||||||
static NAN_METHOD(Cancel);
|
static NAN_METHOD(Cancel);
|
||||||
|
@ -111,11 +113,14 @@ class Op {
|
||||||
|
|
||||||
typedef std::vector<unique_ptr<Op>> OpVec;
|
typedef std::vector<unique_ptr<Op>> OpVec;
|
||||||
struct tag {
|
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();
|
~tag();
|
||||||
Nan::Callback *callback;
|
Nan::Callback *callback;
|
||||||
OpVec *ops;
|
OpVec *ops;
|
||||||
Call *call;
|
Call *call;
|
||||||
|
Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>>
|
||||||
|
call_persist;
|
||||||
};
|
};
|
||||||
|
|
||||||
v8::Local<v8::Value> GetTagNodeValue(void *tag);
|
v8::Local<v8::Value> GetTagNodeValue(void *tag);
|
||||||
|
|
|
@ -280,7 +280,7 @@ NAN_METHOD(Channel::WatchConnectivityState) {
|
||||||
channel->wrapped_channel, last_state, MillisecondsToTimespec(deadline),
|
channel->wrapped_channel, last_state, MillisecondsToTimespec(deadline),
|
||||||
GetCompletionQueue(),
|
GetCompletionQueue(),
|
||||||
new struct tag(callback,
|
new struct tag(callback,
|
||||||
ops.release(), NULL));
|
ops.release(), NULL, Nan::Null()));
|
||||||
CompletionQueueNext();
|
CompletionQueueNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ NAN_METHOD(Server::RequestCall) {
|
||||||
GetCompletionQueue(),
|
GetCompletionQueue(),
|
||||||
GetCompletionQueue(),
|
GetCompletionQueue(),
|
||||||
new struct tag(new Callback(info[0].As<Function>()), ops.release(),
|
new struct tag(new Callback(info[0].As<Function>()), ops.release(),
|
||||||
NULL));
|
NULL, Nan::Null()));
|
||||||
if (error != GRPC_CALL_OK) {
|
if (error != GRPC_CALL_OK) {
|
||||||
return Nan::ThrowError(nanErrorWithCode("requestCall failed", error));
|
return Nan::ThrowError(nanErrorWithCode("requestCall failed", error));
|
||||||
}
|
}
|
||||||
|
@ -246,7 +246,7 @@ NAN_METHOD(Server::TryShutdown) {
|
||||||
grpc_server_shutdown_and_notify(
|
grpc_server_shutdown_and_notify(
|
||||||
server->wrapped_server, GetCompletionQueue(),
|
server->wrapped_server, GetCompletionQueue(),
|
||||||
new struct tag(new Nan::Callback(info[0].As<Function>()), ops.release(),
|
new struct tag(new Nan::Callback(info[0].As<Function>()), ops.release(),
|
||||||
NULL));
|
NULL, Nan::Null()));
|
||||||
CompletionQueueNext();
|
CompletionQueueNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,8 @@ void Server::ShutdownServer() {
|
||||||
|
|
||||||
grpc_server_shutdown_and_notify(
|
grpc_server_shutdown_and_notify(
|
||||||
this->wrapped_server, GetCompletionQueue(),
|
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);
|
grpc_server_cancel_all_calls(this->wrapped_server);
|
||||||
CompletionQueueNext();
|
CompletionQueueNext();
|
||||||
this->wrapped_server = NULL;
|
this->wrapped_server = NULL;
|
||||||
|
|
Loading…
Reference in New Issue