1 /* 2 * 3 * Copyright 2016 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H 20 #define GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H 21 22 #include <grpc/impl/codegen/connectivity_state.h> 23 #include <grpcpp/impl/codegen/status.h> 24 #include <grpcpp/impl/codegen/time.h> 25 26 namespace grpc { 27 class ChannelInterface; 28 class ClientContext; 29 class CompletionQueue; 30 31 template <class R> 32 class ClientReader; 33 template <class W> 34 class ClientWriter; 35 template <class W, class R> 36 class ClientReaderWriter; 37 38 namespace internal { 39 class Call; 40 class CallOpSetInterface; 41 class RpcMethod; 42 template <class InputMessage, class OutputMessage> 43 class BlockingUnaryCallImpl; 44 template <class InputMessage, class OutputMessage> 45 class CallbackUnaryCallImpl; 46 template <class R> 47 class ClientAsyncReaderFactory; 48 template <class W> 49 class ClientAsyncWriterFactory; 50 template <class W, class R> 51 class ClientAsyncReaderWriterFactory; 52 template <class R> 53 class ClientAsyncResponseReaderFactory; 54 } // namespace internal 55 56 /// Codegen interface for \a grpc::Channel. 57 class ChannelInterface { 58 public: ~ChannelInterface()59 virtual ~ChannelInterface() {} 60 /// Get the current channel state. If the channel is in IDLE and 61 /// \a try_to_connect is set to true, try to connect. 62 virtual grpc_connectivity_state GetState(bool try_to_connect) = 0; 63 64 /// Return the \a tag on \a cq when the channel state is changed or \a 65 /// deadline expires. \a GetState needs to called to get the current state. 66 template <typename T> NotifyOnStateChange(grpc_connectivity_state last_observed,T deadline,CompletionQueue * cq,void * tag)67 void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline, 68 CompletionQueue* cq, void* tag) { 69 TimePoint<T> deadline_tp(deadline); 70 NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag); 71 } 72 73 /// Blocking wait for channel state change or \a deadline expiration. 74 /// \a GetState needs to called to get the current state. 75 template <typename T> WaitForStateChange(grpc_connectivity_state last_observed,T deadline)76 bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) { 77 TimePoint<T> deadline_tp(deadline); 78 return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time()); 79 } 80 81 /// Wait for this channel to be connected 82 template <typename T> WaitForConnected(T deadline)83 bool WaitForConnected(T deadline) { 84 grpc_connectivity_state state; 85 while ((state = GetState(true)) != GRPC_CHANNEL_READY) { 86 if (!WaitForStateChange(state, deadline)) return false; 87 } 88 return true; 89 } 90 91 private: 92 template <class R> 93 friend class ::grpc::ClientReader; 94 template <class W> 95 friend class ::grpc::ClientWriter; 96 template <class W, class R> 97 friend class ::grpc::ClientReaderWriter; 98 template <class R> 99 friend class ::grpc::internal::ClientAsyncReaderFactory; 100 template <class W> 101 friend class ::grpc::internal::ClientAsyncWriterFactory; 102 template <class W, class R> 103 friend class ::grpc::internal::ClientAsyncReaderWriterFactory; 104 template <class R> 105 friend class ::grpc::internal::ClientAsyncResponseReaderFactory; 106 template <class InputMessage, class OutputMessage> 107 friend class ::grpc::internal::BlockingUnaryCallImpl; 108 template <class InputMessage, class OutputMessage> 109 friend class ::grpc::internal::CallbackUnaryCallImpl; 110 friend class ::grpc::internal::RpcMethod; 111 virtual internal::Call CreateCall(const internal::RpcMethod& method, 112 ClientContext* context, 113 CompletionQueue* cq) = 0; 114 virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops, 115 internal::Call* call) = 0; 116 virtual void* RegisterMethod(const char* method) = 0; 117 virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed, 118 gpr_timespec deadline, 119 CompletionQueue* cq, void* tag) = 0; 120 virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed, 121 gpr_timespec deadline) = 0; 122 123 // EXPERIMENTAL 124 // A method to get the callbackable completion queue associated with this 125 // channel. If the return value is nullptr, this channel doesn't support 126 // callback operations. 127 // TODO(vjpai): Consider a better default like using a global CQ 128 // Returns nullptr (rather than being pure) since this is a new method 129 // and adding a new pure method to an interface would be a breaking change 130 // (even though this is private and non-API) CallbackCQ()131 virtual CompletionQueue* CallbackCQ() { return nullptr; } 132 }; 133 } // namespace grpc 134 135 #endif // GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H 136