diff options
author | Yash Tibrewal <yashkt@google.com> | 2017-11-16 19:31:28 -0800 |
---|---|---|
committer | Yash Tibrewal <yashkt@google.com> | 2017-11-16 19:31:28 -0800 |
commit | 177039b2f89e73ad0d048da021f939f3a153c4e2 (patch) | |
tree | c7f10f04cd9a0872863e2b181162bc9928160cd8 /include/grpc++ | |
parent | 995aa91bbbc68deb6dfd7c667cfee3af2bedec08 (diff) | |
parent | 82c8f945302f128495e261b853ac49f1dfbe69a1 (diff) |
Merge master
Diffstat (limited to 'include/grpc++')
-rw-r--r-- | include/grpc++/impl/codegen/completion_queue.h | 32 | ||||
-rw-r--r-- | include/grpc++/impl/codegen/proto_utils.h | 33 |
2 files changed, 40 insertions, 25 deletions
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h index 11cc588879..b8a7862578 100644 --- a/include/grpc++/impl/codegen/completion_queue.h +++ b/include/grpc++/impl/codegen/completion_queue.h @@ -65,6 +65,7 @@ class CompletionQueue; class Server; class ServerBuilder; class ServerContext; +class ServerInterface; namespace internal { class CompletionQueueTag; @@ -187,21 +188,6 @@ class CompletionQueue : private GrpcLibraryCodegen { /// owership is performed. grpc_completion_queue* cq() { return cq_; } - /// Manage state of avalanching operations : completion queue tags that - /// trigger other completion queue operations. The underlying core completion - /// queue should not really shutdown until all avalanching operations have - /// been finalized. Note that we maintain the requirement that an avalanche - /// registration must take place before CQ shutdown (which must be maintained - /// elsehwere) - void InitialAvalanching() { - gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1)); - } - void RegisterAvalanching() { - gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, - static_cast<gpr_atm>(1)); - } - void CompleteAvalanching(); - protected: /// Private constructor of CompletionQueue only visible to friend classes CompletionQueue(const grpc_completion_queue_attributes& attributes) { @@ -238,6 +224,7 @@ class CompletionQueue : private GrpcLibraryCodegen { friend class ::grpc::internal::UnknownMethodHandler; friend class ::grpc::Server; friend class ::grpc::ServerContext; + friend class ::grpc::ServerInterface; template <class InputMessage, class OutputMessage> friend class ::grpc::internal::BlockingUnaryCallImpl; @@ -309,6 +296,21 @@ class CompletionQueue : private GrpcLibraryCodegen { GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok)); } + /// Manage state of avalanching operations : completion queue tags that + /// trigger other completion queue operations. The underlying core completion + /// queue should not really shutdown until all avalanching operations have + /// been finalized. Note that we maintain the requirement that an avalanche + /// registration must take place before CQ shutdown (which must be maintained + /// elsehwere) + void InitialAvalanching() { + gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1)); + } + void RegisterAvalanching() { + gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_, + static_cast<gpr_atm>(1)); + } + void CompleteAvalanching(); + grpc_completion_queue* cq_; // owned gpr_atm avalanches_in_flight_; diff --git a/include/grpc++/impl/codegen/proto_utils.h b/include/grpc++/impl/codegen/proto_utils.h index 0f7e115c9a..b7636034d4 100644 --- a/include/grpc++/impl/codegen/proto_utils.h +++ b/include/grpc++/impl/codegen/proto_utils.h @@ -41,8 +41,11 @@ const int kGrpcBufferWriterMaxBufferLength = 1024 * 1024; class GrpcBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream { public: - explicit GrpcBufferWriter(grpc_byte_buffer** bp, int block_size) - : block_size_(block_size), byte_count_(0), have_backup_(false) { + GrpcBufferWriter(grpc_byte_buffer** bp, int block_size, int total_size) + : block_size_(block_size), + total_size_(total_size), + byte_count_(0), + have_backup_(false) { *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(NULL, 0); slice_buffer_ = &(*bp)->data.raw.slice_buffer; } @@ -54,11 +57,20 @@ class GrpcBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream { } bool Next(void** data, int* size) override { + // Protobuf should not ask for more memory than total_size_. + GPR_CODEGEN_ASSERT(byte_count_ < total_size_); if (have_backup_) { slice_ = backup_slice_; have_backup_ = false; } else { - slice_ = g_core_codegen_interface->grpc_slice_malloc(block_size_); + // When less than a whole block is needed, only allocate that much. + // But make sure the allocated slice is not inlined. + size_t remain = total_size_ - byte_count_ > block_size_ + ? block_size_ + : total_size_ - byte_count_; + slice_ = g_core_codegen_interface->grpc_slice_malloc( + remain > GRPC_SLICE_INLINED_SIZE ? remain + : GRPC_SLICE_INLINED_SIZE + 1); } *data = GRPC_SLICE_START_PTR(slice_); // On win x64, int is only 32bit @@ -70,7 +82,7 @@ class GrpcBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream { void BackUp(int count) override { g_core_codegen_interface->grpc_slice_buffer_pop(slice_buffer_); - if (count == block_size_) { + if ((size_t)count == GRPC_SLICE_LENGTH(slice_)) { backup_slice_ = slice_; } else { backup_slice_ = g_core_codegen_interface->grpc_slice_split_tail( @@ -90,6 +102,7 @@ class GrpcBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream { protected: friend class GrpcBufferWriterPeer; const int block_size_; + const int total_size_; int64_t byte_count_; grpc_slice_buffer* slice_buffer_; bool have_backup_; @@ -175,20 +188,20 @@ Status GenericSerialize(const grpc::protobuf::Message& msg, "BufferWriter must be a subclass of io::ZeroCopyOutputStream"); *own_buffer = true; int byte_size = msg.ByteSize(); - if (byte_size <= kGrpcBufferWriterMaxBufferLength) { + if ((size_t)byte_size <= GRPC_SLICE_INLINED_SIZE) { grpc_slice slice = g_core_codegen_interface->grpc_slice_malloc(byte_size); GPR_CODEGEN_ASSERT( GRPC_SLICE_END_PTR(slice) == msg.SerializeWithCachedSizesToArray(GRPC_SLICE_START_PTR(slice))); *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(&slice, 1); g_core_codegen_interface->grpc_slice_unref(slice); + return g_core_codegen_interface->ok(); - } else { - BufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength); - return msg.SerializeToZeroCopyStream(&writer) - ? g_core_codegen_interface->ok() - : Status(StatusCode::INTERNAL, "Failed to serialize message"); } + BufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength, byte_size); + return msg.SerializeToZeroCopyStream(&writer) + ? g_core_codegen_interface->ok() + : Status(StatusCode::INTERNAL, "Failed to serialize message"); } // BufferReader must be a subclass of io::ZeroCopyInputStream. |