|
|
|
@ -145,17 +145,19 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface<R> { |
|
|
|
|
public: |
|
|
|
|
/// Create a stream and write the first request out.
|
|
|
|
|
template <class W> |
|
|
|
|
ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq, |
|
|
|
|
const RpcMethod& method, ClientContext* context, |
|
|
|
|
const W& request, void* tag) |
|
|
|
|
: context_(context), call_(channel->CreateCall(method, context, cq)) { |
|
|
|
|
init_ops_.set_output_tag(tag); |
|
|
|
|
init_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
// TODO(ctiller): don't assert
|
|
|
|
|
GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); |
|
|
|
|
init_ops_.ClientSendClose(); |
|
|
|
|
call_.PerformOps(&init_ops_); |
|
|
|
|
static ClientAsyncReader* Create(ChannelInterface* channel, |
|
|
|
|
CompletionQueue* cq, const RpcMethod& method, |
|
|
|
|
ClientContext* context, const W& request, |
|
|
|
|
void* tag) { |
|
|
|
|
Call call = channel->CreateCall(method, context, cq); |
|
|
|
|
return new (g_core_codegen_interface->grpc_call_arena_alloc( |
|
|
|
|
call.call(), sizeof(ClientAsyncReader))) |
|
|
|
|
ClientAsyncReader(call, context, request, tag); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// always allocated against a call arena, no memory free required
|
|
|
|
|
static void operator delete(void* ptr, std::size_t size) { |
|
|
|
|
assert(size == sizeof(ClientAsyncReader)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ReadInitialMetadata(void* tag) override { |
|
|
|
@ -185,6 +187,19 @@ class ClientAsyncReader final : public ClientAsyncReaderInterface<R> { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
template <class W> |
|
|
|
|
ClientAsyncReader(Call call, ClientContext* context, const W& request, |
|
|
|
|
void* tag) |
|
|
|
|
: context_(context), call_(call) { |
|
|
|
|
init_ops_.set_output_tag(tag); |
|
|
|
|
init_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
// TODO(ctiller): don't assert
|
|
|
|
|
GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); |
|
|
|
|
init_ops_.ClientSendClose(); |
|
|
|
|
call_.PerformOps(&init_ops_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ClientContext* context_; |
|
|
|
|
Call call_; |
|
|
|
|
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose> |
|
|
|
@ -210,23 +225,19 @@ template <class W> |
|
|
|
|
class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> { |
|
|
|
|
public: |
|
|
|
|
template <class R> |
|
|
|
|
ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq, |
|
|
|
|
const RpcMethod& method, ClientContext* context, |
|
|
|
|
R* response, void* tag) |
|
|
|
|
: context_(context), call_(channel->CreateCall(method, context, cq)) { |
|
|
|
|
finish_ops_.RecvMessage(response); |
|
|
|
|
finish_ops_.AllowNoMessage(); |
|
|
|
|
// if corked bit is set in context, we buffer up the initial metadata to
|
|
|
|
|
// coalesce with later message to be sent. No op is performed.
|
|
|
|
|
if (context_->initial_metadata_corked_) { |
|
|
|
|
write_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
} else { |
|
|
|
|
write_ops_.set_output_tag(tag); |
|
|
|
|
write_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
call_.PerformOps(&write_ops_); |
|
|
|
|
static ClientAsyncWriter* Create(ChannelInterface* channel, |
|
|
|
|
CompletionQueue* cq, const RpcMethod& method, |
|
|
|
|
ClientContext* context, R* response, |
|
|
|
|
void* tag) { |
|
|
|
|
Call call = channel->CreateCall(method, context, cq); |
|
|
|
|
return new (g_core_codegen_interface->grpc_call_arena_alloc( |
|
|
|
|
call.call(), sizeof(ClientAsyncWriter))) |
|
|
|
|
ClientAsyncWriter(call, context, response, tag); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// always allocated against a call arena, no memory free required
|
|
|
|
|
static void operator delete(void* ptr, std::size_t size) { |
|
|
|
|
assert(size == sizeof(ClientAsyncWriter)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ReadInitialMetadata(void* tag) override { |
|
|
|
@ -271,6 +282,24 @@ class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
template <class R> |
|
|
|
|
ClientAsyncWriter(Call call, ClientContext* context, R* response, void* tag) |
|
|
|
|
: context_(context), call_(call) { |
|
|
|
|
finish_ops_.RecvMessage(response); |
|
|
|
|
finish_ops_.AllowNoMessage(); |
|
|
|
|
// if corked bit is set in context, we buffer up the initial metadata to
|
|
|
|
|
// coalesce with later message to be sent. No op is performed.
|
|
|
|
|
if (context_->initial_metadata_corked_) { |
|
|
|
|
write_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
} else { |
|
|
|
|
write_ops_.set_output_tag(tag); |
|
|
|
|
write_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
call_.PerformOps(&write_ops_); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ClientContext* context_; |
|
|
|
|
Call call_; |
|
|
|
|
CallOpSet<CallOpRecvInitialMetadata> meta_ops_; |
|
|
|
@ -298,21 +327,20 @@ template <class W, class R> |
|
|
|
|
class ClientAsyncReaderWriter final |
|
|
|
|
: public ClientAsyncReaderWriterInterface<W, R> { |
|
|
|
|
public: |
|
|
|
|
ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq, |
|
|
|
|
const RpcMethod& method, ClientContext* context, |
|
|
|
|
void* tag) |
|
|
|
|
: context_(context), call_(channel->CreateCall(method, context, cq)) { |
|
|
|
|
if (context_->initial_metadata_corked_) { |
|
|
|
|
// if corked bit is set in context, we buffer up the initial metadata to
|
|
|
|
|
// coalesce with later message to be sent. No op is performed.
|
|
|
|
|
write_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
} else { |
|
|
|
|
write_ops_.set_output_tag(tag); |
|
|
|
|
write_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
call_.PerformOps(&write_ops_); |
|
|
|
|
static ClientAsyncReaderWriter* Create(ChannelInterface* channel, |
|
|
|
|
CompletionQueue* cq, |
|
|
|
|
const RpcMethod& method, |
|
|
|
|
ClientContext* context, void* tag) { |
|
|
|
|
Call call = channel->CreateCall(method, context, cq); |
|
|
|
|
|
|
|
|
|
return new (g_core_codegen_interface->grpc_call_arena_alloc( |
|
|
|
|
call.call(), sizeof(ClientAsyncReaderWriter))) |
|
|
|
|
ClientAsyncReaderWriter(call, context, tag); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// always allocated against a call arena, no memory free required
|
|
|
|
|
static void operator delete(void* ptr, std::size_t size) { |
|
|
|
|
assert(size == sizeof(ClientAsyncReaderWriter)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ReadInitialMetadata(void* tag) override { |
|
|
|
@ -366,6 +394,21 @@ class ClientAsyncReaderWriter final |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
ClientAsyncReaderWriter(Call call, ClientContext* context, void* tag) |
|
|
|
|
: context_(context), call_(call) { |
|
|
|
|
if (context_->initial_metadata_corked_) { |
|
|
|
|
// if corked bit is set in context, we buffer up the initial metadata to
|
|
|
|
|
// coalesce with later message to be sent. No op is performed.
|
|
|
|
|
write_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
} else { |
|
|
|
|
write_ops_.set_output_tag(tag); |
|
|
|
|
write_ops_.SendInitialMetadata(context->send_initial_metadata_, |
|
|
|
|
context->initial_metadata_flags()); |
|
|
|
|
call_.PerformOps(&write_ops_); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ClientContext* context_; |
|
|
|
|
Call call_; |
|
|
|
|
CallOpSet<CallOpRecvInitialMetadata> meta_ops_; |
|
|
|
|