blob: fac1ba9d43c1691c0cdbd4bf156ab59f50e9f723 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * Copyright 2015, 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
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080038#include <grpc++/client_context.h>
Craig Tiller50950712015-02-09 10:38:38 -080039#include <grpc++/completion_queue.h>
Craig Tiller20f4af22015-02-10 09:52:15 -080040#include <grpc++/impl/call.h>
David Garcia Quintas08a0a332016-01-21 01:04:36 -080041#include <grpc++/impl/codegen/completion_queue_tag.h>
David Garcia Quintase1300de2016-01-27 18:41:26 -080042#include <grpc++/impl/grpc_library.h>
43#include <grpc++/impl/rpc_method.h>
44#include <grpc++/security/credentials.h>
yang-g9e2f90c2015-08-21 15:35:03 -070045#include <grpc++/support/channel_arguments.h>
46#include <grpc++/support/config.h>
47#include <grpc++/support/status.h>
48#include <grpc++/support/time.h>
David Garcia Quintase1300de2016-01-27 18:41:26 -080049#include <grpc/grpc.h>
Craig Tillerb37d53e2016-10-26 16:16:35 -070050#include <grpc/slice.h>
Mark D. Roth4bbdda42016-11-09 14:40:22 -080051#include <grpc/support/alloc.h>
Craig Tiller28b72422016-10-26 21:15:29 -070052#include <grpc/support/log.h>
Craig Tiller9533d042016-03-25 17:11:06 -070053#include "src/core/lib/profiling/timers.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080054
55namespace grpc {
56
David Garcia Quintasd79ef3a2016-01-28 00:21:27 -080057static internal::GrpcLibraryInitializer g_gli_initializer;
yang-gd556da92015-07-31 15:59:04 -070058Channel::Channel(const grpc::string& host, grpc_channel* channel)
David Garcia Quintase1300de2016-01-27 18:41:26 -080059 : host_(host), c_channel_(channel) {
David Garcia Quintasd79ef3a2016-01-28 00:21:27 -080060 g_gli_initializer.summon();
David Garcia Quintase1300de2016-01-27 18:41:26 -080061}
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080062
63Channel::~Channel() { grpc_channel_destroy(c_channel_); }
64
Mark D. Roth4bbdda42016-11-09 14:40:22 -080065namespace {
66
67grpc::string GetChannelInfoField(grpc_channel* channel,
68 grpc_channel_info* channel_info,
69 char*** channel_info_field) {
70 char* value = NULL;
71 memset(channel_info, 0, sizeof(*channel_info));
72 *channel_info_field = &value;
73 grpc_channel_get_info(channel, channel_info);
74 if (value == NULL) return "";
75 grpc::string result = value;
76 gpr_free(value);
77 return result;
78}
79
80} // namespace
81
82grpc::string Channel::GetLoadBalancingPolicyName() const {
83 grpc_channel_info channel_info;
84 return GetChannelInfoField(c_channel_, &channel_info,
85 &channel_info.lb_policy_name);
86}
87
88grpc::string Channel::GetServiceConfigJSON() const {
89 grpc_channel_info channel_info;
90 return GetChannelInfoField(c_channel_, &channel_info,
91 &channel_info.service_config_json);
92}
93
Craig Tiller47c83fd2015-02-21 22:45:35 -080094Call Channel::CreateCall(const RpcMethod& method, ClientContext* context,
95 CompletionQueue* cq) {
yang-g37ce0342015-08-12 11:46:26 -070096 const bool kRegistered = method.channel_tag() && context->authority().empty();
yang-g0c034a02015-08-11 11:46:32 -070097 grpc_call* c_call = NULL;
yang-g37ce0342015-08-12 11:46:26 -070098 if (kRegistered) {
yang-g0c034a02015-08-11 11:46:32 -070099 c_call = grpc_channel_create_registered_call(
100 c_channel_, context->propagate_from_call_,
101 context->propagation_options_.c_bitmask(), cq->cq(),
Nicolas "Pixel" Nobled53b3892015-08-13 19:20:39 +0200102 method.channel_tag(), context->raw_deadline(), nullptr);
yang-g0c034a02015-08-11 11:46:32 -0700103 } else {
104 const char* host_str = NULL;
105 if (!context->authority().empty()) {
yang-g2f543f22015-08-19 15:14:17 -0700106 host_str = context->authority_.c_str();
yang-g0c034a02015-08-11 11:46:32 -0700107 } else if (!host_.empty()) {
108 host_str = host_.c_str();
109 }
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800110 grpc_slice method_slice = SliceFromCopiedString(method.name());
111 grpc_slice host_slice;
112 if (host_str != nullptr) {
113 host_slice = SliceFromCopiedString(host_str);
114 }
115 c_call = grpc_channel_create_call(
116 c_channel_, context->propagate_from_call_,
117 context->propagation_options_.c_bitmask(), cq->cq(), method_slice,
118 host_str == nullptr ? nullptr : &host_slice, context->raw_deadline(),
119 nullptr);
120 grpc_slice_unref(method_slice);
121 if (host_str != nullptr) {
122 grpc_slice_unref(host_slice);
123 }
yang-g0c034a02015-08-11 11:46:32 -0700124 }
yang-g9a009f22015-07-29 11:38:18 -0700125 grpc_census_call_set_context(c_call, context->census_context());
Craig Tiller1fb99552015-04-27 08:55:08 -0700126 context->set_call(c_call, shared_from_this());
Craig Tiller50950712015-02-09 10:38:38 -0800127 return Call(c_call, this, cq);
128}
129
Craig Tiller50a7a682015-06-04 12:53:40 -0700130void Channel::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
Craig Tiller50950712015-02-09 10:38:38 -0800131 static const size_t MAX_OPS = 8;
Craig Tiller50a7a682015-06-04 12:53:40 -0700132 size_t nops = 0;
133 grpc_op cops[MAX_OPS];
Craig Tiller66051c62017-03-31 09:16:35 -0700134 ops->FillOps(call->call(), cops, &nops);
Craig Tiller50950712015-02-09 10:38:38 -0800135 GPR_ASSERT(GRPC_CALL_OK ==
Nicolas "Pixel" Nobleebb51402015-07-23 02:41:33 +0200136 grpc_call_start_batch(call->call(), cops, nops, ops, nullptr));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800137}
138
Craig Tiller277d3cf2015-04-14 14:04:51 -0700139void* Channel::RegisterMethod(const char* method) {
Craig Tillerd6c98df2015-08-18 09:33:44 -0700140 return grpc_channel_register_call(
141 c_channel_, method, host_.empty() ? NULL : host_.c_str(), nullptr);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800142}
143
yang-ga73dc1c2015-08-05 14:24:00 -0700144grpc_connectivity_state Channel::GetState(bool try_to_connect) {
145 return grpc_channel_check_connectivity_state(c_channel_, try_to_connect);
146}
147
yang-g36f59652015-08-05 15:15:18 -0700148namespace {
Vijay Paic0b2acb2016-11-01 16:31:56 -0700149class TagSaver final : public CompletionQueueTag {
yang-g36f59652015-08-05 15:15:18 -0700150 public:
151 explicit TagSaver(void* tag) : tag_(tag) {}
Vijay Paic0b2acb2016-11-01 16:31:56 -0700152 ~TagSaver() override {}
153 bool FinalizeResult(void** tag, bool* status) override {
yang-g36f59652015-08-05 15:15:18 -0700154 *tag = tag_;
155 delete this;
156 return true;
157 }
Craig Tillerd6c98df2015-08-18 09:33:44 -0700158
yang-g36f59652015-08-05 15:15:18 -0700159 private:
160 void* tag_;
161};
162
yang-gc8abca82015-08-06 22:50:16 -0700163} // namespace
164
165void Channel::NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
166 gpr_timespec deadline,
167 CompletionQueue* cq, void* tag) {
yang-g36f59652015-08-05 15:15:18 -0700168 TagSaver* tag_saver = new TagSaver(tag);
yang-gc8abca82015-08-06 22:50:16 -0700169 grpc_channel_watch_connectivity_state(c_channel_, last_observed, deadline,
170 cq->cq(), tag_saver);
yang-g36f59652015-08-05 15:15:18 -0700171}
172
yang-gc8abca82015-08-06 22:50:16 -0700173bool Channel::WaitForStateChangeImpl(grpc_connectivity_state last_observed,
174 gpr_timespec deadline) {
yang-g36f59652015-08-05 15:15:18 -0700175 CompletionQueue cq;
176 bool ok = false;
177 void* tag = NULL;
yang-gc8abca82015-08-06 22:50:16 -0700178 NotifyOnStateChangeImpl(last_observed, deadline, &cq, NULL);
yang-g36f59652015-08-05 15:15:18 -0700179 cq.Next(&tag, &ok);
180 GPR_ASSERT(tag == NULL);
181 return ok;
182}
183
Craig Tiller190d3602015-02-18 09:23:38 -0800184} // namespace grpc