The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)
https://grpc.io/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
8.3 KiB
225 lines
8.3 KiB
// |
|
// Copyright 2015 gRPC authors. |
|
// |
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
// you may not use this file except in compliance with the License. |
|
// You may obtain a copy of the License at |
|
// |
|
// http://www.apache.org/licenses/LICENSE-2.0 |
|
// |
|
// Unless required by applicable law or agreed to in writing, software |
|
// distributed under the License is distributed on an "AS IS" BASIS, |
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
// See the License for the specific language governing permissions and |
|
// limitations under the License. |
|
// |
|
|
|
#include "src/core/lib/surface/channel.h" |
|
|
|
#include "absl/log/check.h" |
|
|
|
#include <grpc/compression.h> |
|
#include <grpc/grpc.h> |
|
#include <grpc/impl/channel_arg_names.h> |
|
#include <grpc/support/alloc.h> |
|
#include <grpc/support/log.h> |
|
#include <grpc/support/port_platform.h> |
|
|
|
#include "src/core/channelz/channel_trace.h" |
|
#include "src/core/channelz/channelz.h" |
|
#include "src/core/lib/channel/channel_args.h" |
|
#include "src/core/lib/compression/compression_internal.h" |
|
#include "src/core/lib/debug/trace.h" |
|
#include "src/core/lib/iomgr/exec_ctx.h" |
|
#include "src/core/lib/surface/api_trace.h" |
|
#include "src/core/telemetry/stats.h" |
|
#include "src/core/telemetry/stats_data.h" |
|
|
|
namespace grpc_core { |
|
|
|
// |
|
// Channel::RegisteredCall |
|
// |
|
|
|
Channel::RegisteredCall::RegisteredCall(const char* method_arg, |
|
const char* host_arg) { |
|
path = Slice::FromCopiedString(method_arg); |
|
if (host_arg != nullptr && host_arg[0] != 0) { |
|
authority = Slice::FromCopiedString(host_arg); |
|
} |
|
} |
|
|
|
Channel::RegisteredCall::RegisteredCall(const RegisteredCall& other) |
|
: path(other.path.Ref()) { |
|
if (other.authority.has_value()) { |
|
authority = other.authority->Ref(); |
|
} |
|
} |
|
|
|
Channel::RegisteredCall::~RegisteredCall() {} |
|
|
|
// |
|
// Channel |
|
// |
|
|
|
Channel::Channel(std::string target, const ChannelArgs& channel_args) |
|
: target_(std::move(target)), |
|
channelz_node_(channel_args.GetObjectRef<channelz::ChannelNode>()), |
|
compression_options_(CompressionOptionsFromChannelArgs(channel_args)), |
|
call_arena_allocator_(MakeRefCounted<CallArenaAllocator>( |
|
channel_args.GetObject<ResourceQuota>() |
|
->memory_quota() |
|
->CreateMemoryOwner(), |
|
1024)) {} |
|
|
|
Channel::RegisteredCall* Channel::RegisterCall(const char* method, |
|
const char* host) { |
|
MutexLock lock(&mu_); |
|
auto key = std::make_pair(std::string(host != nullptr ? host : ""), |
|
std::string(method != nullptr ? method : "")); |
|
auto rc_posn = registration_table_.find(key); |
|
if (rc_posn != registration_table_.end()) { |
|
return &rc_posn->second; |
|
} |
|
auto insertion_result = registration_table_.insert( |
|
{std::move(key), RegisteredCall(method, host)}); |
|
return &insertion_result.first->second; |
|
} |
|
|
|
} // namespace grpc_core |
|
|
|
// |
|
// C-core API |
|
// |
|
|
|
void grpc_channel_destroy(grpc_channel* channel) { |
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; |
|
grpc_core::ExecCtx exec_ctx; |
|
GRPC_API_TRACE("grpc_channel_destroy(channel=%p)", 1, (channel)); |
|
grpc_channel_destroy_internal(channel); |
|
} |
|
|
|
grpc_call* 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) { |
|
CHECK(!reserved); |
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; |
|
grpc_core::ExecCtx exec_ctx; |
|
return grpc_core::Channel::FromC(channel)->CreateCall( |
|
parent_call, propagation_mask, completion_queue, nullptr, |
|
grpc_core::Slice(grpc_core::CSliceRef(method)), |
|
host != nullptr |
|
? absl::optional<grpc_core::Slice>(grpc_core::CSliceRef(*host)) |
|
: absl::nullopt, |
|
grpc_core::Timestamp::FromTimespecRoundUp(deadline), |
|
/*registered_method=*/false); |
|
} |
|
|
|
void* grpc_channel_register_call(grpc_channel* channel, const char* method, |
|
const char* host, void* reserved) { |
|
GRPC_API_TRACE( |
|
"grpc_channel_register_call(channel=%p, method=%s, host=%s, reserved=%p)", |
|
4, (channel, method, host, reserved)); |
|
CHECK(!reserved); |
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; |
|
grpc_core::ExecCtx exec_ctx; |
|
return grpc_core::Channel::FromC(channel)->RegisterCall(method, host); |
|
} |
|
|
|
grpc_call* 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) { |
|
auto* rc = |
|
static_cast<grpc_core::Channel::RegisteredCall*>(registered_call_handle); |
|
GRPC_API_TRACE( |
|
"grpc_channel_create_registered_call(" |
|
"channel=%p, parent_call=%p, propagation_mask=%x, completion_queue=%p, " |
|
"registered_call_handle=%p, " |
|
"deadline=gpr_timespec { tv_sec: %" PRId64 |
|
", tv_nsec: %d, clock_type: %d }, " |
|
"reserved=%p)", |
|
9, |
|
(channel, parent_call, (unsigned)propagation_mask, completion_queue, |
|
registered_call_handle, deadline.tv_sec, deadline.tv_nsec, |
|
(int)deadline.clock_type, reserved)); |
|
CHECK(!reserved); |
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; |
|
grpc_core::ExecCtx exec_ctx; |
|
return grpc_core::Channel::FromC(channel)->CreateCall( |
|
parent_call, propagation_mask, completion_queue, nullptr, rc->path.Ref(), |
|
rc->authority.has_value() |
|
? absl::optional<grpc_core::Slice>(rc->authority->Ref()) |
|
: absl::nullopt, |
|
grpc_core::Timestamp::FromTimespecRoundUp(deadline), |
|
/*registered_method=*/true); |
|
} |
|
|
|
char* grpc_channel_get_target(grpc_channel* channel) { |
|
GRPC_API_TRACE("grpc_channel_get_target(channel=%p)", 1, (channel)); |
|
auto target = grpc_core::Channel::FromC(channel)->target(); |
|
char* buffer = static_cast<char*>(gpr_zalloc(target.size() + 1)); |
|
memcpy(buffer, target.data(), target.size()); |
|
return buffer; |
|
} |
|
|
|
void grpc_channel_get_info(grpc_channel* channel, |
|
const grpc_channel_info* channel_info) { |
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; |
|
grpc_core::ExecCtx exec_ctx; |
|
grpc_core::Channel::FromC(channel)->GetInfo(channel_info); |
|
} |
|
|
|
void grpc_channel_reset_connect_backoff(grpc_channel* channel) { |
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; |
|
grpc_core::ExecCtx exec_ctx; |
|
GRPC_API_TRACE("grpc_channel_reset_connect_backoff(channel=%p)", 1, |
|
(channel)); |
|
grpc_core::Channel::FromC(channel)->ResetConnectionBackoff(); |
|
} |
|
|
|
int grpc_channel_support_connectivity_watcher(grpc_channel* channel) { |
|
return grpc_core::Channel::FromC(channel)->SupportsConnectivityWatcher(); |
|
} |
|
|
|
grpc_connectivity_state grpc_channel_check_connectivity_state( |
|
grpc_channel* channel, int try_to_connect) { |
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; |
|
grpc_core::ExecCtx exec_ctx; |
|
GRPC_API_TRACE( |
|
"grpc_channel_check_connectivity_state(channel=%p, try_to_connect=%d)", 2, |
|
(channel, try_to_connect)); |
|
return grpc_core::Channel::FromC(channel)->CheckConnectivityState( |
|
try_to_connect); |
|
} |
|
|
|
void grpc_channel_watch_connectivity_state( |
|
grpc_channel* channel, grpc_connectivity_state last_observed_state, |
|
gpr_timespec deadline, grpc_completion_queue* cq, void* tag) { |
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx; |
|
grpc_core::ExecCtx exec_ctx; |
|
GRPC_API_TRACE( |
|
"grpc_channel_watch_connectivity_state(" |
|
"channel=%p, last_observed_state=%d, " |
|
"deadline=gpr_timespec { tv_sec: %" PRId64 |
|
", tv_nsec: %d, clock_type: %d }, " |
|
"cq=%p, tag=%p)", |
|
7, |
|
(channel, (int)last_observed_state, deadline.tv_sec, deadline.tv_nsec, |
|
(int)deadline.clock_type, cq, tag)); |
|
return grpc_core::Channel::FromC(channel)->WatchConnectivityState( |
|
last_observed_state, grpc_core::Timestamp::FromTimespecRoundUp(deadline), |
|
cq, tag); |
|
} |
|
|
|
void grpc_channel_ping(grpc_channel* channel, grpc_completion_queue* cq, |
|
void* tag, void* reserved) { |
|
grpc_core::ExecCtx exec_ctx; |
|
GRPC_API_TRACE("grpc_channel_ping(channel=%p, cq=%p, tag=%p, reserved=%p)", 4, |
|
(channel, cq, tag, reserved)); |
|
CHECK_EQ(reserved, nullptr); |
|
grpc_core::Channel::FromC(channel)->Ping(cq, tag); |
|
}
|
|
|