aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpc++/impl/codegen/async_unary_call.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/grpc++/impl/codegen/async_unary_call.h')
-rw-r--r--include/grpc++/impl/codegen/async_unary_call.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
new file mode 100644
index 0000000000..481b20b535
--- /dev/null
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -0,0 +1,156 @@
+/*
+ *
+ * Copyright 2015-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.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
+#define GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
+
+#include <grpc++/impl/codegen/call.h>
+#include <grpc++/impl/codegen/channel_interface.h>
+#include <grpc++/impl/codegen/client_context.h>
+#include <grpc++/impl/codegen/server_context.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/status.h>
+#include <grpc/impl/codegen/log.h>
+
+namespace grpc {
+
+class CompletionQueue;
+
+template <class R>
+class ClientAsyncResponseReaderInterface {
+ public:
+ virtual ~ClientAsyncResponseReaderInterface() {}
+ virtual void ReadInitialMetadata(void* tag) = 0;
+ virtual void Finish(R* msg, Status* status, void* tag) = 0;
+};
+
+template <class R>
+class ClientAsyncResponseReader GRPC_FINAL
+ : public ClientAsyncResponseReaderInterface<R> {
+ public:
+ template <class W>
+ ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq,
+ const RpcMethod& method, ClientContext* context,
+ const W& request)
+ : context_(context), call_(channel->CreateCall(method, context, cq)) {
+ init_buf_.SendInitialMetadata(context->send_initial_metadata_);
+ // TODO(ctiller): don't assert
+ GPR_ASSERT(init_buf_.SendMessage(request).ok());
+ init_buf_.ClientSendClose();
+ call_.PerformOps(&init_buf_);
+ }
+
+ void ReadInitialMetadata(void* tag) {
+ GPR_ASSERT(!context_->initial_metadata_received_);
+
+ meta_buf_.set_output_tag(tag);
+ meta_buf_.RecvInitialMetadata(context_);
+ call_.PerformOps(&meta_buf_);
+ }
+
+ void Finish(R* msg, Status* status, void* tag) {
+ finish_buf_.set_output_tag(tag);
+ if (!context_->initial_metadata_received_) {
+ finish_buf_.RecvInitialMetadata(context_);
+ }
+ finish_buf_.RecvMessage(msg);
+ finish_buf_.ClientRecvStatus(context_, status);
+ call_.PerformOps(&finish_buf_);
+ }
+
+ private:
+ ClientContext* context_;
+ Call call_;
+ SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpClientSendClose> init_buf_;
+ CallOpSet<CallOpRecvInitialMetadata> meta_buf_;
+ CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
+ CallOpClientRecvStatus> finish_buf_;
+};
+
+template <class W>
+class ServerAsyncResponseWriter GRPC_FINAL
+ : public ServerAsyncStreamingInterface {
+ public:
+ explicit ServerAsyncResponseWriter(ServerContext* ctx)
+ : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+ void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
+ GPR_ASSERT(!ctx_->sent_initial_metadata_);
+
+ meta_buf_.set_output_tag(tag);
+ meta_buf_.SendInitialMetadata(ctx_->initial_metadata_);
+ ctx_->sent_initial_metadata_ = true;
+ call_.PerformOps(&meta_buf_);
+ }
+
+ void Finish(const W& msg, const Status& status, void* tag) {
+ finish_buf_.set_output_tag(tag);
+ if (!ctx_->sent_initial_metadata_) {
+ finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
+ ctx_->sent_initial_metadata_ = true;
+ }
+ // The response is dropped if the status is not OK.
+ if (status.ok()) {
+ finish_buf_.ServerSendStatus(ctx_->trailing_metadata_,
+ finish_buf_.SendMessage(msg));
+ } else {
+ finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ }
+ call_.PerformOps(&finish_buf_);
+ }
+
+ void FinishWithError(const Status& status, void* tag) {
+ GPR_ASSERT(!status.ok());
+ finish_buf_.set_output_tag(tag);
+ if (!ctx_->sent_initial_metadata_) {
+ finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
+ ctx_->sent_initial_metadata_ = true;
+ }
+ finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ call_.PerformOps(&finish_buf_);
+ }
+
+ private:
+ void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
+
+ Call call_;
+ ServerContext* ctx_;
+ CallOpSet<CallOpSendInitialMetadata> meta_buf_;
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpServerSendStatus> finish_buf_;
+};
+
+} // namespace grpc
+
+#endif // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H