• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include <grpc/support/port_platform.h>
18 
19 #include "src/core/lib/surface/channel.h"
20 
21 #include <grpc/compression.h>
22 #include <grpc/grpc.h>
23 #include <grpc/impl/channel_arg_names.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/log.h>
26 
27 #include "src/core/lib/channel/channel_args.h"
28 #include "src/core/lib/channel/channel_trace.h"
29 #include "src/core/lib/channel/channelz.h"
30 #include "src/core/lib/compression/compression_internal.h"
31 #include "src/core/lib/debug/stats.h"
32 #include "src/core/lib/debug/stats_data.h"
33 #include "src/core/lib/debug/trace.h"
34 #include "src/core/lib/iomgr/exec_ctx.h"
35 #include "src/core/lib/surface/api_trace.h"
36 
37 namespace grpc_core {
38 
39 //
40 // Channel::RegisteredCall
41 //
42 
RegisteredCall(const char * method_arg,const char * host_arg)43 Channel::RegisteredCall::RegisteredCall(const char* method_arg,
44                                         const char* host_arg) {
45   path = Slice::FromCopiedString(method_arg);
46   if (host_arg != nullptr && host_arg[0] != 0) {
47     authority = Slice::FromCopiedString(host_arg);
48   }
49 }
50 
RegisteredCall(const RegisteredCall & other)51 Channel::RegisteredCall::RegisteredCall(const RegisteredCall& other)
52     : path(other.path.Ref()) {
53   if (other.authority.has_value()) {
54     authority = other.authority->Ref();
55   }
56 }
57 
~RegisteredCall()58 Channel::RegisteredCall::~RegisteredCall() {}
59 
60 //
61 // Channel
62 //
63 
Channel(std::string target,const ChannelArgs & channel_args)64 Channel::Channel(std::string target, const ChannelArgs& channel_args)
65     : target_(std::move(target)),
66       channelz_node_(channel_args.GetObjectRef<channelz::ChannelNode>()),
67       compression_options_(CompressionOptionsFromChannelArgs(channel_args)) {}
68 
RegisterCall(const char * method,const char * host)69 Channel::RegisteredCall* Channel::RegisterCall(const char* method,
70                                                const char* host) {
71   MutexLock lock(&mu_);
72   auto key = std::make_pair(std::string(host != nullptr ? host : ""),
73                             std::string(method != nullptr ? method : ""));
74   auto rc_posn = registration_table_.find(key);
75   if (rc_posn != registration_table_.end()) {
76     return &rc_posn->second;
77   }
78   auto insertion_result = registration_table_.insert(
79       {std::move(key), RegisteredCall(method, host)});
80   return &insertion_result.first->second;
81 }
82 
83 }  // namespace grpc_core
84 
85 //
86 // C-core API
87 //
88 
grpc_channel_destroy(grpc_channel * channel)89 void grpc_channel_destroy(grpc_channel* channel) {
90   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
91   grpc_core::ExecCtx exec_ctx;
92   GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel));
93   grpc_channel_destroy_internal(channel);
94 }
95 
grpc_channel_create_call(grpc_channel * channel,grpc_call * parent_call,uint32_t propagation_mask,grpc_completion_queue * completion_queue,grpc_slice method,const grpc_slice * host,gpr_timespec deadline,void * reserved)96 grpc_call* grpc_channel_create_call(grpc_channel* channel,
97                                     grpc_call* parent_call,
98                                     uint32_t propagation_mask,
99                                     grpc_completion_queue* completion_queue,
100                                     grpc_slice method, const grpc_slice* host,
101                                     gpr_timespec deadline, void* reserved) {
102   GPR_ASSERT(!reserved);
103   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
104   grpc_core::ExecCtx exec_ctx;
105   return grpc_core::Channel::FromC(channel)->CreateCall(
106       parent_call, propagation_mask, completion_queue, nullptr,
107       grpc_core::Slice(grpc_core::CSliceRef(method)),
108       host != nullptr
109           ? absl::optional<grpc_core::Slice>(grpc_core::CSliceRef(*host))
110           : absl::nullopt,
111       grpc_core::Timestamp::FromTimespecRoundUp(deadline),
112       /*registered_method=*/false);
113 }
114 
grpc_channel_register_call(grpc_channel * channel,const char * method,const char * host,void * reserved)115 void* grpc_channel_register_call(grpc_channel* channel, const char* method,
116                                  const char* host, void* reserved) {
117   GRPC_API_TRACE(
118       "grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)",
119       4, (channel, method, host, reserved));
120   GPR_ASSERT(!reserved);
121   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
122   grpc_core::ExecCtx exec_ctx;
123   return grpc_core::Channel::FromC(channel)->RegisterCall(method, host);
124 }
125 
grpc_channel_create_registered_call(grpc_channel * channel,grpc_call * parent_call,uint32_t propagation_mask,grpc_completion_queue * completion_queue,void * registered_call_handle,gpr_timespec deadline,void * reserved)126 grpc_call* grpc_channel_create_registered_call(
127     grpc_channel* channel, grpc_call* parent_call, uint32_t propagation_mask,
128     grpc_completion_queue* completion_queue, void* registered_call_handle,
129     gpr_timespec deadline, void* reserved) {
130   auto* rc =
131       static_cast<grpc_core::Channel::RegisteredCall*>(registered_call_handle);
132   GRPC_API_TRACE(
133       "grpc_channel_create_registered_call("
134       "channel=%p, parent_call=%p, propagation_mask=%x, completion_queue=%p, "
135       "registered_call_handle=%p, "
136       "deadline=gpr_timespec { tv_sec: %" PRId64
137       ", tv_nsec: %d, clock_type: %d }, "
138       "reserved=%p)",
139       9,
140       (channel, parent_call, (unsigned)propagation_mask, completion_queue,
141        registered_call_handle, deadline.tv_sec, deadline.tv_nsec,
142        (int)deadline.clock_type, reserved));
143   GPR_ASSERT(!reserved);
144   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
145   grpc_core::ExecCtx exec_ctx;
146   return grpc_core::Channel::FromC(channel)->CreateCall(
147       parent_call, propagation_mask, completion_queue, nullptr, rc->path.Ref(),
148       rc->authority.has_value()
149           ? absl::optional<grpc_core::Slice>(rc->authority->Ref())
150           : absl::nullopt,
151       grpc_core::Timestamp::FromTimespecRoundUp(deadline),
152       /*registered_method=*/true);
153 }
154 
grpc_channel_get_target(grpc_channel * channel)155 char* grpc_channel_get_target(grpc_channel* channel) {
156   GRPC_API_TRACE("grpc_channel_get_target(channel=%p)", 1, (channel));
157   auto target = grpc_core::Channel::FromC(channel)->target();
158   char* buffer = static_cast<char*>(gpr_zalloc(target.size() + 1));
159   memcpy(buffer, target.data(), target.size());
160   return buffer;
161 }
162 
grpc_channel_get_info(grpc_channel * channel,const grpc_channel_info * channel_info)163 void grpc_channel_get_info(grpc_channel* channel,
164                            const grpc_channel_info* channel_info) {
165   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
166   grpc_core::ExecCtx exec_ctx;
167   grpc_core::Channel::FromC(channel)->GetInfo(channel_info);
168 }
169 
grpc_channel_reset_connect_backoff(grpc_channel * channel)170 void grpc_channel_reset_connect_backoff(grpc_channel* channel) {
171   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
172   grpc_core::ExecCtx exec_ctx;
173   GRPC_API_TRACE("grpc_channel_reset_connect_backoff(channel=%p)", 1,
174                  (channel));
175   grpc_core::Channel::FromC(channel)->ResetConnectionBackoff();
176 }
177 
grpc_channel_support_connectivity_watcher(grpc_channel * channel)178 int grpc_channel_support_connectivity_watcher(grpc_channel* channel) {
179   return grpc_core::Channel::FromC(channel)->SupportsConnectivityWatcher();
180 }
181 
grpc_channel_check_connectivity_state(grpc_channel * channel,int try_to_connect)182 grpc_connectivity_state grpc_channel_check_connectivity_state(
183     grpc_channel* channel, int try_to_connect) {
184   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
185   grpc_core::ExecCtx exec_ctx;
186   GRPC_API_TRACE(
187       "grpc_channel_check_connectivity_state(channel=%p, try_to_connect=%d)", 2,
188       (channel, try_to_connect));
189   return grpc_core::Channel::FromC(channel)->CheckConnectivityState(
190       try_to_connect);
191 }
192 
grpc_channel_watch_connectivity_state(grpc_channel * channel,grpc_connectivity_state last_observed_state,gpr_timespec deadline,grpc_completion_queue * cq,void * tag)193 void grpc_channel_watch_connectivity_state(
194     grpc_channel* channel, grpc_connectivity_state last_observed_state,
195     gpr_timespec deadline, grpc_completion_queue* cq, void* tag) {
196   grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
197   grpc_core::ExecCtx exec_ctx;
198   GRPC_API_TRACE(
199       "grpc_channel_watch_connectivity_state("
200       "channel=%p, last_observed_state=%d, "
201       "deadline=gpr_timespec { tv_sec: %" PRId64
202       ", tv_nsec: %d, clock_type: %d }, "
203       "cq=%p, tag=%p)",
204       7,
205       (channel, (int)last_observed_state, deadline.tv_sec, deadline.tv_nsec,
206        (int)deadline.clock_type, cq, tag));
207   return grpc_core::Channel::FromC(channel)->WatchConnectivityState(
208       last_observed_state, grpc_core::Timestamp::FromTimespecRoundUp(deadline),
209       cq, tag);
210 }
211 
grpc_channel_ping(grpc_channel * channel,grpc_completion_queue * cq,void * tag,void * reserved)212 void grpc_channel_ping(grpc_channel* channel, grpc_completion_queue* cq,
213                        void* tag, void* reserved) {
214   grpc_core::ExecCtx exec_ctx;
215   GRPC_API_TRACE("grpc_channel_ping(channel=%p, cq=%p, tag=%p, reserved=%p)", 4,
216                  (channel, cq, tag, reserved));
217   GPR_ASSERT(reserved == nullptr);
218   grpc_core::Channel::FromC(channel)->Ping(cq, tag);
219 }
220