Merge pull request #23756 from grpc/revert-23693-channel

Revert "Fold Channel and CompletionQueue from grpc_impl to grpc"
pull/23762/head
Karthik Ravi Shankar 5 years ago committed by GitHub
commit 75a3e1bb45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      BUILD
  2. 3
      BUILD.gn
  3. 6
      CMakeLists.txt
  4. 6
      Makefile
  5. 6
      build_autogenerated.yaml
  6. 3
      gRPC-C++.podspec
  7. 94
      include/grpcpp/channel.h
  8. 130
      include/grpcpp/channel_impl.h
  9. 24
      include/grpcpp/completion_queue_impl.h
  10. 14
      include/grpcpp/generic/generic_stub.h
  11. 5
      include/grpcpp/impl/codegen/async_generic_service.h
  12. 6
      include/grpcpp/impl/codegen/async_stream_impl.h
  13. 2
      include/grpcpp/impl/codegen/async_unary_call_impl.h
  14. 15
      include/grpcpp/impl/codegen/call.h
  15. 2
      include/grpcpp/impl/codegen/call_op_set.h
  16. 14
      include/grpcpp/impl/codegen/channel_interface.h
  17. 4
      include/grpcpp/impl/codegen/client_callback_impl.h
  18. 10
      include/grpcpp/impl/codegen/client_context_impl.h
  19. 3
      include/grpcpp/impl/codegen/client_interceptor.h
  20. 2
      include/grpcpp/impl/codegen/client_unary_call.h
  21. 426
      include/grpcpp/impl/codegen/completion_queue.h
  22. 454
      include/grpcpp/impl/codegen/completion_queue_impl.h
  23. 8
      include/grpcpp/impl/codegen/delegating_channel.h
  24. 11
      include/grpcpp/impl/codegen/intercepted_channel.h
  25. 4
      include/grpcpp/impl/codegen/server_context_impl.h
  26. 60
      include/grpcpp/impl/codegen/server_interface.h
  27. 18
      include/grpcpp/impl/codegen/service_type.h
  28. 8
      include/grpcpp/impl/codegen/sync_stream_impl.h
  29. 4
      include/grpcpp/server_builder.h
  30. 46
      include/grpcpp/server_impl.h
  31. 11
      src/cpp/client/channel_cc.cc
  32. 8
      src/cpp/client/client_context.cc
  33. 5
      src/cpp/client/secure_credentials.h
  34. 6
      src/cpp/common/completion_queue_cc.cc
  35. 4
      src/cpp/server/async_generic_service.cc
  36. 19
      src/cpp/server/server_builder.cc
  37. 4
      src/cpp/server/server_context.cc
  38. 6
      test/cpp/util/create_test_channel.h
  39. 3
      tools/doxygen/Doxyfile.c++
  40. 3
      tools/doxygen/Doxyfile.c++.internal

@ -220,8 +220,10 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpcpp/alarm.h", "include/grpcpp/alarm.h",
"include/grpcpp/alarm_impl.h", "include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h", "include/grpcpp/channel.h",
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h", "include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h", "include/grpcpp/completion_queue.h",
"include/grpcpp/completion_queue_impl.h",
"include/grpcpp/create_channel.h", "include/grpcpp/create_channel.h",
"include/grpcpp/create_channel_posix.h", "include/grpcpp/create_channel_posix.h",
"include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/ext/health_check_service_server_builder_option.h",
@ -2256,6 +2258,7 @@ grpc_cc_library(
"include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_interceptor.h",
"include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/client_unary_call.h",
"include/grpcpp/impl/codegen/completion_queue.h", "include/grpcpp/impl/codegen/completion_queue.h",
"include/grpcpp/impl/codegen/completion_queue_impl.h",
"include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/completion_queue_tag.h",
"include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/config.h",
"include/grpcpp/impl/codegen/core_codegen_interface.h", "include/grpcpp/impl/codegen/core_codegen_interface.h",

@ -1100,8 +1100,10 @@ config("grpc_config") {
"include/grpcpp/alarm.h", "include/grpcpp/alarm.h",
"include/grpcpp/alarm_impl.h", "include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h", "include/grpcpp/channel.h",
"include/grpcpp/channel_impl.h",
"include/grpcpp/client_context.h", "include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h", "include/grpcpp/completion_queue.h",
"include/grpcpp/completion_queue_impl.h",
"include/grpcpp/create_channel.h", "include/grpcpp/create_channel.h",
"include/grpcpp/create_channel_posix.h", "include/grpcpp/create_channel_posix.h",
"include/grpcpp/ext/health_check_service_server_builder_option.h", "include/grpcpp/ext/health_check_service_server_builder_option.h",
@ -1131,6 +1133,7 @@ config("grpc_config") {
"include/grpcpp/impl/codegen/client_interceptor.h", "include/grpcpp/impl/codegen/client_interceptor.h",
"include/grpcpp/impl/codegen/client_unary_call.h", "include/grpcpp/impl/codegen/client_unary_call.h",
"include/grpcpp/impl/codegen/completion_queue.h", "include/grpcpp/impl/codegen/completion_queue.h",
"include/grpcpp/impl/codegen/completion_queue_impl.h",
"include/grpcpp/impl/codegen/completion_queue_tag.h", "include/grpcpp/impl/codegen/completion_queue_tag.h",
"include/grpcpp/impl/codegen/config.h", "include/grpcpp/impl/codegen/config.h",
"include/grpcpp/impl/codegen/config_protobuf.h", "include/grpcpp/impl/codegen/config_protobuf.h",

@ -2744,8 +2744,10 @@ foreach(_hdr
include/grpcpp/alarm.h include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h include/grpcpp/alarm_impl.h
include/grpcpp/channel.h include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h include/grpcpp/client_context.h
include/grpcpp/completion_queue.h include/grpcpp/completion_queue.h
include/grpcpp/completion_queue_impl.h
include/grpcpp/create_channel.h include/grpcpp/create_channel.h
include/grpcpp/create_channel_posix.h include/grpcpp/create_channel_posix.h
include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/ext/health_check_service_server_builder_option.h
@ -2775,6 +2777,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/config_protobuf.h include/grpcpp/impl/codegen/config_protobuf.h
@ -3430,8 +3433,10 @@ foreach(_hdr
include/grpcpp/alarm.h include/grpcpp/alarm.h
include/grpcpp/alarm_impl.h include/grpcpp/alarm_impl.h
include/grpcpp/channel.h include/grpcpp/channel.h
include/grpcpp/channel_impl.h
include/grpcpp/client_context.h include/grpcpp/client_context.h
include/grpcpp/completion_queue.h include/grpcpp/completion_queue.h
include/grpcpp/completion_queue_impl.h
include/grpcpp/create_channel.h include/grpcpp/create_channel.h
include/grpcpp/create_channel_posix.h include/grpcpp/create_channel_posix.h
include/grpcpp/ext/health_check_service_server_builder_option.h include/grpcpp/ext/health_check_service_server_builder_option.h
@ -3461,6 +3466,7 @@ foreach(_hdr
include/grpcpp/impl/codegen/client_interceptor.h include/grpcpp/impl/codegen/client_interceptor.h
include/grpcpp/impl/codegen/client_unary_call.h include/grpcpp/impl/codegen/client_unary_call.h
include/grpcpp/impl/codegen/completion_queue.h include/grpcpp/impl/codegen/completion_queue.h
include/grpcpp/impl/codegen/completion_queue_impl.h
include/grpcpp/impl/codegen/completion_queue_tag.h include/grpcpp/impl/codegen/completion_queue_tag.h
include/grpcpp/impl/codegen/config.h include/grpcpp/impl/codegen/config.h
include/grpcpp/impl/codegen/config_protobuf.h include/grpcpp/impl/codegen/config_protobuf.h

@ -4872,8 +4872,10 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \ include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \ include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \ include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \ include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \ include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \ include/grpcpp/create_channel.h \
include/grpcpp/create_channel_posix.h \ include/grpcpp/create_channel_posix.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \
@ -4903,6 +4905,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/config_protobuf.h \ include/grpcpp/impl/codegen/config_protobuf.h \
@ -5556,8 +5559,10 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/alarm.h \ include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \ include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \ include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \ include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \ include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \ include/grpcpp/create_channel.h \
include/grpcpp/create_channel_posix.h \ include/grpcpp/create_channel_posix.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \
@ -5587,6 +5592,7 @@ PUBLIC_HEADERS_CXX += \
include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/config_protobuf.h \ include/grpcpp/impl/codegen/config_protobuf.h \

@ -2087,8 +2087,10 @@ libs:
- include/grpcpp/alarm.h - include/grpcpp/alarm.h
- include/grpcpp/alarm_impl.h - include/grpcpp/alarm_impl.h
- include/grpcpp/channel.h - include/grpcpp/channel.h
- include/grpcpp/channel_impl.h
- include/grpcpp/client_context.h - include/grpcpp/client_context.h
- include/grpcpp/completion_queue.h - include/grpcpp/completion_queue.h
- include/grpcpp/completion_queue_impl.h
- include/grpcpp/create_channel.h - include/grpcpp/create_channel.h
- include/grpcpp/create_channel_posix.h - include/grpcpp/create_channel_posix.h
- include/grpcpp/ext/health_check_service_server_builder_option.h - include/grpcpp/ext/health_check_service_server_builder_option.h
@ -2118,6 +2120,7 @@ libs:
- include/grpcpp/impl/codegen/client_interceptor.h - include/grpcpp/impl/codegen/client_interceptor.h
- include/grpcpp/impl/codegen/client_unary_call.h - include/grpcpp/impl/codegen/client_unary_call.h
- include/grpcpp/impl/codegen/completion_queue.h - include/grpcpp/impl/codegen/completion_queue.h
- include/grpcpp/impl/codegen/completion_queue_impl.h
- include/grpcpp/impl/codegen/completion_queue_tag.h - include/grpcpp/impl/codegen/completion_queue_tag.h
- include/grpcpp/impl/codegen/config.h - include/grpcpp/impl/codegen/config.h
- include/grpcpp/impl/codegen/config_protobuf.h - include/grpcpp/impl/codegen/config_protobuf.h
@ -2465,8 +2468,10 @@ libs:
- include/grpcpp/alarm.h - include/grpcpp/alarm.h
- include/grpcpp/alarm_impl.h - include/grpcpp/alarm_impl.h
- include/grpcpp/channel.h - include/grpcpp/channel.h
- include/grpcpp/channel_impl.h
- include/grpcpp/client_context.h - include/grpcpp/client_context.h
- include/grpcpp/completion_queue.h - include/grpcpp/completion_queue.h
- include/grpcpp/completion_queue_impl.h
- include/grpcpp/create_channel.h - include/grpcpp/create_channel.h
- include/grpcpp/create_channel_posix.h - include/grpcpp/create_channel_posix.h
- include/grpcpp/ext/health_check_service_server_builder_option.h - include/grpcpp/ext/health_check_service_server_builder_option.h
@ -2496,6 +2501,7 @@ libs:
- include/grpcpp/impl/codegen/client_interceptor.h - include/grpcpp/impl/codegen/client_interceptor.h
- include/grpcpp/impl/codegen/client_unary_call.h - include/grpcpp/impl/codegen/client_unary_call.h
- include/grpcpp/impl/codegen/completion_queue.h - include/grpcpp/impl/codegen/completion_queue.h
- include/grpcpp/impl/codegen/completion_queue_impl.h
- include/grpcpp/impl/codegen/completion_queue_tag.h - include/grpcpp/impl/codegen/completion_queue_tag.h
- include/grpcpp/impl/codegen/config.h - include/grpcpp/impl/codegen/config.h
- include/grpcpp/impl/codegen/config_protobuf.h - include/grpcpp/impl/codegen/config_protobuf.h

@ -79,8 +79,10 @@ Pod::Spec.new do |s|
ss.source_files = 'include/grpcpp/alarm.h', ss.source_files = 'include/grpcpp/alarm.h',
'include/grpcpp/alarm_impl.h', 'include/grpcpp/alarm_impl.h',
'include/grpcpp/channel.h', 'include/grpcpp/channel.h',
'include/grpcpp/channel_impl.h',
'include/grpcpp/client_context.h', 'include/grpcpp/client_context.h',
'include/grpcpp/completion_queue.h', 'include/grpcpp/completion_queue.h',
'include/grpcpp/completion_queue_impl.h',
'include/grpcpp/create_channel.h', 'include/grpcpp/create_channel.h',
'include/grpcpp/create_channel_posix.h', 'include/grpcpp/create_channel_posix.h',
'include/grpcpp/ext/health_check_service_server_builder_option.h', 'include/grpcpp/ext/health_check_service_server_builder_option.h',
@ -110,6 +112,7 @@ Pod::Spec.new do |s|
'include/grpcpp/impl/codegen/client_interceptor.h', 'include/grpcpp/impl/codegen/client_interceptor.h',
'include/grpcpp/impl/codegen/client_unary_call.h', 'include/grpcpp/impl/codegen/client_unary_call.h',
'include/grpcpp/impl/codegen/completion_queue.h', 'include/grpcpp/impl/codegen/completion_queue.h',
'include/grpcpp/impl/codegen/completion_queue_impl.h',
'include/grpcpp/impl/codegen/completion_queue_tag.h', 'include/grpcpp/impl/codegen/completion_queue_tag.h',
'include/grpcpp/impl/codegen/config.h', 'include/grpcpp/impl/codegen/config.h',
'include/grpcpp/impl/codegen/core_codegen.h', 'include/grpcpp/impl/codegen/core_codegen.h',

@ -19,29 +19,11 @@
#ifndef GRPCPP_CHANNEL_H #ifndef GRPCPP_CHANNEL_H
#define GRPCPP_CHANNEL_H #define GRPCPP_CHANNEL_H
#include <memory> #include <grpcpp/channel_impl.h>
#include <grpc/grpc.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/completion_queue.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/sync.h>
struct grpc_channel;
namespace grpc { namespace grpc {
namespace testing {
class ChannelTestPeer;
} // namespace testing
std::shared_ptr<Channel> CreateChannelInternal( typedef ::grpc_impl::Channel Channel;
const std::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
namespace experimental { namespace experimental {
/// Resets the channel's connection backoff. /// Resets the channel's connection backoff.
@ -50,78 +32,6 @@ namespace experimental {
void ChannelResetConnectionBackoff(Channel* channel); void ChannelResetConnectionBackoff(Channel* channel);
} // namespace experimental } // namespace experimental
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ::grpc::ChannelInterface,
public ::grpc::internal::CallHook,
public std::enable_shared_from_this<Channel>,
private ::grpc::GrpcLibraryCodegen {
public:
~Channel();
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect) override;
/// Returns the LB policy name, or the empty string if not yet available.
std::string GetLoadBalancingPolicyName() const;
/// Returns the service config in JSON form, or the empty string if
/// not available.
std::string GetServiceConfigJSON() const;
private:
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
friend class ::grpc::testing::ChannelTestPeer;
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> grpc::CreateChannelInternal(
const std::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class ::grpc::internal::InterceptedChannel;
Channel(const std::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context,
::grpc::CompletionQueue* cq) override;
void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops,
::grpc::internal::Call* call) override;
void* RegisterMethod(const char* method) override;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
::grpc::CompletionQueue* cq, void* tag) override;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) override;
::grpc::CompletionQueue* CallbackCQ() override;
::grpc::internal::Call CreateCallInternal(
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, ::grpc::CompletionQueue* cq,
size_t interceptor_pos) override;
const std::string host_;
grpc_channel* const c_channel_; // owned
// mu_ protects callback_cq_ (the per-channel callbackable completion queue)
grpc::internal::Mutex mu_;
// callback_cq_ references the callbackable completion queue associated
// with this channel (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the channel; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown).
::grpc::CompletionQueue* callback_cq_ = nullptr;
std::vector<
std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators_;
};
} // namespace grpc } // namespace grpc
#endif // GRPCPP_CHANNEL_H #endif // GRPCPP_CHANNEL_H

@ -0,0 +1,130 @@
/*
*
* 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.
*
*/
#ifndef GRPCPP_CHANNEL_IMPL_H
#define GRPCPP_CHANNEL_IMPL_H
#include <memory>
#include <grpc/grpc.h>
#include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/sync.h>
struct grpc_channel;
namespace grpc {
namespace testing {
class ChannelTestPeer;
} // namespace testing
std::shared_ptr<::grpc_impl::Channel> CreateChannelInternal(
const std::string& host, grpc_channel* c_channel,
std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace grpc
namespace grpc_impl {
namespace experimental {
/// Resets the channel's connection backoff.
/// TODO(roth): Once we see whether this proves useful, either create a gRFC
/// and change this to be a method of the Channel class, or remove it.
void ChannelResetConnectionBackoff(Channel* channel);
} // namespace experimental
/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
class Channel final : public ::grpc::ChannelInterface,
public ::grpc::internal::CallHook,
public std::enable_shared_from_this<Channel>,
private ::grpc::GrpcLibraryCodegen {
public:
~Channel();
/// Get the current channel state. If the channel is in IDLE and
/// \a try_to_connect is set to true, try to connect.
grpc_connectivity_state GetState(bool try_to_connect) override;
/// Returns the LB policy name, or the empty string if not yet available.
std::string GetLoadBalancingPolicyName() const;
/// Returns the service config in JSON form, or the empty string if
/// not available.
std::string GetServiceConfigJSON() const;
private:
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
friend class ::grpc::testing::ChannelTestPeer;
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> grpc::CreateChannelInternal(
const std::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class ::grpc::internal::InterceptedChannel;
Channel(const std::string& host, grpc_channel* c_channel,
std::vector<std::unique_ptr<
::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
::grpc::internal::Call CreateCall(const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context,
::grpc_impl::CompletionQueue* cq) override;
void PerformOpsOnCall(::grpc::internal::CallOpSetInterface* ops,
::grpc::internal::Call* call) override;
void* RegisterMethod(const char* method) override;
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline,
::grpc_impl::CompletionQueue* cq,
void* tag) override;
bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) override;
::grpc_impl::CompletionQueue* CallbackCQ() override;
::grpc::internal::Call CreateCallInternal(
const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, ::grpc_impl::CompletionQueue* cq,
size_t interceptor_pos) override;
const std::string host_;
grpc_channel* const c_channel_; // owned
// mu_ protects callback_cq_ (the per-channel callbackable completion queue)
grpc::internal::Mutex mu_;
// callback_cq_ references the callbackable completion queue associated
// with this channel (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the channel; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown).
::grpc_impl::CompletionQueue* callback_cq_ = nullptr;
std::vector<
std::unique_ptr<::grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_creators_;
};
} // namespace grpc_impl
#endif // GRPCPP_CHANNEL_IMPL_H

@ -0,0 +1,24 @@
/*
*
* Copyright 2019 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.
*
*/
#ifndef GRPCPP_COMPLETION_QUEUE_IMPL_H
#define GRPCPP_COMPLETION_QUEUE_IMPL_H
#include <grpcpp/impl/codegen/completion_queue_impl.h>
#endif // GRPCPP_COMPLETION_QUEUE_IMPL_H

@ -29,9 +29,10 @@
#include <grpcpp/support/client_callback_impl.h> #include <grpcpp/support/client_callback_impl.h>
#include <grpcpp/support/status.h> #include <grpcpp/support/status.h>
namespace grpc { namespace grpc_impl {
class CompletionQueue; class CompletionQueue;
} // namespace grpc_impl
namespace grpc {
typedef ::grpc_impl::ClientAsyncReaderWriter<ByteBuffer, ByteBuffer> typedef ::grpc_impl::ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
GenericClientAsyncReaderWriter; GenericClientAsyncReaderWriter;
@ -54,7 +55,7 @@ class TemplatedGenericStub final {
std::unique_ptr< std::unique_ptr<
::grpc_impl::ClientAsyncReaderWriter<RequestType, ResponseType>> ::grpc_impl::ClientAsyncReaderWriter<RequestType, ResponseType>>
PrepareCall(ClientContext* context, const std::string& method, PrepareCall(ClientContext* context, const std::string& method,
::grpc::CompletionQueue* cq) { ::grpc_impl::CompletionQueue* cq) {
return CallInternal(channel_.get(), context, method, cq, false, nullptr); return CallInternal(channel_.get(), context, method, cq, false, nullptr);
} }
@ -64,7 +65,8 @@ class TemplatedGenericStub final {
/// succeeded (i.e. the call won't proceed if the return value is nullptr). /// succeeded (i.e. the call won't proceed if the return value is nullptr).
std::unique_ptr<::grpc_impl::ClientAsyncResponseReader<ResponseType>> std::unique_ptr<::grpc_impl::ClientAsyncResponseReader<ResponseType>>
PrepareUnaryCall(ClientContext* context, const std::string& method, PrepareUnaryCall(ClientContext* context, const std::string& method,
const RequestType& request, ::grpc::CompletionQueue* cq) { const RequestType& request,
::grpc_impl::CompletionQueue* cq) {
return std::unique_ptr< return std::unique_ptr<
::grpc_impl::ClientAsyncResponseReader<ResponseType>>( ::grpc_impl::ClientAsyncResponseReader<ResponseType>>(
grpc_impl::internal::ClientAsyncResponseReaderFactory< grpc_impl::internal::ClientAsyncResponseReaderFactory<
@ -84,7 +86,7 @@ class TemplatedGenericStub final {
std::unique_ptr< std::unique_ptr<
::grpc_impl::ClientAsyncReaderWriter<RequestType, ResponseType>> ::grpc_impl::ClientAsyncReaderWriter<RequestType, ResponseType>>
Call(ClientContext* context, const std::string& method, Call(ClientContext* context, const std::string& method,
::grpc::CompletionQueue* cq, void* tag) { ::grpc_impl::CompletionQueue* cq, void* tag) {
return CallInternal(channel_.get(), context, method, cq, true, tag); return CallInternal(channel_.get(), context, method, cq, true, tag);
} }
@ -203,7 +205,7 @@ class TemplatedGenericStub final {
std::unique_ptr< std::unique_ptr<
::grpc_impl::ClientAsyncReaderWriter<RequestType, ResponseType>> ::grpc_impl::ClientAsyncReaderWriter<RequestType, ResponseType>>
CallInternal(grpc::ChannelInterface* channel, ClientContext* context, CallInternal(grpc::ChannelInterface* channel, ClientContext* context,
const std::string& method, ::grpc::CompletionQueue* cq, const std::string& method, ::grpc_impl::CompletionQueue* cq,
bool start, void* tag) { bool start, void* tag) {
return std::unique_ptr< return std::unique_ptr<
::grpc_impl::ClientAsyncReaderWriter<RequestType, ResponseType>>( ::grpc_impl::ClientAsyncReaderWriter<RequestType, ResponseType>>(

@ -80,8 +80,9 @@ class AsyncGenericService final {
void RequestCall(GenericServerContext* ctx, void RequestCall(GenericServerContext* ctx,
GenericServerAsyncReaderWriter* reader_writer, GenericServerAsyncReaderWriter* reader_writer,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, void* tag); ::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag);
private: private:
friend class grpc_impl::Server; friend class grpc_impl::Server;

@ -178,7 +178,7 @@ class ClientAsyncReaderFactory {
/// used to send to the server when starting the call. /// used to send to the server when starting the call.
template <class W> template <class W>
static ClientAsyncReader<R>* Create(::grpc::ChannelInterface* channel, static ClientAsyncReader<R>* Create(::grpc::ChannelInterface* channel,
::grpc::CompletionQueue* cq, ::grpc_impl::CompletionQueue* cq,
const ::grpc::internal::RpcMethod& method, const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, ::grpc_impl::ClientContext* context,
const W& request, bool start, void* tag) { const W& request, bool start, void* tag) {
@ -327,7 +327,7 @@ class ClientAsyncWriterFactory {
/// method of this instance. /// method of this instance.
template <class R> template <class R>
static ClientAsyncWriter<W>* Create(::grpc::ChannelInterface* channel, static ClientAsyncWriter<W>* Create(::grpc::ChannelInterface* channel,
::grpc::CompletionQueue* cq, ::grpc_impl::CompletionQueue* cq,
const ::grpc::internal::RpcMethod& method, const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, ::grpc_impl::ClientContext* context,
R* response, bool start, void* tag) { R* response, bool start, void* tag) {
@ -493,7 +493,7 @@ class ClientAsyncReaderWriterFactory {
/// Note that \a context will be used to fill in custom initial metadata /// Note that \a context will be used to fill in custom initial metadata
/// used to send to the server when starting the call. /// used to send to the server when starting the call.
static ClientAsyncReaderWriter<W, R>* Create( static ClientAsyncReaderWriter<W, R>* Create(
::grpc::ChannelInterface* channel, ::grpc::CompletionQueue* cq, ::grpc::ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq,
const ::grpc::internal::RpcMethod& method, const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, bool start, void* tag) { ::grpc_impl::ClientContext* context, bool start, void* tag) {
::grpc::internal::Call call = channel->CreateCall(method, context, cq); ::grpc::internal::Call call = channel->CreateCall(method, context, cq);

@ -77,7 +77,7 @@ class ClientAsyncResponseReaderFactory {
/// used to send to the server when starting the call. /// used to send to the server when starting the call.
template <class W> template <class W>
static ClientAsyncResponseReader<R>* Create( static ClientAsyncResponseReader<R>* Create(
::grpc::ChannelInterface* channel, ::grpc::CompletionQueue* cq, ::grpc::ChannelInterface* channel, ::grpc_impl::CompletionQueue* cq,
const ::grpc::internal::RpcMethod& method, const ::grpc::internal::RpcMethod& method,
::grpc_impl::ClientContext* context, const W& request, bool start) { ::grpc_impl::ClientContext* context, const W& request, bool start) {
::grpc::internal::Call call = channel->CreateCall(method, context, cq); ::grpc::internal::Call call = channel->CreateCall(method, context, cq);

@ -21,8 +21,11 @@
#include <grpc/impl/codegen/grpc_types.h> #include <grpc/impl/codegen/grpc_types.h>
#include <grpcpp/impl/codegen/call_hook.h> #include <grpcpp/impl/codegen/call_hook.h>
namespace grpc { namespace grpc_impl {
class CompletionQueue; class CompletionQueue;
}
namespace grpc {
namespace experimental { namespace experimental {
class ClientRpcInfo; class ClientRpcInfo;
class ServerRpcInfo; class ServerRpcInfo;
@ -40,13 +43,13 @@ class Call final {
call_(nullptr), call_(nullptr),
max_receive_message_size_(-1) {} max_receive_message_size_(-1) {}
/** call is owned by the caller */ /** call is owned by the caller */
Call(grpc_call* call, CallHook* call_hook, ::grpc::CompletionQueue* cq) Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq)
: call_hook_(call_hook), : call_hook_(call_hook),
cq_(cq), cq_(cq),
call_(call), call_(call),
max_receive_message_size_(-1) {} max_receive_message_size_(-1) {}
Call(grpc_call* call, CallHook* call_hook, ::grpc::CompletionQueue* cq, Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq,
experimental::ClientRpcInfo* rpc_info) experimental::ClientRpcInfo* rpc_info)
: call_hook_(call_hook), : call_hook_(call_hook),
cq_(cq), cq_(cq),
@ -54,7 +57,7 @@ class Call final {
max_receive_message_size_(-1), max_receive_message_size_(-1),
client_rpc_info_(rpc_info) {} client_rpc_info_(rpc_info) {}
Call(grpc_call* call, CallHook* call_hook, ::grpc::CompletionQueue* cq, Call(grpc_call* call, CallHook* call_hook, ::grpc_impl::CompletionQueue* cq,
int max_receive_message_size, experimental::ServerRpcInfo* rpc_info) int max_receive_message_size, experimental::ServerRpcInfo* rpc_info)
: call_hook_(call_hook), : call_hook_(call_hook),
cq_(cq), cq_(cq),
@ -67,7 +70,7 @@ class Call final {
} }
grpc_call* call() const { return call_; } grpc_call* call() const { return call_; }
::grpc::CompletionQueue* cq() const { return cq_; } ::grpc_impl::CompletionQueue* cq() const { return cq_; }
int max_receive_message_size() const { return max_receive_message_size_; } int max_receive_message_size() const { return max_receive_message_size_; }
@ -81,7 +84,7 @@ class Call final {
private: private:
CallHook* call_hook_; CallHook* call_hook_;
::grpc::CompletionQueue* cq_; ::grpc_impl::CompletionQueue* cq_;
grpc_call* call_; grpc_call* call_;
int max_receive_message_size_; int max_receive_message_size_;
experimental::ClientRpcInfo* client_rpc_info_ = nullptr; experimental::ClientRpcInfo* client_rpc_info_ = nullptr;

@ -30,7 +30,7 @@
#include <grpcpp/impl/codegen/call_hook.h> #include <grpcpp/impl/codegen/call_hook.h>
#include <grpcpp/impl/codegen/call_op_set_interface.h> #include <grpcpp/impl/codegen/call_op_set_interface.h>
#include <grpcpp/impl/codegen/client_context_impl.h> #include <grpcpp/impl/codegen/client_context_impl.h>
#include <grpcpp/impl/codegen/completion_queue.h> #include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h> #include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/config.h> #include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h> #include <grpcpp/impl/codegen/core_codegen_interface.h>

@ -26,6 +26,7 @@
namespace grpc_impl { namespace grpc_impl {
class ClientContext; class ClientContext;
class CompletionQueue;
template <class R> template <class R>
class ClientReader; class ClientReader;
template <class W> template <class W>
@ -55,7 +56,6 @@ class ClientCallbackUnaryFactory;
namespace grpc { namespace grpc {
class ChannelInterface; class ChannelInterface;
class CompletionQueue;
namespace experimental { namespace experimental {
class DelegatingChannel; class DelegatingChannel;
@ -82,7 +82,7 @@ class ChannelInterface {
/// deadline expires. \a GetState needs to called to get the current state. /// deadline expires. \a GetState needs to called to get the current state.
template <typename T> template <typename T>
void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline, void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
::grpc::CompletionQueue* cq, void* tag) { ::grpc_impl::CompletionQueue* cq, void* tag) {
TimePoint<T> deadline_tp(deadline); TimePoint<T> deadline_tp(deadline);
NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag); NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
} }
@ -136,13 +136,13 @@ class ChannelInterface {
friend class ::grpc::internal::InterceptedChannel; friend class ::grpc::internal::InterceptedChannel;
virtual internal::Call CreateCall(const internal::RpcMethod& method, virtual internal::Call CreateCall(const internal::RpcMethod& method,
::grpc_impl::ClientContext* context, ::grpc_impl::ClientContext* context,
::grpc::CompletionQueue* cq) = 0; ::grpc_impl::CompletionQueue* cq) = 0;
virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops, virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
internal::Call* call) = 0; internal::Call* call) = 0;
virtual void* RegisterMethod(const char* method) = 0; virtual void* RegisterMethod(const char* method) = 0;
virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline, gpr_timespec deadline,
::grpc::CompletionQueue* cq, ::grpc_impl::CompletionQueue* cq,
void* tag) = 0; void* tag) = 0;
virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline) = 0; gpr_timespec deadline) = 0;
@ -156,8 +156,8 @@ class ChannelInterface {
// change (even though this is private and non-API) // change (even though this is private and non-API)
virtual internal::Call CreateCallInternal( virtual internal::Call CreateCallInternal(
const internal::RpcMethod& /*method*/, const internal::RpcMethod& /*method*/,
::grpc_impl::ClientContext* /*context*/, ::grpc::CompletionQueue* /*cq*/, ::grpc_impl::ClientContext* /*context*/,
size_t /*interceptor_pos*/) { ::grpc_impl::CompletionQueue* /*cq*/, size_t /*interceptor_pos*/) {
return internal::Call(); return internal::Call();
} }
@ -169,7 +169,7 @@ class ChannelInterface {
// Returns nullptr (rather than being pure) since this is a post-1.0 method // Returns nullptr (rather than being pure) since this is a post-1.0 method
// and adding a new pure method to an interface would be a breaking change // and adding a new pure method to an interface would be a breaking change
// (even though this is private and non-API) // (even though this is private and non-API)
virtual ::grpc::CompletionQueue* CallbackCQ() { return nullptr; } virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; }
}; };
} // namespace grpc } // namespace grpc

@ -29,13 +29,13 @@
#include <grpcpp/impl/codegen/status.h> #include <grpcpp/impl/codegen/status.h>
namespace grpc { namespace grpc {
class Channel;
namespace internal { namespace internal {
class RpcMethod; class RpcMethod;
} // namespace internal } // namespace internal
} // namespace grpc } // namespace grpc
namespace grpc_impl { namespace grpc_impl {
class Channel;
class ClientContext; class ClientContext;
namespace internal { namespace internal {
@ -60,7 +60,7 @@ class CallbackUnaryCallImpl {
::grpc_impl::ClientContext* context, ::grpc_impl::ClientContext* context,
const InputMessage* request, OutputMessage* result, const InputMessage* request, OutputMessage* result,
std::function<void(::grpc::Status)> on_completion) { std::function<void(::grpc::Status)> on_completion) {
::grpc::CompletionQueue* cq = channel->CallbackCQ(); ::grpc_impl::CompletionQueue* cq = channel->CallbackCQ();
GPR_CODEGEN_ASSERT(cq != nullptr); GPR_CODEGEN_ASSERT(cq != nullptr);
grpc::internal::Call call(channel->CreateCall(method, context, cq)); grpc::internal::Call call(channel->CreateCall(method, context, cq));

@ -59,9 +59,7 @@ struct grpc_call;
namespace grpc { namespace grpc {
class CallCredentials; class CallCredentials;
class Channel;
class ChannelInterface; class ChannelInterface;
class CompletionQueue;
namespace internal { namespace internal {
class RpcMethod; class RpcMethod;
@ -91,6 +89,8 @@ class ClientCallbackUnaryImpl;
class ClientContextAccessor; class ClientContextAccessor;
} // namespace internal } // namespace internal
class Channel;
class CompletionQueue;
class ServerContext; class ServerContext;
template <class R> template <class R>
class ClientReader; class ClientReader;
@ -417,7 +417,7 @@ class ClientContext {
friend class ::grpc::testing::InteropClientContextInspector; friend class ::grpc::testing::InteropClientContextInspector;
friend class ::grpc::internal::CallOpClientRecvStatus; friend class ::grpc::internal::CallOpClientRecvStatus;
friend class ::grpc::internal::CallOpRecvInitialMetadata; friend class ::grpc::internal::CallOpRecvInitialMetadata;
friend class ::grpc::Channel; friend class ::grpc_impl::Channel;
template <class R> template <class R>
friend class ::grpc_impl::ClientReader; friend class ::grpc_impl::ClientReader;
template <class W> template <class W>
@ -452,7 +452,7 @@ class ClientContext {
grpc_call* call() const { return call_; } grpc_call* call() const { return call_; }
void set_call(grpc_call* call, void set_call(grpc_call* call,
const std::shared_ptr<::grpc::Channel>& channel); const std::shared_ptr<::grpc_impl::Channel>& channel);
grpc::experimental::ClientRpcInfo* set_client_rpc_info( grpc::experimental::ClientRpcInfo* set_client_rpc_info(
const char* method, grpc::internal::RpcMethod::RpcType type, const char* method, grpc::internal::RpcMethod::RpcType type,
@ -488,7 +488,7 @@ class ClientContext {
bool wait_for_ready_explicitly_set_; bool wait_for_ready_explicitly_set_;
bool idempotent_; bool idempotent_;
bool cacheable_; bool cacheable_;
std::shared_ptr<::grpc::Channel> channel_; std::shared_ptr<::grpc_impl::Channel> channel_;
grpc::internal::Mutex mu_; grpc::internal::Mutex mu_;
grpc_call* call_; grpc_call* call_;
bool call_canceled_; bool call_canceled_;

@ -28,13 +28,12 @@
namespace grpc_impl { namespace grpc_impl {
class Channel;
class ClientContext; class ClientContext;
} // namespace grpc_impl } // namespace grpc_impl
namespace grpc { namespace grpc {
class Channel;
namespace internal { namespace internal {
class InterceptorBatchMethodsImpl; class InterceptorBatchMethodsImpl;
} }

@ -49,7 +49,7 @@ class BlockingUnaryCallImpl {
BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method, BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method,
grpc_impl::ClientContext* context, grpc_impl::ClientContext* context,
const InputMessage& request, OutputMessage* result) { const InputMessage& request, OutputMessage* result) {
::grpc::CompletionQueue cq(grpc_completion_queue_attributes{ ::grpc_impl::CompletionQueue cq(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING, GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
nullptr}); // Pluckable completion queue nullptr}); // Pluckable completion queue
::grpc::internal::Call call(channel->CreateCall(method, context, &cq)); ::grpc::internal::Call call(channel->CreateCall(method, context, &cq));

@ -16,435 +16,15 @@
* *
*/ */
/// A completion queue implements a concurrent producer-consumer queue, with
/// two main API-exposed methods: \a Next and \a AsyncNext. These
/// methods are the essential component of the gRPC C++ asynchronous API.
/// There is also a \a Shutdown method to indicate that a given completion queue
/// will no longer have regular events. This must be called before the
/// completion queue is destroyed.
/// All completion queue APIs are thread-safe and may be used concurrently with
/// any other completion queue API invocation; it is acceptable to have
/// multiple threads calling \a Next or \a AsyncNext on the same or different
/// completion queues, or to call these methods concurrently with a \a Shutdown
/// elsewhere.
/// \remark{All other API calls on completion queue should be completed before
/// a completion queue destructor is called.}
#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H #ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H
#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H #define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H
#include <list> #include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpc/impl/codegen/atm.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/sync.h>
#include <grpcpp/impl/codegen/time.h>
struct grpc_completion_queue;
namespace grpc_impl {
class Server;
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
class ServerContextBase;
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler;
template <::grpc::StatusCode code>
class ErrorMethodHandler;
} // namespace internal
} // namespace grpc_impl
namespace grpc { namespace grpc {
class Channel; typedef ::grpc_impl::CompletionQueue CompletionQueue;
class ChannelInterface; typedef ::grpc_impl::ServerCompletionQueue ServerCompletionQueue;
class ServerBuilder;
class ServerInterface;
namespace internal {
class CompletionQueueTag;
class RpcMethod;
template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>
class CallOpSet;
} // namespace internal
extern CoreCodegenInterface* g_core_codegen_interface;
/// A thin wrapper around \ref grpc_completion_queue (see \ref
/// src/core/lib/surface/completion_queue.h).
/// See \ref doc/cpp/perf_notes.md for notes on best practices for high
/// performance servers.
class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
public:
/// Default constructor. Implicitly creates a \a grpc_completion_queue
/// instance.
CompletionQueue()
: CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING,
nullptr}) {}
/// Wrap \a take, taking ownership of the instance.
///
/// \param take The completion queue instance to wrap. Ownership is taken.
explicit CompletionQueue(grpc_completion_queue* take);
/// Destructor. Destroys the owned wrapped completion queue / instance.
~CompletionQueue() {
::grpc::g_core_codegen_interface->grpc_completion_queue_destroy(cq_);
}
/// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
enum NextStatus {
SHUTDOWN, ///< The completion queue has been shutdown and fully-drained
GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
///< associated value; \a ok indicating its success.
TIMEOUT ///< deadline was reached.
};
/// Read from the queue, blocking until an event is available or the queue is
/// shutting down.
///
/// \param tag [out] Updated to point to the read event's tag.
/// \param ok [out] true if read a successful event, false otherwise.
///
/// Note that each tag sent to the completion queue (through RPC operations
/// or alarms) will be delivered out of the completion queue by a call to
/// Next (or a related method), regardless of whether the operation succeeded
/// or not. Success here means that this operation completed in the normal
/// valid manner.
///
/// Server-side RPC request: \a ok indicates that the RPC has indeed
/// been started. If it is false, the server has been Shutdown
/// before this particular call got matched to an incoming RPC.
///
/// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is
/// going to go to the wire. If it is false, it not going to the wire. This
/// would happen if the channel is either permanently broken or
/// transiently broken but with the fail-fast option. (Note that async unary
/// RPCs don't post a CQ tag at this point, nor do client-streaming
/// or bidi-streaming RPCs that have the initial metadata corked option set.)
///
/// Client-side Write, Client-side WritesDone, Server-side Write,
/// Server-side Finish, Server-side SendInitialMetadata (which is
/// typically included in Write or Finish when not done explicitly):
/// \a ok means that the data/metadata/status/etc is going to go to the
/// wire. If it is false, it not going to the wire because the call
/// is already dead (i.e., canceled, deadline expired, other side
/// dropped the channel, etc).
///
/// Client-side Read, Server-side Read, Client-side
/// RecvInitialMetadata (which is typically included in Read if not
/// done explicitly): \a ok indicates whether there is a valid message
/// that got read. If not, you know that there are certainly no more
/// messages that can ever be read from this stream. For the client-side
/// operations, this only happens because the call is dead. For the
/// server-sider operation, though, this could happen because the client
/// has done a WritesDone already.
///
/// Client-side Finish: \a ok should always be true
///
/// Server-side AsyncNotifyWhenDone: \a ok should always be true
///
/// Alarm: \a ok is true if it expired, false if it was canceled
///
/// \return true if got an event, false if the queue is fully drained and
/// shut down.
bool Next(void** tag, bool* ok) {
return (AsyncNextInternal(tag, ok,
::grpc::g_core_codegen_interface->gpr_inf_future(
GPR_CLOCK_REALTIME)) != SHUTDOWN);
}
/// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param tag [out] Upon success, updated to point to the event's tag.
/// \param ok [out] Upon success, true if a successful event, false otherwise
/// See documentation for CompletionQueue::Next for explanation of ok
/// \param deadline [in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T>
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
::grpc::TimePoint<T> deadline_tp(deadline);
return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
}
/// EXPERIMENTAL
/// First executes \a F, then reads from the queue, blocking up to
/// \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param f [in] Function to execute before calling AsyncNext on this queue.
/// \param tag [out] Upon success, updated to point to the event's tag.
/// \param ok [out] Upon success, true if read a regular event, false
/// otherwise.
/// \param deadline [in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T, typename F>
NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) {
CompletionQueueTLSCache cache = CompletionQueueTLSCache(this);
f();
if (cache.Flush(tag, ok)) {
return GOT_EVENT;
} else {
return AsyncNext(tag, ok, deadline);
}
}
/// Request the shutdown of the queue.
///
/// \warning This method must be called at some point if this completion queue
/// is accessed with Next or AsyncNext. \a Next will not return false
/// until this method has been called and all pending tags have been drained.
/// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .)
/// Only once either one of these methods does that (that is, once the queue
/// has been \em drained) can an instance of this class be destroyed.
/// Also note that applications must ensure that no work is enqueued on this
/// completion queue after this method is called.
void Shutdown();
/// Returns a \em raw pointer to the underlying \a grpc_completion_queue
/// instance.
///
/// \warning Remember that the returned instance is owned. No transfer of
/// owership is performed.
grpc_completion_queue* cq() { return cq_; }
protected:
/// Private constructor of CompletionQueue only visible to friend classes
CompletionQueue(const grpc_completion_queue_attributes& attributes) {
cq_ = ::grpc::g_core_codegen_interface->grpc_completion_queue_create(
::grpc::g_core_codegen_interface->grpc_completion_queue_factory_lookup(
&attributes),
&attributes, NULL);
InitialAvalanching(); // reserve this for the future shutdown
}
private:
// Friends for access to server registration lists that enable checking and
// logging on shutdown
friend class ::grpc::ServerBuilder;
friend class ::grpc_impl::Server;
// Friend synchronous wrappers so that they can access Pluck(), which is
// a semi-private API geared towards the synchronous implementation.
template <class R>
friend class ::grpc_impl::ClientReader;
template <class W>
friend class ::grpc_impl::ClientWriter;
template <class W, class R>
friend class ::grpc_impl::ClientReaderWriter;
template <class R>
friend class ::grpc_impl::ServerReader;
template <class W>
friend class ::grpc_impl::ServerWriter;
template <class W, class R>
friend class ::grpc_impl::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc_impl::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc_impl::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc_impl::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
friend class ::grpc_impl::internal::TemplatedBidiStreamingHandler;
template <::grpc::StatusCode code>
friend class ::grpc_impl::internal::ErrorMethodHandler;
friend class ::grpc_impl::ServerContextBase;
friend class ::grpc::ServerInterface;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
// Friends that need access to constructor for callback CQ
friend class ::grpc::Channel;
// For access to Register/CompleteAvalanching
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>
friend class ::grpc::internal::CallOpSet;
/// EXPERIMENTAL
/// Creates a Thread Local cache to store the first event
/// On this completion queue queued from this thread. Once
/// initialized, it must be flushed on the same thread.
class CompletionQueueTLSCache {
public:
CompletionQueueTLSCache(CompletionQueue* cq);
~CompletionQueueTLSCache();
bool Flush(void** tag, bool* ok);
private:
CompletionQueue* cq_;
bool flushed_;
};
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
/// Wraps \a grpc_completion_queue_pluck.
/// \warning Must not be mixed with calls to \a Next.
bool Pluck(::grpc::internal::CompletionQueueTag* tag) {
auto deadline =
::grpc::g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
while (true) {
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
bool ok = ev.success != 0;
void* ignored = tag;
if (tag->FinalizeResult(&ignored, &ok)) {
GPR_CODEGEN_ASSERT(ignored == tag);
return ok;
}
}
}
/// Performs a single polling pluck on \a tag.
/// \warning Must not be mixed with calls to \a Next.
///
/// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already
/// shutdown. This is most likely a bug and if it is a bug, then change this
/// implementation to simple call the other TryPluck function with a zero
/// timeout. i.e:
/// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
void TryPluck(::grpc::internal::CompletionQueueTag* tag) {
auto deadline =
::grpc::g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT) return;
bool ok = ev.success != 0;
void* ignored = tag;
// the tag must be swallowed if using TryPluck
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
/// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if
/// the pluck() was successful and returned the tag.
///
/// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
/// that the tag is internal not something that is returned to the user.
void TryPluck(::grpc::internal::CompletionQueueTag* tag,
gpr_timespec deadline) {
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
return;
}
bool ok = ev.success != 0;
void* ignored = tag;
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
/// Manage state of avalanching operations : completion queue tags that
/// trigger other completion queue operations. The underlying core completion
/// queue should not really shutdown until all avalanching operations have
/// been finalized. Note that we maintain the requirement that an avalanche
/// registration must take place before CQ shutdown (which must be maintained
/// elsehwere)
void InitialAvalanching() {
gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1));
}
void RegisterAvalanching() {
gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
static_cast<gpr_atm>(1));
}
void CompleteAvalanching() {
if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
static_cast<gpr_atm>(-1)) == 1) {
::grpc::g_core_codegen_interface->grpc_completion_queue_shutdown(cq_);
}
}
void RegisterServer(const ::grpc_impl::Server* server) {
(void)server;
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
server_list_.push_back(server);
#endif
}
void UnregisterServer(const ::grpc_impl::Server* server) {
(void)server;
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
server_list_.remove(server);
#endif
}
bool ServerListEmpty() const {
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
return server_list_.empty();
#endif
return true;
}
grpc_completion_queue* cq_; // owned
gpr_atm avalanches_in_flight_;
// List of servers associated with this CQ. Even though this is only used with
// NDEBUG, instantiate it in all cases since otherwise the size will be
// inconsistent.
mutable grpc::internal::Mutex server_list_mutex_;
std::list<const ::grpc_impl::Server*>
server_list_ /* GUARDED_BY(server_list_mutex_) */;
};
/// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder or Server (for health checker).
class ServerCompletionQueue : public CompletionQueue {
public:
bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; }
protected:
/// Default constructor
ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {}
private:
/// \param completion_type indicates whether this is a NEXT or CALLBACK
/// completion queue.
/// \param polling_type Informs the GRPC library about the type of polling
/// allowed on this completion queue. See grpc_cq_polling_type's description
/// in grpc_types.h for more details.
/// \param shutdown_cb is the shutdown callback used for CALLBACK api queues
ServerCompletionQueue(grpc_cq_completion_type completion_type,
grpc_cq_polling_type polling_type,
grpc_experimental_completion_queue_functor* shutdown_cb)
: CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, completion_type, polling_type,
shutdown_cb}),
polling_type_(polling_type) {}
grpc_cq_polling_type polling_type_;
friend class ::grpc::ServerBuilder;
friend class ::grpc_impl::Server;
};
} // namespace grpc } // namespace grpc

@ -0,0 +1,454 @@
/*
*
* Copyright 2015-2016 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.
*
*/
/// A completion queue implements a concurrent producer-consumer queue, with
/// two main API-exposed methods: \a Next and \a AsyncNext. These
/// methods are the essential component of the gRPC C++ asynchronous API.
/// There is also a \a Shutdown method to indicate that a given completion queue
/// will no longer have regular events. This must be called before the
/// completion queue is destroyed.
/// All completion queue APIs are thread-safe and may be used concurrently with
/// any other completion queue API invocation; it is acceptable to have
/// multiple threads calling \a Next or \a AsyncNext on the same or different
/// completion queues, or to call these methods concurrently with a \a Shutdown
/// elsewhere.
/// \remark{All other API calls on completion queue should be completed before
/// a completion queue destructor is called.}
#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H
#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H
#include <list>
#include <grpc/impl/codegen/atm.h>
#include <grpcpp/impl/codegen/completion_queue_tag.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/sync.h>
#include <grpcpp/impl/codegen/time.h>
struct grpc_completion_queue;
namespace grpc_impl {
class Channel;
class Server;
template <class R>
class ClientReader;
template <class W>
class ClientWriter;
template <class W, class R>
class ClientReaderWriter;
template <class R>
class ServerReader;
template <class W>
class ServerWriter;
class ServerContextBase;
namespace internal {
template <class W, class R>
class ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler;
template <::grpc::StatusCode code>
class ErrorMethodHandler;
} // namespace internal
} // namespace grpc_impl
namespace grpc {
class ChannelInterface;
class ServerBuilder;
class ServerInterface;
namespace internal {
class CompletionQueueTag;
class RpcMethod;
template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>
class CallOpSet;
} // namespace internal
extern CoreCodegenInterface* g_core_codegen_interface;
} // namespace grpc
namespace grpc_impl {
/// A thin wrapper around \ref grpc_completion_queue (see \ref
/// src/core/lib/surface/completion_queue.h).
/// See \ref doc/cpp/perf_notes.md for notes on best practices for high
/// performance servers.
class CompletionQueue : private ::grpc::GrpcLibraryCodegen {
public:
/// Default constructor. Implicitly creates a \a grpc_completion_queue
/// instance.
CompletionQueue()
: CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING,
nullptr}) {}
/// Wrap \a take, taking ownership of the instance.
///
/// \param take The completion queue instance to wrap. Ownership is taken.
explicit CompletionQueue(grpc_completion_queue* take);
/// Destructor. Destroys the owned wrapped completion queue / instance.
~CompletionQueue() {
::grpc::g_core_codegen_interface->grpc_completion_queue_destroy(cq_);
}
/// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
enum NextStatus {
SHUTDOWN, ///< The completion queue has been shutdown and fully-drained
GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
///< associated value; \a ok indicating its success.
TIMEOUT ///< deadline was reached.
};
/// Read from the queue, blocking until an event is available or the queue is
/// shutting down.
///
/// \param tag [out] Updated to point to the read event's tag.
/// \param ok [out] true if read a successful event, false otherwise.
///
/// Note that each tag sent to the completion queue (through RPC operations
/// or alarms) will be delivered out of the completion queue by a call to
/// Next (or a related method), regardless of whether the operation succeeded
/// or not. Success here means that this operation completed in the normal
/// valid manner.
///
/// Server-side RPC request: \a ok indicates that the RPC has indeed
/// been started. If it is false, the server has been Shutdown
/// before this particular call got matched to an incoming RPC.
///
/// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is
/// going to go to the wire. If it is false, it not going to the wire. This
/// would happen if the channel is either permanently broken or
/// transiently broken but with the fail-fast option. (Note that async unary
/// RPCs don't post a CQ tag at this point, nor do client-streaming
/// or bidi-streaming RPCs that have the initial metadata corked option set.)
///
/// Client-side Write, Client-side WritesDone, Server-side Write,
/// Server-side Finish, Server-side SendInitialMetadata (which is
/// typically included in Write or Finish when not done explicitly):
/// \a ok means that the data/metadata/status/etc is going to go to the
/// wire. If it is false, it not going to the wire because the call
/// is already dead (i.e., canceled, deadline expired, other side
/// dropped the channel, etc).
///
/// Client-side Read, Server-side Read, Client-side
/// RecvInitialMetadata (which is typically included in Read if not
/// done explicitly): \a ok indicates whether there is a valid message
/// that got read. If not, you know that there are certainly no more
/// messages that can ever be read from this stream. For the client-side
/// operations, this only happens because the call is dead. For the
/// server-sider operation, though, this could happen because the client
/// has done a WritesDone already.
///
/// Client-side Finish: \a ok should always be true
///
/// Server-side AsyncNotifyWhenDone: \a ok should always be true
///
/// Alarm: \a ok is true if it expired, false if it was canceled
///
/// \return true if got an event, false if the queue is fully drained and
/// shut down.
bool Next(void** tag, bool* ok) {
return (AsyncNextInternal(tag, ok,
::grpc::g_core_codegen_interface->gpr_inf_future(
GPR_CLOCK_REALTIME)) != SHUTDOWN);
}
/// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param tag [out] Upon success, updated to point to the event's tag.
/// \param ok [out] Upon success, true if a successful event, false otherwise
/// See documentation for CompletionQueue::Next for explanation of ok
/// \param deadline [in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T>
NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
::grpc::TimePoint<T> deadline_tp(deadline);
return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
}
/// EXPERIMENTAL
/// First executes \a F, then reads from the queue, blocking up to
/// \a deadline (or the queue's shutdown).
/// Both \a tag and \a ok are updated upon success (if an event is available
/// within the \a deadline). A \a tag points to an arbitrary location usually
/// employed to uniquely identify an event.
///
/// \param f [in] Function to execute before calling AsyncNext on this queue.
/// \param tag [out] Upon success, updated to point to the event's tag.
/// \param ok [out] Upon success, true if read a regular event, false
/// otherwise.
/// \param deadline [in] How long to block in wait for an event.
///
/// \return The type of event read.
template <typename T, typename F>
NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) {
CompletionQueueTLSCache cache = CompletionQueueTLSCache(this);
f();
if (cache.Flush(tag, ok)) {
return GOT_EVENT;
} else {
return AsyncNext(tag, ok, deadline);
}
}
/// Request the shutdown of the queue.
///
/// \warning This method must be called at some point if this completion queue
/// is accessed with Next or AsyncNext. \a Next will not return false
/// until this method has been called and all pending tags have been drained.
/// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .)
/// Only once either one of these methods does that (that is, once the queue
/// has been \em drained) can an instance of this class be destroyed.
/// Also note that applications must ensure that no work is enqueued on this
/// completion queue after this method is called.
void Shutdown();
/// Returns a \em raw pointer to the underlying \a grpc_completion_queue
/// instance.
///
/// \warning Remember that the returned instance is owned. No transfer of
/// owership is performed.
grpc_completion_queue* cq() { return cq_; }
protected:
/// Private constructor of CompletionQueue only visible to friend classes
CompletionQueue(const grpc_completion_queue_attributes& attributes) {
cq_ = ::grpc::g_core_codegen_interface->grpc_completion_queue_create(
::grpc::g_core_codegen_interface->grpc_completion_queue_factory_lookup(
&attributes),
&attributes, NULL);
InitialAvalanching(); // reserve this for the future shutdown
}
private:
// Friends for access to server registration lists that enable checking and
// logging on shutdown
friend class ::grpc::ServerBuilder;
friend class ::grpc_impl::Server;
// Friend synchronous wrappers so that they can access Pluck(), which is
// a semi-private API geared towards the synchronous implementation.
template <class R>
friend class ::grpc_impl::ClientReader;
template <class W>
friend class ::grpc_impl::ClientWriter;
template <class W, class R>
friend class ::grpc_impl::ClientReaderWriter;
template <class R>
friend class ::grpc_impl::ServerReader;
template <class W>
friend class ::grpc_impl::ServerWriter;
template <class W, class R>
friend class ::grpc_impl::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc_impl::internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc_impl::internal::ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ::grpc_impl::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
friend class ::grpc_impl::internal::TemplatedBidiStreamingHandler;
template <::grpc::StatusCode code>
friend class ::grpc_impl::internal::ErrorMethodHandler;
friend class ::grpc_impl::ServerContextBase;
friend class ::grpc::ServerInterface;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
// Friends that need access to constructor for callback CQ
friend class ::grpc_impl::Channel;
// For access to Register/CompleteAvalanching
template <class Op1, class Op2, class Op3, class Op4, class Op5, class Op6>
friend class ::grpc::internal::CallOpSet;
/// EXPERIMENTAL
/// Creates a Thread Local cache to store the first event
/// On this completion queue queued from this thread. Once
/// initialized, it must be flushed on the same thread.
class CompletionQueueTLSCache {
public:
CompletionQueueTLSCache(CompletionQueue* cq);
~CompletionQueueTLSCache();
bool Flush(void** tag, bool* ok);
private:
CompletionQueue* cq_;
bool flushed_;
};
NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
/// Wraps \a grpc_completion_queue_pluck.
/// \warning Must not be mixed with calls to \a Next.
bool Pluck(::grpc::internal::CompletionQueueTag* tag) {
auto deadline =
::grpc::g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
while (true) {
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
bool ok = ev.success != 0;
void* ignored = tag;
if (tag->FinalizeResult(&ignored, &ok)) {
GPR_CODEGEN_ASSERT(ignored == tag);
return ok;
}
}
}
/// Performs a single polling pluck on \a tag.
/// \warning Must not be mixed with calls to \a Next.
///
/// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already
/// shutdown. This is most likely a bug and if it is a bug, then change this
/// implementation to simple call the other TryPluck function with a zero
/// timeout. i.e:
/// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
void TryPluck(::grpc::internal::CompletionQueueTag* tag) {
auto deadline =
::grpc::g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT) return;
bool ok = ev.success != 0;
void* ignored = tag;
// the tag must be swallowed if using TryPluck
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
/// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if
/// the pluck() was successful and returned the tag.
///
/// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
/// that the tag is internal not something that is returned to the user.
void TryPluck(::grpc::internal::CompletionQueueTag* tag,
gpr_timespec deadline) {
auto ev = ::grpc::g_core_codegen_interface->grpc_completion_queue_pluck(
cq_, tag, deadline, nullptr);
if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
return;
}
bool ok = ev.success != 0;
void* ignored = tag;
GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
}
/// Manage state of avalanching operations : completion queue tags that
/// trigger other completion queue operations. The underlying core completion
/// queue should not really shutdown until all avalanching operations have
/// been finalized. Note that we maintain the requirement that an avalanche
/// registration must take place before CQ shutdown (which must be maintained
/// elsehwere)
void InitialAvalanching() {
gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1));
}
void RegisterAvalanching() {
gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
static_cast<gpr_atm>(1));
}
void CompleteAvalanching() {
if (gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
static_cast<gpr_atm>(-1)) == 1) {
::grpc::g_core_codegen_interface->grpc_completion_queue_shutdown(cq_);
}
}
void RegisterServer(const Server* server) {
(void)server;
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
server_list_.push_back(server);
#endif
}
void UnregisterServer(const Server* server) {
(void)server;
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
server_list_.remove(server);
#endif
}
bool ServerListEmpty() const {
#ifndef NDEBUG
grpc::internal::MutexLock l(&server_list_mutex_);
return server_list_.empty();
#endif
return true;
}
grpc_completion_queue* cq_; // owned
gpr_atm avalanches_in_flight_;
// List of servers associated with this CQ. Even though this is only used with
// NDEBUG, instantiate it in all cases since otherwise the size will be
// inconsistent.
mutable grpc::internal::Mutex server_list_mutex_;
std::list<const Server*> server_list_ /* GUARDED_BY(server_list_mutex_) */;
};
/// A specific type of completion queue used by the processing of notifications
/// by servers. Instantiated by \a ServerBuilder or Server (for health checker).
class ServerCompletionQueue : public CompletionQueue {
public:
bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; }
protected:
/// Default constructor
ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {}
private:
/// \param completion_type indicates whether this is a NEXT or CALLBACK
/// completion queue.
/// \param polling_type Informs the GRPC library about the type of polling
/// allowed on this completion queue. See grpc_cq_polling_type's description
/// in grpc_types.h for more details.
/// \param shutdown_cb is the shutdown callback used for CALLBACK api queues
ServerCompletionQueue(grpc_cq_completion_type completion_type,
grpc_cq_polling_type polling_type,
grpc_experimental_completion_queue_functor* shutdown_cb)
: CompletionQueue(grpc_completion_queue_attributes{
GRPC_CQ_CURRENT_VERSION, completion_type, polling_type,
shutdown_cb}),
polling_type_(polling_type) {}
grpc_cq_polling_type polling_type_;
friend class ::grpc::ServerBuilder;
friend class ::grpc_impl::Server;
};
} // namespace grpc_impl
#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_IMPL_H

@ -40,7 +40,7 @@ class DelegatingChannel : public ::grpc::ChannelInterface {
private: private:
internal::Call CreateCall(const internal::RpcMethod& method, internal::Call CreateCall(const internal::RpcMethod& method,
ClientContext* context, ClientContext* context,
::grpc::CompletionQueue* cq) final { ::grpc_impl::CompletionQueue* cq) final {
return delegate_channel()->CreateCall(method, context, cq); return delegate_channel()->CreateCall(method, context, cq);
} }
@ -55,7 +55,7 @@ class DelegatingChannel : public ::grpc::ChannelInterface {
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline, gpr_timespec deadline,
::grpc::CompletionQueue* cq, ::grpc_impl::CompletionQueue* cq,
void* tag) override { void* tag) override {
delegate_channel()->NotifyOnStateChangeImpl(last_observed, deadline, cq, delegate_channel()->NotifyOnStateChangeImpl(last_observed, deadline, cq,
tag); tag);
@ -68,13 +68,13 @@ class DelegatingChannel : public ::grpc::ChannelInterface {
internal::Call CreateCallInternal(const internal::RpcMethod& method, internal::Call CreateCallInternal(const internal::RpcMethod& method,
ClientContext* context, ClientContext* context,
::grpc::CompletionQueue* cq, ::grpc_impl::CompletionQueue* cq,
size_t interceptor_pos) final { size_t interceptor_pos) final {
return delegate_channel()->CreateCallInternal(method, context, cq, return delegate_channel()->CreateCallInternal(method, context, cq,
interceptor_pos); interceptor_pos);
} }
::grpc::CompletionQueue* CallbackCQ() final { ::grpc_impl::CompletionQueue* CallbackCQ() final {
return delegate_channel()->CallbackCQ(); return delegate_channel()->CallbackCQ();
} }

@ -21,8 +21,11 @@
#include <grpcpp/impl/codegen/channel_interface.h> #include <grpcpp/impl/codegen/channel_interface.h>
namespace grpc { namespace grpc_impl {
class CompletionQueue; class CompletionQueue;
}
namespace grpc {
namespace internal { namespace internal {
@ -47,7 +50,7 @@ class InterceptedChannel : public ChannelInterface {
: channel_(channel), interceptor_pos_(pos) {} : channel_(channel), interceptor_pos_(pos) {}
Call CreateCall(const RpcMethod& method, ::grpc_impl::ClientContext* context, Call CreateCall(const RpcMethod& method, ::grpc_impl::ClientContext* context,
::grpc::CompletionQueue* cq) override { ::grpc_impl::CompletionQueue* cq) override {
return channel_->CreateCallInternal(method, context, cq, interceptor_pos_); return channel_->CreateCallInternal(method, context, cq, interceptor_pos_);
} }
@ -60,7 +63,7 @@ class InterceptedChannel : public ChannelInterface {
void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
gpr_timespec deadline, gpr_timespec deadline,
::grpc::CompletionQueue* cq, ::grpc_impl::CompletionQueue* cq,
void* tag) override { void* tag) override {
return channel_->NotifyOnStateChangeImpl(last_observed, deadline, cq, tag); return channel_->NotifyOnStateChangeImpl(last_observed, deadline, cq, tag);
} }
@ -69,7 +72,7 @@ class InterceptedChannel : public ChannelInterface {
return channel_->WaitForStateChangeImpl(last_observed, deadline); return channel_->WaitForStateChangeImpl(last_observed, deadline);
} }
::grpc::CompletionQueue* CallbackCQ() override { ::grpc_impl::CompletionQueue* CallbackCQ() override {
return channel_->CallbackCQ(); return channel_->CallbackCQ();
} }

@ -50,6 +50,7 @@ struct census_context;
namespace grpc_impl { namespace grpc_impl {
class ClientContext; class ClientContext;
class CompletionQueue;
class Server; class Server;
template <class W, class R> template <class W, class R>
class ServerAsyncReader; class ServerAsyncReader;
@ -94,7 +95,6 @@ class ErrorMethodHandler;
} // namespace grpc_impl } // namespace grpc_impl
namespace grpc { namespace grpc {
class CompletionQueue;
class GenericServerContext; class GenericServerContext;
class ServerInterface; class ServerInterface;
@ -426,7 +426,7 @@ class ServerContextBase {
gpr_timespec deadline_; gpr_timespec deadline_;
grpc_call* call_; grpc_call* call_;
::grpc::CompletionQueue* cq_; ::grpc_impl::CompletionQueue* cq_;
bool sent_initial_metadata_; bool sent_initial_metadata_;
mutable std::shared_ptr<const ::grpc::AuthContext> auth_context_; mutable std::shared_ptr<const ::grpc::AuthContext> auth_context_;
mutable ::grpc::internal::MetadataMap client_metadata_; mutable ::grpc::internal::MetadataMap client_metadata_;

@ -31,13 +31,16 @@
#include <grpcpp/impl/codegen/rpc_service_method.h> #include <grpcpp/impl/codegen/rpc_service_method.h>
#include <grpcpp/impl/codegen/server_context_impl.h> #include <grpcpp/impl/codegen/server_context_impl.h>
namespace grpc { namespace grpc_impl {
class AsyncGenericService;
class Channel; class Channel;
class CompletionQueue; class CompletionQueue;
class GenericServerContext;
class ServerCompletionQueue; class ServerCompletionQueue;
} // namespace grpc_impl
namespace grpc {
class AsyncGenericService;
class GenericServerContext;
class ServerCredentials; class ServerCredentials;
class Service; class Service;
@ -178,7 +181,8 @@ class ServerInterface : public internal::CallHook {
/// caller is required to keep all completion queues live until the server is /// caller is required to keep all completion queues live until the server is
/// destroyed. /// destroyed.
/// \param num_cqs How many completion queues does \a cqs hold. /// \param num_cqs How many completion queues does \a cqs hold.
virtual void Start(::grpc::ServerCompletionQueue** cqs, size_t num_cqs) = 0; virtual void Start(::grpc_impl::ServerCompletionQueue** cqs,
size_t num_cqs) = 0;
virtual void ShutdownInternal(gpr_timespec deadline) = 0; virtual void ShutdownInternal(gpr_timespec deadline) = 0;
@ -194,9 +198,9 @@ class ServerInterface : public internal::CallHook {
BaseAsyncRequest(ServerInterface* server, BaseAsyncRequest(ServerInterface* server,
::grpc_impl::ServerContext* context, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, void* tag, ::grpc_impl::ServerCompletionQueue* notification_cq,
bool delete_on_finalize); void* tag, bool delete_on_finalize);
virtual ~BaseAsyncRequest(); virtual ~BaseAsyncRequest();
bool FinalizeResult(void** tag, bool* status) override; bool FinalizeResult(void** tag, bool* status) override;
@ -208,8 +212,8 @@ class ServerInterface : public internal::CallHook {
ServerInterface* const server_; ServerInterface* const server_;
::grpc_impl::ServerContext* const context_; ::grpc_impl::ServerContext* const context_;
internal::ServerAsyncStreamingInterface* const stream_; internal::ServerAsyncStreamingInterface* const stream_;
::grpc::CompletionQueue* const call_cq_; ::grpc_impl::CompletionQueue* const call_cq_;
::grpc::ServerCompletionQueue* const notification_cq_; ::grpc_impl::ServerCompletionQueue* const notification_cq_;
void* const tag_; void* const tag_;
const bool delete_on_finalize_; const bool delete_on_finalize_;
grpc_call* call_; grpc_call* call_;
@ -224,8 +228,8 @@ class ServerInterface : public internal::CallHook {
RegisteredAsyncRequest(ServerInterface* server, RegisteredAsyncRequest(ServerInterface* server,
::grpc_impl::ServerContext* context, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, ::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, const char* name, void* tag, const char* name,
internal::RpcMethod::RpcType type); internal::RpcMethod::RpcType type);
@ -243,7 +247,7 @@ class ServerInterface : public internal::CallHook {
protected: protected:
void IssueRequest(void* registered_method, grpc_byte_buffer** payload, void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
::grpc::ServerCompletionQueue* notification_cq); ::grpc_impl::ServerCompletionQueue* notification_cq);
const char* name_; const char* name_;
const internal::RpcMethod::RpcType type_; const internal::RpcMethod::RpcType type_;
}; };
@ -254,8 +258,8 @@ class ServerInterface : public internal::CallHook {
ServerInterface* server, ServerInterface* server,
::grpc_impl::ServerContext* context, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, ::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag) void* tag)
: RegisteredAsyncRequest( : RegisteredAsyncRequest(
server, context, stream, call_cq, notification_cq, tag, server, context, stream, call_cq, notification_cq, tag,
@ -273,8 +277,8 @@ class ServerInterface : public internal::CallHook {
ServerInterface* server, ServerInterface* server,
::grpc_impl::ServerContext* context, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, ::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, Message* request) void* tag, Message* request)
: RegisteredAsyncRequest( : RegisteredAsyncRequest(
server, context, stream, call_cq, notification_cq, tag, server, context, stream, call_cq, notification_cq, tag,
@ -329,8 +333,8 @@ class ServerInterface : public internal::CallHook {
public: public:
GenericAsyncRequest(ServerInterface* server, GenericServerContext* context, GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, ::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, bool delete_on_finalize); void* tag, bool delete_on_finalize);
bool FinalizeResult(void** tag, bool* status) override; bool FinalizeResult(void** tag, bool* status) override;
@ -343,8 +347,8 @@ class ServerInterface : public internal::CallHook {
void RequestAsyncCall(internal::RpcServiceMethod* method, void RequestAsyncCall(internal::RpcServiceMethod* method,
::grpc_impl::ServerContext* context, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, ::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag, Message* message) { void* tag, Message* message) {
GPR_CODEGEN_ASSERT(method); GPR_CODEGEN_ASSERT(method);
new PayloadAsyncRequest<Message>(method, this, context, stream, call_cq, new PayloadAsyncRequest<Message>(method, this, context, stream, call_cq,
@ -354,19 +358,19 @@ class ServerInterface : public internal::CallHook {
void RequestAsyncCall(internal::RpcServiceMethod* method, void RequestAsyncCall(internal::RpcServiceMethod* method,
::grpc_impl::ServerContext* context, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, ::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag) { void* tag) {
GPR_CODEGEN_ASSERT(method); GPR_CODEGEN_ASSERT(method);
new NoPayloadAsyncRequest(method, this, context, stream, call_cq, new NoPayloadAsyncRequest(method, this, context, stream, call_cq,
notification_cq, tag); notification_cq, tag);
} }
void RequestAsyncGenericCall(GenericServerContext* context, void RequestAsyncGenericCall(
internal::ServerAsyncStreamingInterface* stream, GenericServerContext* context,
::grpc::CompletionQueue* call_cq, internal::ServerAsyncStreamingInterface* stream,
::grpc::ServerCompletionQueue* notification_cq, ::grpc_impl::CompletionQueue* call_cq,
void* tag) { ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
new GenericAsyncRequest(this, context, stream, call_cq, notification_cq, new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
tag, true); tag, true);
} }
@ -391,7 +395,7 @@ class ServerInterface : public internal::CallHook {
// Returns nullptr (rather than being pure) since this is a post-1.0 method // Returns nullptr (rather than being pure) since this is a post-1.0 method
// and adding a new pure method to an interface would be a breaking change // and adding a new pure method to an interface would be a breaking change
// (even though this is private and non-API) // (even though this is private and non-API)
virtual ::grpc::CompletionQueue* CallbackCQ() { return nullptr; } virtual ::grpc_impl::CompletionQueue* CallbackCQ() { return nullptr; }
}; };
} // namespace grpc } // namespace grpc

@ -29,11 +29,11 @@
namespace grpc_impl { namespace grpc_impl {
class Server; class Server;
class CompletionQueue;
class ServerContext; class ServerContext;
} // namespace grpc_impl } // namespace grpc_impl
namespace grpc { namespace grpc {
class CompletionQueue;
class ServerInterface; class ServerInterface;
namespace internal { namespace internal {
@ -130,8 +130,8 @@ class Service {
void RequestAsyncUnary(int index, ::grpc_impl::ServerContext* context, void RequestAsyncUnary(int index, ::grpc_impl::ServerContext* context,
Message* request, Message* request,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, ::grpc_impl::ServerCompletionQueue* notification_cq,
void* tag) { void* tag) {
// Typecast the index to size_t for indexing into a vector // Typecast the index to size_t for indexing into a vector
// while preserving the API that existed before a compiler // while preserving the API that existed before a compiler
@ -143,8 +143,8 @@ class Service {
void RequestAsyncClientStreaming( void RequestAsyncClientStreaming(
int index, ::grpc_impl::ServerContext* context, int index, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, void* tag) { ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
size_t idx = static_cast<size_t>(index); size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag); notification_cq, tag);
@ -153,8 +153,8 @@ class Service {
void RequestAsyncServerStreaming( void RequestAsyncServerStreaming(
int index, ::grpc_impl::ServerContext* context, Message* request, int index, ::grpc_impl::ServerContext* context, Message* request,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, void* tag) { ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
size_t idx = static_cast<size_t>(index); size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag, request); notification_cq, tag, request);
@ -162,8 +162,8 @@ class Service {
void RequestAsyncBidiStreaming( void RequestAsyncBidiStreaming(
int index, ::grpc_impl::ServerContext* context, int index, ::grpc_impl::ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, internal::ServerAsyncStreamingInterface* stream,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, void* tag) { ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
size_t idx = static_cast<size_t>(index); size_t idx = static_cast<size_t>(index);
server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq, server_->RequestAsyncCall(methods_[idx].get(), context, stream, call_cq,
notification_cq, tag); notification_cq, tag);

@ -21,7 +21,7 @@
#include <grpcpp/impl/codegen/call.h> #include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/channel_interface.h> #include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/client_context_impl.h> #include <grpcpp/impl/codegen/client_context_impl.h>
#include <grpcpp/impl/codegen/completion_queue.h> #include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h> #include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/server_context_impl.h> #include <grpcpp/impl/codegen/server_context_impl.h>
#include <grpcpp/impl/codegen/service_type.h> #include <grpcpp/impl/codegen/service_type.h>
@ -232,7 +232,7 @@ class ClientReader final : public ClientReaderInterface<R> {
private: private:
friend class internal::ClientReaderFactory<R>; friend class internal::ClientReaderFactory<R>;
::grpc_impl::ClientContext* context_; ::grpc_impl::ClientContext* context_;
::grpc::CompletionQueue cq_; ::grpc_impl::CompletionQueue cq_;
::grpc::internal::Call call_; ::grpc::internal::Call call_;
/// Block to create a stream and write the initial metadata and \a request /// Block to create a stream and write the initial metadata and \a request
@ -400,7 +400,7 @@ class ClientWriter : public ClientWriterInterface<W> {
::grpc::internal::CallOpGenericRecvMessage, ::grpc::internal::CallOpGenericRecvMessage,
::grpc::internal::CallOpClientRecvStatus> ::grpc::internal::CallOpClientRecvStatus>
finish_ops_; finish_ops_;
::grpc::CompletionQueue cq_; ::grpc_impl::CompletionQueue cq_;
::grpc::internal::Call call_; ::grpc::internal::Call call_;
}; };
@ -544,7 +544,7 @@ class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
friend class internal::ClientReaderWriterFactory<W, R>; friend class internal::ClientReaderWriterFactory<W, R>;
::grpc_impl::ClientContext* context_; ::grpc_impl::ClientContext* context_;
::grpc::CompletionQueue cq_; ::grpc_impl::CompletionQueue cq_;
::grpc::internal::Call call_; ::grpc::internal::Call call_;
/// Block to create a stream and write the initial metadata and \a request /// Block to create a stream and write the initial metadata and \a request

@ -167,7 +167,7 @@ class ServerBuilder {
/// not polling the completion queue frequently) will have a significantly /// not polling the completion queue frequently) will have a significantly
/// negative performance impact and hence should not be used in production /// negative performance impact and hence should not be used in production
/// use cases. /// use cases.
std::unique_ptr<grpc::ServerCompletionQueue> AddCompletionQueue( std::unique_ptr<grpc_impl::ServerCompletionQueue> AddCompletionQueue(
bool is_frequently_polled = true); bool is_frequently_polled = true);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -382,7 +382,7 @@ class ServerBuilder {
SyncServerSettings sync_server_settings_; SyncServerSettings sync_server_settings_;
/// List of completion queues added via \a AddCompletionQueue method. /// List of completion queues added via \a AddCompletionQueue method.
std::vector<grpc::ServerCompletionQueue*> cqs_; std::vector<grpc_impl::ServerCompletionQueue*> cqs_;
std::shared_ptr<grpc::ServerCredentials> creds_; std::shared_ptr<grpc::ServerCredentials> creds_;
std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_; std::vector<std::unique_ptr<grpc::ServerBuilderPlugin>> plugins_;

@ -27,12 +27,12 @@
#include <grpc/compression.h> #include <grpc/compression.h>
#include <grpc/support/atm.h> #include <grpc/support/atm.h>
#include <grpcpp/channel.h> #include <grpcpp/channel_impl.h>
#include <grpcpp/completion_queue.h> #include <grpcpp/completion_queue_impl.h>
#include <grpcpp/health_check_service_interface.h> #include <grpcpp/health_check_service_interface.h>
#include <grpcpp/impl/call.h> #include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/client_interceptor.h> #include <grpcpp/impl/codegen/client_interceptor.h>
#include <grpcpp/impl/codegen/completion_queue.h> #include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpcpp/impl/codegen/grpc_library.h> #include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/impl/codegen/server_interface.h> #include <grpcpp/impl/codegen/server_interface.h>
#include <grpcpp/impl/rpc_service_method.h> #include <grpcpp/impl/rpc_service_method.h>
@ -109,8 +109,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
} }
/// Establish a channel for in-process communication /// Establish a channel for in-process communication
std::shared_ptr<grpc::Channel> InProcessChannel( std::shared_ptr<Channel> InProcessChannel(const grpc::ChannelArguments& args);
const grpc::ChannelArguments& args);
/// NOTE: class experimental_type is not part of the public API of this class. /// NOTE: class experimental_type is not part of the public API of this class.
/// TODO(yashykt): Integrate into public API when this is no longer /// TODO(yashykt): Integrate into public API when this is no longer
@ -121,7 +120,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// Establish a channel for in-process communication with client /// Establish a channel for in-process communication with client
/// interceptors /// interceptors
std::shared_ptr<grpc::Channel> InProcessChannelWithInterceptors( std::shared_ptr<Channel> InProcessChannelWithInterceptors(
const grpc::ChannelArguments& args, const grpc::ChannelArguments& args,
std::vector<std::unique_ptr< std::vector<std::unique_ptr<
grpc::experimental::ClientInterceptorFactoryInterface>> grpc::experimental::ClientInterceptorFactoryInterface>>
@ -180,19 +179,18 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// ///
/// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on
/// server completion queues passed via sync_server_cqs param. /// server completion queues passed via sync_server_cqs param.
Server( Server(grpc::ChannelArguments* args,
grpc::ChannelArguments* args, std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
std::shared_ptr<std::vector<std::unique_ptr<grpc::ServerCompletionQueue>>> sync_server_cqs,
sync_server_cqs, int min_pollers, int max_pollers, int sync_cq_timeout_msec,
int min_pollers, int max_pollers, int sync_cq_timeout_msec, std::vector<
std::vector< std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>> acceptors,
acceptors, grpc_resource_quota* server_rq = nullptr,
grpc_resource_quota* server_rq = nullptr, std::vector<std::unique_ptr<
std::vector<std::unique_ptr< grpc::experimental::ServerInterceptorFactoryInterface>>
grpc::experimental::ServerInterceptorFactoryInterface>> interceptor_creators = std::vector<std::unique_ptr<
interceptor_creators = std::vector<std::unique_ptr< grpc::experimental::ServerInterceptorFactoryInterface>>());
grpc::experimental::ServerInterceptorFactoryInterface>>());
/// Start the server. /// Start the server.
/// ///
@ -200,7 +198,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// caller is required to keep all completion queues live until the server is /// caller is required to keep all completion queues live until the server is
/// destroyed. /// destroyed.
/// \param num_cqs How many completion queues does \a cqs hold. /// \param num_cqs How many completion queues does \a cqs hold.
void Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) override; void Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
grpc_server* server() override { return server_; } grpc_server* server() override { return server_; }
@ -289,7 +287,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
return max_receive_message_size_; return max_receive_message_size_;
} }
grpc::CompletionQueue* CallbackCQ() override; CompletionQueue* CallbackCQ() override;
grpc_impl::ServerInitializer* initializer(); grpc_impl::ServerInitializer* initializer();
@ -317,7 +315,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
/// The following completion queues are ONLY used in case of Sync API /// The following completion queues are ONLY used in case of Sync API
/// i.e. if the server has any services with sync methods. The server uses /// i.e. if the server has any services with sync methods. The server uses
/// these completion queues to poll for new RPCs /// these completion queues to poll for new RPCs
std::shared_ptr<std::vector<std::unique_ptr<grpc::ServerCompletionQueue>>> std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
sync_server_cqs_; sync_server_cqs_;
/// List of \a ThreadManager instances (one for each cq in /// List of \a ThreadManager instances (one for each cq in
@ -375,12 +373,12 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen {
// with this server (if any). It is set on the first call to CallbackCQ(). // with this server (if any). It is set on the first call to CallbackCQ().
// It is _not owned_ by the server; ownership belongs with its internal // It is _not owned_ by the server; ownership belongs with its internal
// shutdown callback tag (invoked when the CQ is fully shutdown). // shutdown callback tag (invoked when the CQ is fully shutdown).
grpc::CompletionQueue* callback_cq_ /* GUARDED_BY(mu_) */ = nullptr; CompletionQueue* callback_cq_ /* GUARDED_BY(mu_) */ = nullptr;
// List of CQs passed in by user that must be Shutdown only after Server is // List of CQs passed in by user that must be Shutdown only after Server is
// Shutdown. Even though this is only used with NDEBUG, instantiate it in all // Shutdown. Even though this is only used with NDEBUG, instantiate it in all
// cases since otherwise the size will be inconsistent. // cases since otherwise the size will be inconsistent.
std::vector<grpc::CompletionQueue*> cq_list_; std::vector<CompletionQueue*> cq_list_;
}; };
} // namespace grpc_impl } // namespace grpc_impl

@ -41,7 +41,11 @@
#include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/string.h"
#include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/completion_queue.h"
namespace grpc { void ::grpc::experimental::ChannelResetConnectionBackoff(Channel* channel) {
grpc_impl::experimental::ChannelResetConnectionBackoff(channel);
}
namespace grpc_impl {
static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer; static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer;
Channel::Channel(const std::string& host, grpc_channel* channel, Channel::Channel(const std::string& host, grpc_channel* channel,
@ -63,7 +67,8 @@ Channel::~Channel() {
namespace { namespace {
inline grpc_slice SliceFromArray(const char* arr, size_t len) { inline grpc_slice SliceFromArray(const char* arr, size_t len) {
return g_core_codegen_interface->grpc_slice_from_copied_buffer(arr, len); return ::grpc::g_core_codegen_interface->grpc_slice_from_copied_buffer(arr,
len);
} }
std::string GetChannelInfoField(grpc_channel* channel, std::string GetChannelInfoField(grpc_channel* channel,
@ -249,4 +254,4 @@ class ShutdownCallback : public grpc_experimental_completion_queue_functor {
return callback_cq_; return callback_cq_;
} }
} // namespace grpc } // namespace grpc_impl

@ -31,11 +31,9 @@
#include <grpcpp/server_context.h> #include <grpcpp/server_context.h>
#include <grpcpp/support/time.h> #include <grpcpp/support/time.h>
namespace grpc { namespace grpc_impl {
class Channel; class Channel;
} // namespace grpc
namespace grpc_impl {
class DefaultGlobalClientCallbacks final class DefaultGlobalClientCallbacks final
: public ClientContext::GlobalCallbacks { : public ClientContext::GlobalCallbacks {
@ -115,8 +113,8 @@ void ClientContext::AddMetadata(const std::string& meta_key,
send_initial_metadata_.insert(std::make_pair(meta_key, meta_value)); send_initial_metadata_.insert(std::make_pair(meta_key, meta_value));
} }
void ClientContext::set_call(grpc_call* call, void ClientContext::set_call(
const std::shared_ptr<::grpc::Channel>& channel) { grpc_call* call, const std::shared_ptr<::grpc_impl::Channel>& channel) {
grpc::internal::MutexLock lock(&mu_); grpc::internal::MutexLock lock(&mu_);
GPR_ASSERT(call_ == nullptr); GPR_ASSERT(call_ == nullptr);
call_ = call; call_ = call;

@ -29,9 +29,12 @@
#include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/credentials/credentials.h"
#include "src/cpp/server/thread_pool_interface.h" #include "src/cpp/server/thread_pool_interface.h"
namespace grpc { namespace grpc_impl {
class Channel; class Channel;
} // namespace grpc_impl
namespace grpc {
class SecureChannelCredentials final : public ChannelCredentials { class SecureChannelCredentials final : public ChannelCredentials {
public: public:

@ -24,9 +24,9 @@
#include <grpcpp/impl/grpc_library.h> #include <grpcpp/impl/grpc_library.h>
#include <grpcpp/support/time.h> #include <grpcpp/support/time.h>
namespace grpc { namespace grpc_impl {
static internal::GrpcLibraryInitializer g_gli_initializer; static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer;
// 'CompletionQueue' constructor can safely call GrpcLibraryCodegen(false) here // 'CompletionQueue' constructor can safely call GrpcLibraryCodegen(false) here
// i.e not have GrpcLibraryCodegen call grpc_init(). This is because, to create // i.e not have GrpcLibraryCodegen call grpc_init(). This is because, to create
@ -96,4 +96,4 @@ bool CompletionQueue::CompletionQueueTLSCache::Flush(void** tag, bool* ok) {
return false; return false;
} }
} // namespace grpc } // namespace grpc_impl

@ -24,8 +24,8 @@ namespace grpc {
void AsyncGenericService::RequestCall( void AsyncGenericService::RequestCall(
GenericServerContext* ctx, GenericServerAsyncReaderWriter* reader_writer, GenericServerContext* ctx, GenericServerAsyncReaderWriter* reader_writer,
::grpc::CompletionQueue* call_cq, ::grpc_impl::CompletionQueue* call_cq,
::grpc::ServerCompletionQueue* notification_cq, void* tag) { ::grpc_impl::ServerCompletionQueue* notification_cq, void* tag) {
server_->RequestAsyncGenericCall(ctx, reader_writer, call_cq, notification_cq, server_->RequestAsyncGenericCall(ctx, reader_writer, call_cq, notification_cq,
tag); tag);
} }

@ -68,14 +68,14 @@ ServerBuilder::~ServerBuilder() {
} }
} }
std::unique_ptr<grpc::ServerCompletionQueue> ServerBuilder::AddCompletionQueue( std::unique_ptr<grpc_impl::ServerCompletionQueue>
bool is_frequently_polled) { ServerBuilder::AddCompletionQueue(bool is_frequently_polled) {
grpc::ServerCompletionQueue* cq = new grpc::ServerCompletionQueue( grpc_impl::ServerCompletionQueue* cq = new grpc_impl::ServerCompletionQueue(
GRPC_CQ_NEXT, GRPC_CQ_NEXT,
is_frequently_polled ? GRPC_CQ_DEFAULT_POLLING : GRPC_CQ_NON_LISTENING, is_frequently_polled ? GRPC_CQ_DEFAULT_POLLING : GRPC_CQ_NON_LISTENING,
nullptr); nullptr);
cqs_.push_back(cq); cqs_.push_back(cq);
return std::unique_ptr<grpc::ServerCompletionQueue>(cq); return std::unique_ptr<grpc_impl::ServerCompletionQueue>(cq);
} }
ServerBuilder& ServerBuilder::RegisterService(Service* service) { ServerBuilder& ServerBuilder::RegisterService(Service* service) {
@ -275,10 +275,11 @@ std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() {
// This is different from the completion queues added to the server via // This is different from the completion queues added to the server via
// ServerBuilder's AddCompletionQueue() method (those completion queues // ServerBuilder's AddCompletionQueue() method (those completion queues
// are in 'cqs_' member variable of ServerBuilder object) // are in 'cqs_' member variable of ServerBuilder object)
std::shared_ptr<std::vector<std::unique_ptr<grpc::ServerCompletionQueue>>> std::shared_ptr<
std::vector<std::unique_ptr<grpc_impl::ServerCompletionQueue>>>
sync_server_cqs( sync_server_cqs(
std::make_shared< std::make_shared<std::vector<
std::vector<std::unique_ptr<grpc::ServerCompletionQueue>>>()); std::unique_ptr<grpc_impl::ServerCompletionQueue>>>());
bool has_frequently_polled_cqs = false; bool has_frequently_polled_cqs = false;
for (const auto& cq : cqs_) { for (const auto& cq : cqs_) {
@ -306,8 +307,8 @@ std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() {
// Create completion queues to listen to incoming rpc requests // Create completion queues to listen to incoming rpc requests
for (int i = 0; i < sync_server_settings_.num_cqs; i++) { for (int i = 0; i < sync_server_settings_.num_cqs; i++) {
sync_server_cqs->emplace_back( sync_server_cqs->emplace_back(new grpc_impl::ServerCompletionQueue(
new grpc::ServerCompletionQueue(GRPC_CQ_NEXT, polling_type, nullptr)); GRPC_CQ_NEXT, polling_type, nullptr));
} }
} }

@ -27,7 +27,7 @@
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpcpp/impl/call.h> #include <grpcpp/impl/call.h>
#include <grpcpp/impl/codegen/completion_queue.h> #include <grpcpp/impl/codegen/completion_queue_impl.h>
#include <grpcpp/support/server_callback.h> #include <grpcpp/support/server_callback.h>
#include <grpcpp/support/time.h> #include <grpcpp/support/time.h>
@ -89,7 +89,7 @@ class ServerContextBase::CompletionOp final
bool FinalizeResult(void** tag, bool* status) override; bool FinalizeResult(void** tag, bool* status) override;
bool CheckCancelled(grpc::CompletionQueue* cq) { bool CheckCancelled(CompletionQueue* cq) {
cq->TryPluck(this); cq->TryPluck(this);
return CheckCancelledNoPluck(); return CheckCancelledNoPluck();
} }

@ -26,8 +26,12 @@
#include <grpcpp/security/credentials.h> #include <grpcpp/security/credentials.h>
#include <grpcpp/support/channel_arguments.h> #include <grpcpp/support/channel_arguments.h>
namespace grpc { namespace grpc_impl {
class Channel; class Channel;
}
namespace grpc {
namespace testing { namespace testing {

@ -935,8 +935,10 @@ include/grpc/support/workaround_list.h \
include/grpcpp/alarm.h \ include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \ include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \ include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \ include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \ include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \ include/grpcpp/create_channel.h \
include/grpcpp/create_channel_posix.h \ include/grpcpp/create_channel_posix.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \
@ -966,6 +968,7 @@ include/grpcpp/impl/codegen/client_context_impl.h \
include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/config_protobuf.h \ include/grpcpp/impl/codegen/config_protobuf.h \

@ -935,8 +935,10 @@ include/grpc/support/workaround_list.h \
include/grpcpp/alarm.h \ include/grpcpp/alarm.h \
include/grpcpp/alarm_impl.h \ include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \ include/grpcpp/channel.h \
include/grpcpp/channel_impl.h \
include/grpcpp/client_context.h \ include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \ include/grpcpp/completion_queue.h \
include/grpcpp/completion_queue_impl.h \
include/grpcpp/create_channel.h \ include/grpcpp/create_channel.h \
include/grpcpp/create_channel_posix.h \ include/grpcpp/create_channel_posix.h \
include/grpcpp/ext/health_check_service_server_builder_option.h \ include/grpcpp/ext/health_check_service_server_builder_option.h \
@ -966,6 +968,7 @@ include/grpcpp/impl/codegen/client_context_impl.h \
include/grpcpp/impl/codegen/client_interceptor.h \ include/grpcpp/impl/codegen/client_interceptor.h \
include/grpcpp/impl/codegen/client_unary_call.h \ include/grpcpp/impl/codegen/client_unary_call.h \
include/grpcpp/impl/codegen/completion_queue.h \ include/grpcpp/impl/codegen/completion_queue.h \
include/grpcpp/impl/codegen/completion_queue_impl.h \
include/grpcpp/impl/codegen/completion_queue_tag.h \ include/grpcpp/impl/codegen/completion_queue_tag.h \
include/grpcpp/impl/codegen/config.h \ include/grpcpp/impl/codegen/config.h \
include/grpcpp/impl/codegen/config_protobuf.h \ include/grpcpp/impl/codegen/config_protobuf.h \

Loading…
Cancel
Save