diff options
Diffstat (limited to 'src/node')
-rw-r--r-- | src/node/ext/byte_buffer.cc | 6 | ||||
-rw-r--r-- | src/node/ext/call.cc | 136 | ||||
-rw-r--r-- | src/node/ext/call.h | 17 | ||||
-rw-r--r-- | src/node/ext/call_credentials.cc | 15 | ||||
-rw-r--r-- | src/node/ext/call_credentials.h | 4 | ||||
-rw-r--r-- | src/node/ext/channel.cc | 3 | ||||
-rw-r--r-- | src/node/ext/node_grpc.cc | 30 | ||||
-rw-r--r-- | src/node/ext/server.cc | 19 | ||||
-rw-r--r-- | src/node/ext/slice.cc | 102 | ||||
-rw-r--r-- | src/node/ext/slice.h | 52 |
10 files changed, 141 insertions, 243 deletions
diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc index 7d6fb19860..fc339fc462 100644 --- a/src/node/ext/byte_buffer.cc +++ b/src/node/ext/byte_buffer.cc @@ -40,7 +40,6 @@ #include "grpc/slice.h" #include "byte_buffer.h" -#include "slice.h" namespace grpc { namespace node { @@ -55,7 +54,10 @@ using v8::Value; grpc_byte_buffer *BufferToByteBuffer(Local<Value> buffer) { Nan::HandleScope scope; - grpc_slice slice = CreateSliceFromBuffer(buffer); + int length = ::node::Buffer::Length(buffer); + char *data = ::node::Buffer::Data(buffer); + grpc_slice slice = grpc_slice_malloc(length); + memcpy(GRPC_SLICE_START_PTR(slice), data, length); grpc_byte_buffer *byte_buffer(grpc_raw_byte_buffer_create(&slice, 1)); grpc_slice_unref(slice); return byte_buffer; diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index 9213d5e87d..96f66a48d2 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -48,7 +48,6 @@ #include "completion_queue.h" #include "completion_queue_async_worker.h" #include "call_credentials.h" -#include "slice.h" #include "timeval.h" using std::unique_ptr; @@ -97,7 +96,8 @@ Local<Value> nanErrorWithCode(const char *msg, grpc_call_error code) { return scope.Escape(err); } -bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array) { +bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array, + shared_ptr<Resources> resources) { HandleScope scope; grpc_metadata_array_init(array); Local<Array> keys = Nan::GetOwnPropertyNames(metadata).ToLocalChecked(); @@ -113,25 +113,32 @@ bool CreateMetadataArray(Local<Object> metadata, grpc_metadata_array *array) { array->metadata = reinterpret_cast<grpc_metadata*>( gpr_malloc(array->capacity * sizeof(grpc_metadata))); for (unsigned int i = 0; i < keys->Length(); i++) { - Local<String> current_key(Nan::To<String>(keys->Get(i)).ToLocalChecked()); + Local<String> current_key(keys->Get(i)->ToString()); + Utf8String *utf8_key = new Utf8String(current_key); + resources->strings.push_back(unique_ptr<Utf8String>(utf8_key)); Local<Array> values = Local<Array>::Cast( Nan::Get(metadata, current_key).ToLocalChecked()); - grpc_slice key_slice = grpc_slice_intern(CreateSliceFromString(current_key)); for (unsigned int j = 0; j < values->Length(); j++) { Local<Value> value = Nan::Get(values, j).ToLocalChecked(); grpc_metadata *current = &array->metadata[array->count]; - current->key = key_slice; + current->key = **utf8_key; // Only allow binary headers for "-bin" keys - if (grpc_is_binary_header(key_slice)) { + if (grpc_is_binary_header(current->key, strlen(current->key))) { if (::node::Buffer::HasInstance(value)) { - current->value = CreateSliceFromBuffer(value); + current->value = ::node::Buffer::Data(value); + current->value_length = ::node::Buffer::Length(value); + PersistentValue *handle = new PersistentValue(value); + resources->handles.push_back(unique_ptr<PersistentValue>(handle)); } else { return false; } } else { if (value->IsString()) { Local<String> string_value = Nan::To<String>(value).ToLocalChecked(); - current->value = CreateSliceFromString(string_value); + Utf8String *utf8_value = new Utf8String(string_value); + resources->strings.push_back(unique_ptr<Utf8String>(utf8_value)); + current->value = **utf8_value; + current->value_length = string_value->Length(); } else { return false; } @@ -146,25 +153,40 @@ Local<Value> ParseMetadata(const grpc_metadata_array *metadata_array) { EscapableHandleScope scope; grpc_metadata *metadata_elements = metadata_array->metadata; size_t length = metadata_array->count; + std::map<const char*, size_t> size_map; + std::map<const char*, size_t> index_map; + + for (unsigned int i = 0; i < length; i++) { + const char *key = metadata_elements[i].key; + if (size_map.count(key)) { + size_map[key] += 1; + } else { + size_map[key] = 1; + } + index_map[key] = 0; + } Local<Object> metadata_object = Nan::New<Object>(); for (unsigned int i = 0; i < length; i++) { grpc_metadata* elem = &metadata_elements[i]; - // TODO(murgatroid99): Use zero-copy string construction instead - Local<String> key_string = CopyStringFromSlice(elem->key); + Local<String> key_string = Nan::New(elem->key).ToLocalChecked(); Local<Array> array; MaybeLocal<Value> maybe_array = Nan::Get(metadata_object, key_string); if (maybe_array.IsEmpty() || !maybe_array.ToLocalChecked()->IsArray()) { - array = Nan::New<Array>(0); + array = Nan::New<Array>(size_map[elem->key]); Nan::Set(metadata_object, key_string, array); } else { array = Local<Array>::Cast(maybe_array.ToLocalChecked()); } - if (grpc_is_binary_header(elem->key)) { - Nan::Set(array, array->Length(), CreateBufferFromSlice(elem->value)); + if (grpc_is_binary_header(elem->key, strlen(elem->key))) { + Nan::Set(array, index_map[elem->key], + MakeFastBuffer( + Nan::CopyBuffer(elem->value, + elem->value_length).ToLocalChecked())); } else { - // TODO(murgatroid99): Use zero-copy string construction instead - Nan::Set(array, array->Length(), CopyStringFromSlice(elem->value)); + Nan::Set(array, index_map[elem->key], + Nan::New(elem->value).ToLocalChecked()); } + index_map[elem->key] += 1; } return scope.Escape(metadata_object); } @@ -183,7 +205,8 @@ class SendMetadataOp : public Op { EscapableHandleScope scope; return scope.Escape(Nan::True()); } - bool ParseOp(Local<Value> value, grpc_op *out) { + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { if (!value->IsObject()) { return false; } @@ -193,7 +216,7 @@ class SendMetadataOp : public Op { return false; } if (!CreateMetadataArray(maybe_metadata.ToLocalChecked(), - &array)) { + &array, resources)) { return false; } out->data.send_initial_metadata.count = array.count; @@ -223,7 +246,8 @@ class SendMessageOp : public Op { EscapableHandleScope scope; return scope.Escape(Nan::True()); } - bool ParseOp(Local<Value> value, grpc_op *out) { + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { if (!::node::Buffer::HasInstance(value)) { return false; } @@ -238,7 +262,9 @@ class SendMessageOp : public Op { } } send_message = BufferToByteBuffer(value); - out->data.send_message = send_message; + out->data.send_message.send_message = send_message; + PersistentValue *handle = new PersistentValue(value); + resources->handles.push_back(unique_ptr<PersistentValue>(handle)); return true; } bool IsFinalOp() { @@ -258,7 +284,8 @@ class SendClientCloseOp : public Op { EscapableHandleScope scope; return scope.Escape(Nan::True()); } - bool ParseOp(Local<Value> value, grpc_op *out) { + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { return true; } bool IsFinalOp() { @@ -272,14 +299,12 @@ class SendClientCloseOp : public Op { class SendServerStatusOp : public Op { public: - ~SendServerStatusOp() { - grpc_slice_unref(details); - } Local<Value> GetNodeValue() const { EscapableHandleScope scope; return scope.Escape(Nan::True()); } - bool ParseOp(Local<Value> value, grpc_op *out) { + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { if (!value->IsObject()) { return false; } @@ -314,15 +339,16 @@ class SendServerStatusOp : public Op { Local<String> details = Nan::To<String>( maybe_details.ToLocalChecked()).ToLocalChecked(); grpc_metadata_array array; - if (!CreateMetadataArray(metadata, &array)) { + if (!CreateMetadataArray(metadata, &array, resources)) { return false; } out->data.send_status_from_server.trailing_metadata_count = array.count; out->data.send_status_from_server.trailing_metadata = array.metadata; out->data.send_status_from_server.status = static_cast<grpc_status_code>(code); - this->details = CreateSliceFromString(details); - out->data.send_status_from_server.status_details = &this->details; + Utf8String *str = new Utf8String(details); + resources->strings.push_back(unique_ptr<Utf8String>(str)); + out->data.send_status_from_server.status_details = **str; return true; } bool IsFinalOp() { @@ -332,9 +358,6 @@ class SendServerStatusOp : public Op { std::string GetTypeString() const { return "send_status"; } - - private: - grpc_slice details; }; class GetMetadataOp : public Op { @@ -352,8 +375,9 @@ class GetMetadataOp : public Op { return scope.Escape(ParseMetadata(&recv_metadata)); } - bool ParseOp(Local<Value> value, grpc_op *out) { - out->data.recv_initial_metadata = &recv_metadata; + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { + out->data.recv_initial_metadata.recv_initial_metadata = &recv_metadata; return true; } bool IsFinalOp() { @@ -384,8 +408,9 @@ class ReadMessageOp : public Op { return scope.Escape(ByteBufferToBuffer(recv_message)); } - bool ParseOp(Local<Value> value, grpc_op *out) { - out->data.recv_message = &recv_message; + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { + out->data.recv_message.recv_message = &recv_message; return true; } bool IsFinalOp() { @@ -405,16 +430,21 @@ class ClientStatusOp : public Op { public: ClientStatusOp() { grpc_metadata_array_init(&metadata_array); + status_details = NULL; + details_capacity = 0; } ~ClientStatusOp() { grpc_metadata_array_destroy(&metadata_array); + gpr_free(status_details); } - bool ParseOp(Local<Value> value, grpc_op *out) { + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { out->data.recv_status_on_client.trailing_metadata = &metadata_array; out->data.recv_status_on_client.status = &status; out->data.recv_status_on_client.status_details = &status_details; + out->data.recv_status_on_client.status_details_capacity = &details_capacity; return true; } @@ -423,8 +453,10 @@ class ClientStatusOp : public Op { Local<Object> status_obj = Nan::New<Object>(); Nan::Set(status_obj, Nan::New("code").ToLocalChecked(), Nan::New<Number>(status)); - Nan::Set(status_obj, Nan::New("details").ToLocalChecked(), - CopyStringFromSlice(status_details)); + if (status_details != NULL) { + Nan::Set(status_obj, Nan::New("details").ToLocalChecked(), + Nan::New(status_details).ToLocalChecked()); + } Nan::Set(status_obj, Nan::New("metadata").ToLocalChecked(), ParseMetadata(&metadata_array)); return scope.Escape(status_obj); @@ -439,7 +471,8 @@ class ClientStatusOp : public Op { private: grpc_metadata_array metadata_array; grpc_status_code status; - grpc_slice status_details; + char *status_details; + size_t details_capacity; }; class ServerCloseResponseOp : public Op { @@ -449,7 +482,8 @@ class ServerCloseResponseOp : public Op { return scope.Escape(Nan::New<Boolean>(cancelled)); } - bool ParseOp(Local<Value> value, grpc_op *out) { + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { out->data.recv_close_on_server.cancelled = &cancelled; return true; } @@ -466,8 +500,9 @@ class ServerCloseResponseOp : public Op { int cancelled; }; -tag::tag(Callback *callback, OpVec *ops, Call *call) : - callback(callback), ops(ops), call(call){ +tag::tag(Callback *callback, OpVec *ops, + shared_ptr<Resources> resources, Call *call) : + callback(callback), ops(ops), resources(resources), call(call){ } tag::~tag() { @@ -615,24 +650,20 @@ NAN_METHOD(Call::New) { if (channel->GetWrappedChannel() == NULL) { return Nan::ThrowError("Call cannot be created from a closed channel"); } + Utf8String method(info[1]); double deadline = Nan::To<double>(info[2]).FromJust(); grpc_channel *wrapped_channel = channel->GetWrappedChannel(); grpc_call *wrapped_call; if (info[3]->IsString()) { - grpc_slice *host = new grpc_slice; - *host = CreateSliceFromString( - Nan::To<String>(info[3]).ToLocalChecked()); + Utf8String host_override(info[3]); wrapped_call = grpc_channel_create_call( wrapped_channel, parent_call, propagate_flags, - GetCompletionQueue(), CreateSliceFromString( - Nan::To<String>(info[1]).ToLocalChecked()), - host, MillisecondsToTimespec(deadline), NULL); - delete host; + GetCompletionQueue(), *method, + *host_override, MillisecondsToTimespec(deadline), NULL); } else if (info[3]->IsUndefined() || info[3]->IsNull()) { wrapped_call = grpc_channel_create_call( wrapped_channel, parent_call, propagate_flags, - GetCompletionQueue(), CreateSliceFromString( - Nan::To<String>(info[1]).ToLocalChecked()), + GetCompletionQueue(), *method, NULL, MillisecondsToTimespec(deadline), NULL); } else { return Nan::ThrowTypeError("Call's fourth argument must be a string"); @@ -669,6 +700,7 @@ NAN_METHOD(Call::StartBatch) { } Local<Function> callback_func = info[1].As<Function>(); Call *call = ObjectWrap::Unwrap<Call>(info.This()); + shared_ptr<Resources> resources(new Resources); Local<Object> obj = Nan::To<Object>(info[0]).ToLocalChecked(); Local<Array> keys = Nan::GetOwnPropertyNames(obj).ToLocalChecked(); size_t nops = keys->Length(); @@ -713,7 +745,7 @@ NAN_METHOD(Call::StartBatch) { default: return Nan::ThrowError("Argument object had an unrecognized key"); } - if (!op->ParseOp(obj->Get(type), &ops[i])) { + if (!op->ParseOp(obj->Get(type), &ops[i], resources)) { return Nan::ThrowTypeError("Incorrectly typed arguments to startBatch"); } op_vector->push_back(std::move(op)); @@ -721,7 +753,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(), resources, call), 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..31c6566d14 100644 --- a/src/node/ext/call.h +++ b/src/node/ext/call.h @@ -51,12 +51,20 @@ namespace node { using std::unique_ptr; using std::shared_ptr; +typedef Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>> PersistentValue; + v8::Local<v8::Value> nanErrorWithCode(const char *msg, grpc_call_error code); v8::Local<v8::Value> ParseMetadata(const grpc_metadata_array *metadata_array); +struct Resources { + std::vector<unique_ptr<Nan::Utf8String> > strings; + std::vector<unique_ptr<PersistentValue> > handles; +}; + bool CreateMetadataArray(v8::Local<v8::Object> metadata, - grpc_metadata_array *array); + grpc_metadata_array *array, + shared_ptr<Resources> resources); /* Wrapper class for grpc_call structs. */ class Call : public Nan::ObjectWrap { @@ -98,7 +106,8 @@ class Call : public Nan::ObjectWrap { class Op { public: virtual v8::Local<v8::Value> GetNodeValue() const = 0; - virtual bool ParseOp(v8::Local<v8::Value> value, grpc_op *out) = 0; + virtual bool ParseOp(v8::Local<v8::Value> value, grpc_op *out, + shared_ptr<Resources> resources) = 0; virtual ~Op(); v8::Local<v8::Value> GetOpType() const; virtual bool IsFinalOp() = 0; @@ -109,10 +118,12 @@ 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, + shared_ptr<Resources> resources, Call *call); ~tag(); Nan::Callback *callback; OpVec *ops; + shared_ptr<Resources> resources; Call *call; }; diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc index 4d172d4ddf..41f6c29f7d 100644 --- a/src/node/ext/call_credentials.cc +++ b/src/node/ext/call_credentials.cc @@ -35,7 +35,7 @@ #include <nan.h> #include <uv.h> -#include <list> +#include <queue> #include "grpc/grpc.h" #include "grpc/grpc_security.h" @@ -170,7 +170,7 @@ NAN_METHOD(CallCredentials::CreateFromPlugin) { grpc_metadata_credentials_plugin plugin; plugin_state *state = new plugin_state; state->callback = new Nan::Callback(info[0].As<Function>()); - state->pending_callbacks = new std::list<plugin_callback_data*>(); + state->pending_callbacks = new std::queue<plugin_callback_data*>(); uv_mutex_init(&state->plugin_mutex); uv_async_init(uv_default_loop(), &state->plugin_async, @@ -206,6 +206,7 @@ NAN_METHOD(PluginCallback) { return Nan::ThrowTypeError( "The callback's fourth argument must be an object"); } + shared_ptr<Resources> resources(new Resources); grpc_status_code code = static_cast<grpc_status_code>( Nan::To<uint32_t>(info[0]).FromJust()); Utf8String details_utf8_str(info[1]); @@ -213,7 +214,7 @@ NAN_METHOD(PluginCallback) { grpc_metadata_array array; Local<Object> callback_data = Nan::To<Object>(info[3]).ToLocalChecked(); if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(), - &array)){ + &array, resources)){ return Nan::ThrowError("Failed to parse metadata"); } grpc_credentials_plugin_metadata_cb cb = @@ -231,13 +232,13 @@ NAN_METHOD(PluginCallback) { NAUV_WORK_CB(SendPluginCallback) { Nan::HandleScope scope; plugin_state *state = reinterpret_cast<plugin_state*>(async->data); - std::list<plugin_callback_data*> callbacks; + std::queue<plugin_callback_data*> callbacks; uv_mutex_lock(&state->plugin_mutex); - callbacks.splice(callbacks.begin(), *state->pending_callbacks); + state->pending_callbacks->swap(callbacks); uv_mutex_unlock(&state->plugin_mutex); while (!callbacks.empty()) { plugin_callback_data *data = callbacks.front(); - callbacks.pop_front(); + callbacks.pop(); Local<Object> callback_data = Nan::New<Object>(); Nan::Set(callback_data, Nan::New("cb").ToLocalChecked(), Nan::New<v8::External>(reinterpret_cast<void*>(data->cb))); @@ -266,7 +267,7 @@ void plugin_get_metadata(void *state, grpc_auth_metadata_context context, data->user_data = user_data; uv_mutex_lock(&p_state->plugin_mutex); - p_state->pending_callbacks->push_back(data); + p_state->pending_callbacks->push(data); uv_mutex_unlock(&p_state->plugin_mutex); uv_async_send(&p_state->plugin_async); diff --git a/src/node/ext/call_credentials.h b/src/node/ext/call_credentials.h index 04c852bea1..21a4b8923e 100644 --- a/src/node/ext/call_credentials.h +++ b/src/node/ext/call_credentials.h @@ -34,7 +34,7 @@ #ifndef GRPC_NODE_CALL_CREDENTIALS_H_ #define GRPC_NODE_CALL_CREDENTIALS_H_ -#include <list> +#include <queue> #include <node.h> #include <nan.h> @@ -84,7 +84,7 @@ typedef struct plugin_callback_data { typedef struct plugin_state { Nan::Callback *callback; - std::list<plugin_callback_data*> *pending_callbacks; + std::queue<plugin_callback_data*> *pending_callbacks; uv_mutex_t plugin_mutex; // async.data == this uv_async_t plugin_async; diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc index c795ff7f42..5bc58b9b32 100644 --- a/src/node/ext/channel.cc +++ b/src/node/ext/channel.cc @@ -280,7 +280,8 @@ NAN_METHOD(Channel::WatchConnectivityState) { channel->wrapped_channel, last_state, MillisecondsToTimespec(deadline), GetCompletionQueue(), new struct tag(callback, - ops.release(), NULL)); + ops.release(), + shared_ptr<Resources>(nullptr), NULL)); CompletionQueueNext(); } diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index 682af0e5ad..614f2e9457 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -31,7 +31,7 @@ * */ -#include <list> +#include <queue> #include <node.h> #include <nan.h> @@ -56,12 +56,9 @@ extern "C" { #include "server.h" #include "completion_queue_async_worker.h" #include "server_credentials.h" -#include "slice.h" #include "timeval.h" #include "completion_queue.h" -using grpc::node::CreateSliceFromString; - using v8::FunctionTemplate; using v8::Local; using v8::Value; @@ -77,7 +74,7 @@ typedef struct log_args { typedef struct logger_state { Nan::Callback *callback; - std::list<log_args *> *pending_args; + std::queue<log_args *> *pending_args; uv_mutex_t mutex; uv_async_t async; // Indicates that a logger has been set @@ -286,8 +283,10 @@ NAN_METHOD(MetadataKeyIsLegal) { "headerKeyIsLegal's argument must be a string"); } Local<String> key = Nan::To<String>(info[0]).ToLocalChecked(); + Nan::Utf8String key_utf8_str(key); + char *key_str = *key_utf8_str; info.GetReturnValue().Set(static_cast<bool>( - grpc_header_key_is_legal(CreateSliceFromString(key)))); + grpc_header_key_is_legal(key_str, static_cast<size_t>(key->Length())))); } NAN_METHOD(MetadataNonbinValueIsLegal) { @@ -296,8 +295,11 @@ NAN_METHOD(MetadataNonbinValueIsLegal) { "metadataNonbinValueIsLegal's argument must be a string"); } Local<String> value = Nan::To<String>(info[0]).ToLocalChecked(); + Nan::Utf8String value_utf8_str(value); + char *value_str = *value_utf8_str; info.GetReturnValue().Set(static_cast<bool>( - grpc_header_nonbin_value_is_legal(CreateSliceFromString(value)))); + grpc_header_nonbin_value_is_legal( + value_str, static_cast<size_t>(value->Length())))); } NAN_METHOD(MetadataKeyIsBinary) { @@ -306,8 +308,10 @@ NAN_METHOD(MetadataKeyIsBinary) { "metadataKeyIsLegal's argument must be a string"); } Local<String> key = Nan::To<String>(info[0]).ToLocalChecked(); + Nan::Utf8String key_utf8_str(key); + char *key_str = *key_utf8_str; info.GetReturnValue().Set(static_cast<bool>( - grpc_is_binary_header(CreateSliceFromString(key)))); + grpc_is_binary_header(key_str, static_cast<size_t>(key->Length())))); } static grpc_ssl_roots_override_result get_ssl_roots_override( @@ -338,14 +342,14 @@ NAN_METHOD(SetDefaultRootsPem) { NAUV_WORK_CB(LogMessagesCallback) { Nan::HandleScope scope; - std::list<log_args *> args; + std::queue<log_args *> args; uv_mutex_lock(&grpc_logger_state.mutex); - args.splice(args.begin(), *grpc_logger_state.pending_args); + grpc_logger_state.pending_args->swap(args); uv_mutex_unlock(&grpc_logger_state.mutex); /* Call the callback with each log message */ while (!args.empty()) { log_args *arg = args.front(); - args.pop_front(); + args.pop(); Local<Value> file = Nan::New(arg->core_args.file).ToLocalChecked(); Local<Value> line = Nan::New<Uint32, uint32_t>(arg->core_args.line); Local<Value> severity = Nan::New( @@ -372,7 +376,7 @@ void node_log_func(gpr_log_func_args *args) { args_copy->timestamp = gpr_now(GPR_CLOCK_REALTIME); uv_mutex_lock(&grpc_logger_state.mutex); - grpc_logger_state.pending_args->push_back(args_copy); + grpc_logger_state.pending_args->push(args_copy); uv_mutex_unlock(&grpc_logger_state.mutex); uv_async_send(&grpc_logger_state.async); @@ -380,7 +384,7 @@ void node_log_func(gpr_log_func_args *args) { void init_logger() { memset(&grpc_logger_state, 0, sizeof(logger_state)); - grpc_logger_state.pending_args = new std::list<log_args *>(); + grpc_logger_state.pending_args = new std::queue<log_args *>(); uv_mutex_init(&grpc_logger_state.mutex); uv_async_init(uv_default_loop(), &grpc_logger_state.async, diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc index 4761b2867d..70d5b96f39 100644 --- a/src/node/ext/server.cc +++ b/src/node/ext/server.cc @@ -46,7 +46,6 @@ #include "grpc/grpc_security.h" #include "grpc/support/log.h" #include "server_credentials.h" -#include "slice.h" #include "timeval.h" namespace grpc { @@ -100,11 +99,10 @@ class NewCallOp : public Op { } Local<Object> obj = Nan::New<Object>(); Nan::Set(obj, Nan::New("call").ToLocalChecked(), Call::WrapStruct(call)); - // TODO(murgatroid99): Use zero-copy string construction instead Nan::Set(obj, Nan::New("method").ToLocalChecked(), - CopyStringFromSlice(details.method)); + Nan::New(details.method).ToLocalChecked()); Nan::Set(obj, Nan::New("host").ToLocalChecked(), - CopyStringFromSlice(details.host)); + Nan::New(details.host).ToLocalChecked()); Nan::Set(obj, Nan::New("deadline").ToLocalChecked(), Nan::New<Date>(TimespecToMilliseconds(details.deadline)) .ToLocalChecked()); @@ -113,7 +111,8 @@ class NewCallOp : public Op { return scope.Escape(obj); } - bool ParseOp(Local<Value> value, grpc_op *out) { + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { return true; } bool IsFinalOp() { @@ -140,7 +139,8 @@ class ServerShutdownOp : public Op { return Nan::New<External>(reinterpret_cast<void *>(server)); } - bool ParseOp(Local<Value> value, grpc_op *out) { + bool ParseOp(Local<Value> value, grpc_op *out, + shared_ptr<Resources> resources) { return true; } bool IsFinalOp() { @@ -207,7 +207,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(), + shared_ptr<Resources>(nullptr), NULL)); grpc_server_cancel_all_calls(this->wrapped_server); CompletionQueueNext(); this->wrapped_server = NULL; @@ -260,7 +261,7 @@ NAN_METHOD(Server::RequestCall) { GetCompletionQueue(), GetCompletionQueue(), new struct tag(new Callback(info[0].As<Function>()), ops.release(), - NULL)); + shared_ptr<Resources>(nullptr), NULL)); if (error != GRPC_CALL_OK) { return Nan::ThrowError(nanErrorWithCode("requestCall failed", error)); } @@ -313,7 +314,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)); + shared_ptr<Resources>(nullptr), NULL)); CompletionQueueNext(); } diff --git a/src/node/ext/slice.cc b/src/node/ext/slice.cc deleted file mode 100644 index 98a80b3d2f..0000000000 --- a/src/node/ext/slice.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <node.h> -#include <nan.h> -#include <grpc/slice.h> -#include <grpc/support/alloc.h> - -#include "slice.h" -#include "byte_buffer.h" - -namespace grpc { -namespace node { - -using Nan::Persistent; - -using v8::Local; -using v8::String; -using v8::Value; - -namespace { -void SliceFreeCallback(char *data, void *hint) { - grpc_slice *slice = reinterpret_cast<grpc_slice*>(hint); - grpc_slice_unref(*slice); - delete slice; -} - -void string_destroy_func(void *user_data) { - delete reinterpret_cast<Nan::Utf8String*>(user_data); -} - -void buffer_destroy_func(void *user_data) { - delete reinterpret_cast<PersistentValue*>(user_data); -} -} // namespace - -grpc_slice CreateSliceFromString(const Local<String> source) { - Nan::HandleScope scope; - Nan::Utf8String *utf8_value = new Nan::Utf8String(source); - return grpc_slice_new_with_user_data(**utf8_value, source->Length(), - string_destroy_func, utf8_value); -} - -grpc_slice CreateSliceFromBuffer(const Local<Value> source) { - // Prerequisite: ::node::Buffer::HasInstance(source) - Nan::HandleScope scope; - return grpc_slice_new_with_user_data(::node::Buffer::Data(source), - ::node::Buffer::Length(source), - buffer_destroy_func, - new PersistentValue(source)); -} -Local<String> CopyStringFromSlice(const grpc_slice slice) { - Nan::EscapableHandleScope scope; - if (GRPC_SLICE_LENGTH(slice) == 0) { - return scope.Escape(Nan::EmptyString()); - } - return scope.Escape(Nan::New<String>( - const_cast<char *>(reinterpret_cast<const char *>(GRPC_SLICE_START_PTR(slice))), - GRPC_SLICE_LENGTH(slice)).ToLocalChecked()); -} - -Local<Value> CreateBufferFromSlice(const grpc_slice slice) { - Nan::EscapableHandleScope scope; - grpc_slice *slice_ptr = new grpc_slice; - *slice_ptr = grpc_slice_ref(slice); - return scope.Escape(MakeFastBuffer(Nan::NewBuffer( - const_cast<char *>(reinterpret_cast<const char *>(GRPC_SLICE_START_PTR(*slice_ptr))), - GRPC_SLICE_LENGTH(*slice_ptr), SliceFreeCallback, slice_ptr).ToLocalChecked())); -} - -} // namespace node -} // namespace grpc diff --git a/src/node/ext/slice.h b/src/node/ext/slice.h deleted file mode 100644 index 7dcb1bd45a..0000000000 --- a/src/node/ext/slice.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <node.h> -#include <nan.h> -#include <grpc/slice.h> - -namespace grpc { -namespace node { - -typedef Nan::Persistent<v8::Value, Nan::CopyablePersistentTraits<v8::Value>> PersistentValue; - -grpc_slice CreateSliceFromString(const v8::Local<v8::String> source); - -grpc_slice CreateSliceFromBuffer(const v8::Local<v8::Value> source); - -v8::Local<v8::String> CopyStringFromSlice(const grpc_slice slice); - -v8::Local<v8::Value> CreateBufferFromSlice(const grpc_slice slice); - -} // namespace node -} // namespace grpc |