blob: f9bedbd0b5de54cff5522d84531676bb5a384cec [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
David Garcia Quintasa43aadd2016-01-21 10:01:28 -08003 * Copyright 2015-2016, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
yang-g8c2be9f2015-08-19 16:28:09 -070034#include <grpc++/channel.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035
yangg59dfc902014-12-19 14:00:14 -080036#include <memory>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080037
38#include <grpc/grpc.h>
39#include <grpc/support/log.h>
40#include <grpc/support/slice.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080041#include <grpc++/client_context.h>
Craig Tiller50950712015-02-09 10:38:38 -080042#include <grpc++/completion_queue.h>
Julien Boeuf5be92a32015-08-28 16:28:18 -070043#include <grpc++/security/credentials.h>
Craig Tiller20f4af22015-02-10 09:52:15 -080044#include <grpc++/impl/call.h>
yangg1b151092015-01-09 15:31:05 -080045#include <grpc++/impl/rpc_method.h>
David Garcia Quintas08a0a332016-01-21 01:04:36 -080046#include <grpc++/impl/codegen/completion_queue_tag.h>
yang-g9e2f90c2015-08-21 15:35:03 -070047#include <grpc++/support/channel_arguments.h>
48#include <grpc++/support/config.h>
49#include <grpc++/support/status.h>
50#include <grpc++/support/time.h>
51#include "src/core/profiling/timers.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080052
53namespace grpc {
54
yang-gd556da92015-07-31 15:59:04 -070055Channel::Channel(const grpc::string& host, grpc_channel* channel)
56 : host_(host), c_channel_(channel) {}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080057
58Channel::~Channel() { grpc_channel_destroy(c_channel_); }
59
Craig Tiller47c83fd2015-02-21 22:45:35 -080060Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
61 CompletionQueue* cq) {
yang-g37ce0342015-08-12 11:46:26 -070062 const bool kRegistered = method.channel_tag() && context->authority().empty();
yang-g0c034a02015-08-11 11:46:32 -070063 grpc_call* c_call = NULL;
yang-g37ce0342015-08-12 11:46:26 -070064 if (kRegistered) {
yang-g0c034a02015-08-11 11:46:32 -070065 c_call = grpc_channel_create_registered_call(
66 c_channel_, context->propagate_from_call_,
67 context->propagation_options_.c_bitmask(), cq->cq(),
Nicolas "Pixel" Nobled53b3892015-08-13 19:20:39 +020068 method.channel_tag(), context->raw_deadline(), nullptr);
yang-g0c034a02015-08-11 11:46:32 -070069 } else {
70 const char* host_str = NULL;
71 if (!context->authority().empty()) {
yang-g2f543f22015-08-19 15:14:17 -070072 host_str = context->authority_.c_str();
yang-g0c034a02015-08-11 11:46:32 -070073 } else if (!host_.empty()) {
74 host_str = host_.c_str();
75 }
76 c_call = grpc_channel_create_call(c_channel_, context->propagate_from_call_,
77 context->propagation_options_.c_bitmask(),
78 cq->cq(), method.name(), host_str,
Nicolas "Pixel" Nobled53b3892015-08-13 19:20:39 +020079 context->raw_deadline(), nullptr);
yang-g0c034a02015-08-11 11:46:32 -070080 }
yang-g9a009f22015-07-29 11:38:18 -070081 grpc_census_call_set_context(c_call, context->census_context());
Craig Tiller1fb99552015-04-27 08:55:08 -070082 context->set_call(c_call, shared_from_this());
Craig Tiller50950712015-02-09 10:38:38 -080083 return Call(c_call, this, cq);
84}
85
Craig Tiller50a7a682015-06-04 12:53:40 -070086void Channel::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
Craig Tiller50950712015-02-09 10:38:38 -080087 static const size_t MAX_OPS = 8;
Craig Tiller50a7a682015-06-04 12:53:40 -070088 size_t nops = 0;
89 grpc_op cops[MAX_OPS];
Craig Tiller50a7a682015-06-04 12:53:40 -070090 ops->FillOps(cops, &nops);
Craig Tiller50950712015-02-09 10:38:38 -080091 GPR_ASSERT(GRPC_CALL_OK ==
Nicolas "Pixel" Nobleebb51402015-07-23 02:41:33 +020092 grpc_call_start_batch(call->call(), cops, nops, ops, nullptr));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080093}
94
Craig Tiller277d3cf2015-04-14 14:04:51 -070095void* Channel::RegisterMethod(const char* method) {
Craig Tillerd6c98df2015-08-18 09:33:44 -070096 return grpc_channel_register_call(
97 c_channel_, method, host_.empty() ? NULL : host_.c_str(), nullptr);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080098}
99
yang-ga73dc1c2015-08-05 14:24:00 -0700100grpc_connectivity_state Channel::GetState(bool try_to_connect) {
101 return grpc_channel_check_connectivity_state(c_channel_, try_to_connect);
102}
103
yang-g36f59652015-08-05 15:15:18 -0700104namespace {
105class TagSaver GRPC_FINAL : public CompletionQueueTag {
106 public:
107 explicit TagSaver(void* tag) : tag_(tag) {}
108 ~TagSaver() GRPC_OVERRIDE {}
109 bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
110 *tag = tag_;
111 delete this;
112 return true;
113 }
Craig Tillerd6c98df2015-08-18 09:33:44 -0700114
yang-g36f59652015-08-05 15:15:18 -0700115 private:
116 void* tag_;
117};
118
yang-gc8abca82015-08-06 22:50:16 -0700119} // namespace
120
121void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
122 gpr_timespec deadline,
123 CompletionQueue* cq, void* tag) {
yang-g36f59652015-08-05 15:15:18 -0700124 TagSaver* tag_saver = new TagSaver(tag);
yang-gc8abca82015-08-06 22:50:16 -0700125 grpc_channel_watch_connectivity_state(c_channel_, last_observed, deadline,
126 cq->cq(), tag_saver);
yang-g36f59652015-08-05 15:15:18 -0700127}
128
yang-gc8abca82015-08-06 22:50:16 -0700129bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed,
130 gpr_timespec deadline) {
yang-g36f59652015-08-05 15:15:18 -0700131 CompletionQueue cq;
132 bool ok = false;
133 void* tag = NULL;
yang-gc8abca82015-08-06 22:50:16 -0700134 NotifyOnStateChangeImpl(last_observed, deadline, &cq, NULL);
yang-g36f59652015-08-05 15:15:18 -0700135 cq.Next(&tag, &ok);
136 GPR_ASSERT(tag == NULL);
137 return ok;
138}
139
Craig Tiller190d3602015-02-18 09:23:38 -0800140} // namespace grpc