• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2019 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_SERVER_CONTEXT_H
20 #define GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
21 
22 #include <atomic>
23 #include <cassert>
24 #include <map>
25 #include <memory>
26 #include <type_traits>
27 #include <vector>
28 
29 #include <grpc/impl/codegen/port_platform.h>
30 
31 #include <grpc/impl/codegen/compression_types.h>
32 #include <grpcpp/impl/codegen/call.h>
33 #include <grpcpp/impl/codegen/call_op_set.h>
34 #include <grpcpp/impl/codegen/callback_common.h>
35 #include <grpcpp/impl/codegen/completion_queue_tag.h>
36 #include <grpcpp/impl/codegen/config.h>
37 #include <grpcpp/impl/codegen/create_auth_context.h>
38 #include <grpcpp/impl/codegen/message_allocator.h>
39 #include <grpcpp/impl/codegen/metadata_map.h>
40 #include <grpcpp/impl/codegen/rpc_service_method.h>
41 #include <grpcpp/impl/codegen/security/auth_context.h>
42 #include <grpcpp/impl/codegen/server_callback.h>
43 #include <grpcpp/impl/codegen/server_interceptor.h>
44 #include <grpcpp/impl/codegen/status.h>
45 #include <grpcpp/impl/codegen/string_ref.h>
46 #include <grpcpp/impl/codegen/time.h>
47 
48 struct grpc_metadata;
49 struct grpc_call;
50 struct census_context;
51 
52 namespace grpc {
53 template <class W, class R>
54 class ServerAsyncReader;
55 template <class W>
56 class ServerAsyncWriter;
57 template <class W>
58 class ServerAsyncResponseWriter;
59 template <class W, class R>
60 class ServerAsyncReaderWriter;
61 template <class R>
62 class ServerReader;
63 template <class W>
64 class ServerWriter;
65 
66 namespace internal {
67 template <class ServiceType, class RequestType, class ResponseType>
68 class BidiStreamingHandler;
69 template <class RequestType, class ResponseType>
70 class CallbackUnaryHandler;
71 template <class RequestType, class ResponseType>
72 class CallbackClientStreamingHandler;
73 template <class RequestType, class ResponseType>
74 class CallbackServerStreamingHandler;
75 template <class RequestType, class ResponseType>
76 class CallbackBidiHandler;
77 template <class ServiceType, class RequestType, class ResponseType>
78 class ClientStreamingHandler;
79 template <class ResponseType>
80 void UnaryRunHandlerHelper(const MethodHandler::HandlerParameter&,
81                            ResponseType*, Status&);
82 template <class ServiceType, class RequestType, class ResponseType,
83           class BaseRequestType, class BaseResponseType>
84 class RpcMethodHandler;
85 template <class Base>
86 class FinishOnlyReactor;
87 template <class W, class R>
88 class ServerReaderWriterBody;
89 template <class ServiceType, class RequestType, class ResponseType>
90 class ServerStreamingHandler;
91 class ServerReactor;
92 template <class Streamer, bool WriteNeeded>
93 class TemplatedBidiStreamingHandler;
94 template <::grpc::StatusCode code>
95 class ErrorMethodHandler;
96 }  // namespace internal
97 
98 class ClientContext;
99 class CompletionQueue;
100 class GenericServerContext;
101 class Server;
102 class ServerInterface;
103 class ContextAllocator;
104 
105 // TODO(vjpai): Remove namespace experimental when de-experimentalized fully.
106 namespace experimental {
107 
108 typedef ::grpc::ServerContextBase ServerContextBase;
109 typedef ::grpc::CallbackServerContext CallbackServerContext;
110 
111 }  // namespace experimental
112 
113 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
114 namespace experimental {
115 #endif
116 class GenericCallbackServerContext;
117 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
118 }  // namespace experimental
119 #endif
120 namespace internal {
121 class Call;
122 }  // namespace internal
123 
124 namespace testing {
125 class InteropServerContextInspector;
126 class ServerContextTestSpouse;
127 class DefaultReactorTestPeer;
128 }  // namespace testing
129 
130 /// Base class of ServerContext. Experimental until callback API is final.
131 class ServerContextBase {
132  public:
133   virtual ~ServerContextBase();
134 
135   /// Return the deadline for the server call.
deadline()136   std::chrono::system_clock::time_point deadline() const {
137     return ::grpc::Timespec2Timepoint(deadline_);
138   }
139 
140   /// Return a \a gpr_timespec representation of the server call's deadline.
raw_deadline()141   gpr_timespec raw_deadline() const { return deadline_; }
142 
143   /// Add the (\a key, \a value) pair to the initial metadata
144   /// associated with a server call. These are made available at the client side
145   /// by the \a grpc::ClientContext::GetServerInitialMetadata() method.
146   ///
147   /// \warning This method should only be called before sending initial metadata
148   /// to the client (which can happen explicitly, or implicitly when sending a
149   /// a response message or status to the client).
150   ///
151   /// \param key The metadata key. If \a value is binary data, it must
152   /// end in "-bin".
153   /// \param value The metadata value. If its value is binary, the key name
154   /// must end in "-bin".
155   ///
156   /// Metadata must conform to the following format:
157   /// Custom-Metadata -> Binary-Header / ASCII-Header
158   /// Binary-Header -> {Header-Name "-bin" } {binary value}
159   /// ASCII-Header -> Header-Name ASCII-Value
160   /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - .
161   /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII
162   void AddInitialMetadata(const std::string& key, const std::string& value);
163 
164   /// Add the (\a key, \a value) pair to the initial metadata
165   /// associated with a server call. These are made available at the client
166   /// side by the \a grpc::ClientContext::GetServerTrailingMetadata() method.
167   ///
168   /// \warning This method should only be called before sending trailing
169   /// metadata to the client (which happens when the call is finished and a
170   /// status is sent to the client).
171   ///
172   /// \param key The metadata key. If \a value is binary data,
173   /// it must end in "-bin".
174   /// \param value The metadata value. If its value is binary, the key name
175   /// must end in "-bin".
176   ///
177   /// Metadata must conform to the following format:
178   /// Custom-Metadata -> Binary-Header / ASCII-Header
179   /// Binary-Header -> {Header-Name "-bin" } {binary value}
180   /// ASCII-Header -> Header-Name ASCII-Value
181   /// Header-Name -> 1*( %x30-39 / %x61-7A / "_" / "-" / ".") ; 0-9 a-z _ - .
182   /// ASCII-Value -> 1*( %x20-%x7E ) ; space and printable ASCII
183   void AddTrailingMetadata(const std::string& key, const std::string& value);
184 
185   /// Return whether this RPC failed before the server could provide its status
186   /// back to the client. This could be because of explicit API cancellation
187   /// from the client-side or server-side, because of deadline exceeded, network
188   /// connection reset, HTTP/2 parameter configuration (e.g., max message size,
189   /// max connection age), etc. It does NOT include failure due to a non-OK
190   /// status return from the server application's request handler, including
191   /// Status::CANCELLED.
192   ///
193   /// IsCancelled is always safe to call when using sync or callback API.
194   /// When using async API, it is only safe to call IsCancelled after
195   /// the AsyncNotifyWhenDone tag has been delivered. Thread-safe.
196   bool IsCancelled() const;
197 
198   /// Cancel the Call from the server. This is a best-effort API and
199   /// depending on when it is called, the RPC may still appear successful to
200   /// the client. For example, if TryCancel() is called on a separate thread, it
201   /// might race with the server handler which might return success to the
202   /// client before TryCancel() was even started by the thread.
203   ///
204   /// It is the caller's responsibility to prevent such races and ensure that if
205   /// TryCancel() is called, the serverhandler must return Status::CANCELLED.
206   /// The only exception is that if the serverhandler is already returning an
207   /// error status code, it is ok to not return Status::CANCELLED even if
208   /// TryCancel() was called.
209   ///
210   /// For reasons such as the above, it is generally preferred to explicitly
211   /// finish an RPC by returning Status::CANCELLED rather than using TryCancel.
212   ///
213   /// Note that TryCancel() does not change any of the tags that are pending
214   /// on the completion queue. All pending tags will still be delivered
215   /// (though their ok result may reflect the effect of cancellation).
216   void TryCancel() const;
217 
218   /// Return a collection of initial metadata key-value pairs sent from the
219   /// client. Note that keys may happen more than
220   /// once (ie, a \a std::multimap is returned).
221   ///
222   /// It is safe to use this method after initial metadata has been received,
223   /// Calls always begin with the client sending initial metadata, so this is
224   /// safe to access as soon as the call has begun on the server side.
225   ///
226   /// \return A multimap of initial metadata key-value pairs from the server.
client_metadata()227   const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata()
228       const {
229     return *client_metadata_.map();
230   }
231 
232   /// Return the compression algorithm to be used by the server call.
compression_level()233   grpc_compression_level compression_level() const {
234     return compression_level_;
235   }
236 
237   /// Set \a level to be the compression level used for the server call.
238   ///
239   /// \param level The compression level used for the server call.
set_compression_level(grpc_compression_level level)240   void set_compression_level(grpc_compression_level level) {
241     compression_level_set_ = true;
242     compression_level_ = level;
243   }
244 
245   /// Return a bool indicating whether the compression level for this call
246   /// has been set (either implicitly or through a previous call to
247   /// \a set_compression_level.
compression_level_set()248   bool compression_level_set() const { return compression_level_set_; }
249 
250   /// Return the compression algorithm the server call will request be used.
251   /// Note that the gRPC runtime may decide to ignore this request, for example,
252   /// due to resource constraints, or if the server is aware the client doesn't
253   /// support the requested algorithm.
compression_algorithm()254   grpc_compression_algorithm compression_algorithm() const {
255     return compression_algorithm_;
256   }
257   /// Set \a algorithm to be the compression algorithm used for the server call.
258   ///
259   /// \param algorithm The compression algorithm used for the server call.
260   void set_compression_algorithm(grpc_compression_algorithm algorithm);
261 
262   /// Set the serialized load reporting costs in \a cost_data for the call.
263   void SetLoadReportingCosts(const std::vector<std::string>& cost_data);
264 
265   /// Return the authentication context for this server call.
266   ///
267   /// \see grpc::AuthContext.
auth_context()268   std::shared_ptr<const ::grpc::AuthContext> auth_context() const {
269     if (auth_context_ == nullptr) {
270       auth_context_ = ::grpc::CreateAuthContext(call_.call);
271     }
272     return auth_context_;
273   }
274 
275   /// Return the peer uri in a string.
276   /// WARNING: this value is never authenticated or subject to any security
277   /// related code. It must not be used for any authentication related
278   /// functionality. Instead, use auth_context.
279   std::string peer() const;
280 
281   /// Get the census context associated with this server call.
282   const struct census_context* census_context() const;
283 
284   /// Should be used for framework-level extensions only.
285   /// Applications never need to call this method.
c_call()286   grpc_call* c_call() { return call_.call; }
287 
288  protected:
289   /// Async only. Has to be called before the rpc starts.
290   /// Returns the tag in completion queue when the rpc finishes.
291   /// IsCancelled() can then be called to check whether the rpc was cancelled.
292   /// TODO(vjpai): Fix this so that the tag is returned even if the call never
293   /// starts (https://github.com/grpc/grpc/issues/10136).
AsyncNotifyWhenDone(void * tag)294   void AsyncNotifyWhenDone(void* tag) {
295     has_notify_when_done_tag_ = true;
296     async_notify_when_done_tag_ = tag;
297   }
298 
299   /// NOTE: This is an API for advanced users who need custom allocators.
300   /// Get and maybe mutate the allocator state associated with the current RPC.
301   /// Currently only applicable for callback unary RPC methods.
302   /// WARNING: This is experimental API and could be changed or removed.
GetRpcAllocatorState()303   ::grpc::experimental::RpcAllocatorState* GetRpcAllocatorState() {
304     return message_allocator_state_;
305   }
306 
307   /// Get a library-owned default unary reactor for use in minimal reaction
308   /// cases. This supports typical unary RPC usage of providing a response and
309   /// status. It supports immediate Finish (finish from within the method
310   /// handler) or delayed Finish (finish called after the method handler
311   /// invocation). It does not support reacting to cancellation or completion,
312   /// or early sending of initial metadata. Since this is a library-owned
313   /// reactor, it should not be delete'd or freed in any way. This is more
314   /// efficient than creating a user-owned reactor both because of avoiding an
315   /// allocation and because its minimal reactions are optimized using a core
316   /// surface flag that allows their reactions to run inline without any
317   /// thread-hop.
318   ///
319   /// This method should not be called more than once or called after return
320   /// from the method handler.
321   ///
322   /// WARNING: This is experimental API and could be changed or removed.
DefaultReactor()323   ::grpc::ServerUnaryReactor* DefaultReactor() {
324     // Short-circuit the case where a default reactor was already set up by
325     // the TestPeer.
326     if (test_unary_ != nullptr) {
327       return reinterpret_cast<Reactor*>(&default_reactor_);
328     }
329     new (&default_reactor_) Reactor;
330 #ifndef NDEBUG
331     bool old = false;
332     assert(default_reactor_used_.compare_exchange_strong(
333         old, true, std::memory_order_relaxed));
334 #else
335     default_reactor_used_.store(true, std::memory_order_relaxed);
336 #endif
337     return reinterpret_cast<Reactor*>(&default_reactor_);
338   }
339 
340   /// Constructors for use by derived classes
341   ServerContextBase();
342   ServerContextBase(gpr_timespec deadline, grpc_metadata_array* arr);
343 
set_context_allocator(ContextAllocator * context_allocator)344   void set_context_allocator(ContextAllocator* context_allocator) {
345     context_allocator_ = context_allocator;
346   }
347 
context_allocator()348   ContextAllocator* context_allocator() const { return context_allocator_; }
349 
350  private:
351   friend class ::grpc::testing::InteropServerContextInspector;
352   friend class ::grpc::testing::ServerContextTestSpouse;
353   friend class ::grpc::testing::DefaultReactorTestPeer;
354   friend class ::grpc::ServerInterface;
355   friend class ::grpc::Server;
356   template <class W, class R>
357   friend class ::grpc::ServerAsyncReader;
358   template <class W>
359   friend class ::grpc::ServerAsyncWriter;
360   template <class W>
361   friend class ::grpc::ServerAsyncResponseWriter;
362   template <class W, class R>
363   friend class ::grpc::ServerAsyncReaderWriter;
364   template <class R>
365   friend class ::grpc::ServerReader;
366   template <class W>
367   friend class ::grpc::ServerWriter;
368   template <class W, class R>
369   friend class ::grpc::internal::ServerReaderWriterBody;
370   template <class ResponseType>
371   friend void ::grpc::internal::UnaryRunHandlerHelper(
372       const internal::MethodHandler::HandlerParameter& param, ResponseType* rsp,
373       Status& status);
374   template <class ServiceType, class RequestType, class ResponseType,
375             class BaseRequestType, class BaseResponseType>
376   friend class ::grpc::internal::RpcMethodHandler;
377   template <class ServiceType, class RequestType, class ResponseType>
378   friend class ::grpc::internal::ClientStreamingHandler;
379   template <class ServiceType, class RequestType, class ResponseType>
380   friend class ::grpc::internal::ServerStreamingHandler;
381   template <class Streamer, bool WriteNeeded>
382   friend class ::grpc::internal::TemplatedBidiStreamingHandler;
383   template <class RequestType, class ResponseType>
384   friend class ::grpc::internal::CallbackUnaryHandler;
385   template <class RequestType, class ResponseType>
386   friend class ::grpc::internal::CallbackClientStreamingHandler;
387   template <class RequestType, class ResponseType>
388   friend class ::grpc::internal::CallbackServerStreamingHandler;
389   template <class RequestType, class ResponseType>
390   friend class ::grpc::internal::CallbackBidiHandler;
391   template <::grpc::StatusCode code>
392   friend class ::grpc::internal::ErrorMethodHandler;
393   template <class Base>
394   friend class ::grpc::internal::FinishOnlyReactor;
395   friend class ::grpc::ClientContext;
396   friend class ::grpc::GenericServerContext;
397 #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
398   friend class ::grpc::GenericCallbackServerContext;
399 #else
400   friend class ::grpc::experimental::GenericCallbackServerContext;
401 #endif
402 
403   /// Prevent copying.
404   ServerContextBase(const ServerContextBase&);
405   ServerContextBase& operator=(const ServerContextBase&);
406 
407   class CompletionOp;
408 
409   void BeginCompletionOp(
410       ::grpc::internal::Call* call, std::function<void(bool)> callback,
411       ::grpc::internal::ServerCallbackCall* callback_controller);
412   /// Return the tag queued by BeginCompletionOp()
413   ::grpc::internal::CompletionQueueTag* GetCompletionOpTag();
414 
set_call(grpc_call * call)415   void set_call(grpc_call* call) { call_.call = call; }
416 
417   void BindDeadlineAndMetadata(gpr_timespec deadline, grpc_metadata_array* arr);
418 
initial_metadata_flags()419   uint32_t initial_metadata_flags() const { return 0; }
420 
set_server_rpc_info(const char * method,::grpc::internal::RpcMethod::RpcType type,const std::vector<std::unique_ptr<::grpc::experimental::ServerInterceptorFactoryInterface>> & creators)421   ::grpc::experimental::ServerRpcInfo* set_server_rpc_info(
422       const char* method, ::grpc::internal::RpcMethod::RpcType type,
423       const std::vector<std::unique_ptr<
424           ::grpc::experimental::ServerInterceptorFactoryInterface>>& creators) {
425     if (!creators.empty()) {
426       rpc_info_ = new ::grpc::experimental::ServerRpcInfo(this, method, type);
427       rpc_info_->RegisterInterceptors(creators);
428     }
429     return rpc_info_;
430   }
431 
set_message_allocator_state(::grpc::experimental::RpcAllocatorState * allocator_state)432   void set_message_allocator_state(
433       ::grpc::experimental::RpcAllocatorState* allocator_state) {
434     message_allocator_state_ = allocator_state;
435   }
436 
437   struct CallWrapper {
438     ~CallWrapper();
439 
440     grpc_call* call = nullptr;
441   };
442 
443   // NOTE: call_ must be the first data member of this object so that its
444   //       destructor is the last to be called, since its destructor may unref
445   //       the underlying core call which holds the arena that may be used to
446   //       hold this object.
447   CallWrapper call_;
448 
449   CompletionOp* completion_op_ = nullptr;
450   bool has_notify_when_done_tag_ = false;
451   void* async_notify_when_done_tag_ = nullptr;
452   ::grpc::internal::CallbackWithSuccessTag completion_tag_;
453 
454   gpr_timespec deadline_;
455   ::grpc::CompletionQueue* cq_ = nullptr;
456   bool sent_initial_metadata_ = false;
457   mutable std::shared_ptr<const ::grpc::AuthContext> auth_context_;
458   mutable ::grpc::internal::MetadataMap client_metadata_;
459   std::multimap<std::string, std::string> initial_metadata_;
460   std::multimap<std::string, std::string> trailing_metadata_;
461 
462   bool compression_level_set_ = false;
463   grpc_compression_level compression_level_;
464   grpc_compression_algorithm compression_algorithm_;
465 
466   ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
467                               ::grpc::internal::CallOpSendMessage>
468       pending_ops_;
469   bool has_pending_ops_ = false;
470 
471   ::grpc::experimental::ServerRpcInfo* rpc_info_ = nullptr;
472   ::grpc::experimental::RpcAllocatorState* message_allocator_state_ = nullptr;
473   ContextAllocator* context_allocator_ = nullptr;
474 
475   class Reactor : public ::grpc::ServerUnaryReactor {
476    public:
OnCancel()477     void OnCancel() override {}
OnDone()478     void OnDone() override {}
479     // Override InternalInlineable for this class since its reactions are
480     // trivial and thus do not need to be run from the executor (triggering a
481     // thread hop). This should only be used by internal reactors (thus the
482     // name) and not by user application code.
InternalInlineable()483     bool InternalInlineable() override { return true; }
484   };
485 
SetupTestDefaultReactor(std::function<void (::grpc::Status)> func)486   void SetupTestDefaultReactor(std::function<void(::grpc::Status)> func) {
487     // NOLINTNEXTLINE(modernize-make-unique)
488     test_unary_.reset(new TestServerCallbackUnary(this, std::move(func)));
489   }
test_status_set()490   bool test_status_set() const {
491     return (test_unary_ != nullptr) && test_unary_->status_set();
492   }
test_status()493   ::grpc::Status test_status() const { return test_unary_->status(); }
494 
495   class TestServerCallbackUnary : public ::grpc::ServerCallbackUnary {
496    public:
TestServerCallbackUnary(ServerContextBase * ctx,std::function<void (::grpc::Status)> func)497     TestServerCallbackUnary(ServerContextBase* ctx,
498                             std::function<void(::grpc::Status)> func)
499         : reactor_(ctx->DefaultReactor()), func_(std::move(func)) {
500       this->BindReactor(reactor_);
501     }
Finish(::grpc::Status s)502     void Finish(::grpc::Status s) override {
503       status_ = s;
504       func_(std::move(s));
505       status_set_.store(true, std::memory_order_release);
506     }
SendInitialMetadata()507     void SendInitialMetadata() override {}
508 
status_set()509     bool status_set() const {
510       return status_set_.load(std::memory_order_acquire);
511     }
status()512     ::grpc::Status status() const { return status_; }
513 
514    private:
CallOnDone()515     void CallOnDone() override {}
reactor()516     ::grpc::internal::ServerReactor* reactor() override { return reactor_; }
517 
518     ::grpc::ServerUnaryReactor* const reactor_;
519     std::atomic_bool status_set_{false};
520     ::grpc::Status status_;
521     const std::function<void(::grpc::Status s)> func_;
522   };
523 
524   typename std::aligned_storage<sizeof(Reactor), alignof(Reactor)>::type
525       default_reactor_;
526   std::atomic_bool default_reactor_used_{false};
527   std::unique_ptr<TestServerCallbackUnary> test_unary_;
528 };
529 
530 /// A ServerContext or CallbackServerContext allows the code implementing a
531 /// service handler to:
532 ///
533 /// - Add custom initial and trailing metadata key-value pairs that will
534 ///   propagated to the client side.
535 /// - Control call settings such as compression and authentication.
536 /// - Access metadata coming from the client.
537 /// - Get performance metrics (ie, census).
538 ///
539 /// Context settings are only relevant to the call handler they are supplied to,
540 /// that is to say, they aren't sticky across multiple calls. Some of these
541 /// settings, such as the compression options, can be made persistent at server
542 /// construction time by specifying the appropriate \a ChannelArguments
543 /// to a \a grpc::ServerBuilder, via \a ServerBuilder::AddChannelArgument.
544 ///
545 /// \warning ServerContext instances should \em not be reused across rpcs.
546 class ServerContext : public ServerContextBase {
547  public:
ServerContext()548   ServerContext() {}  // for async calls
549 
550   using ServerContextBase::AddInitialMetadata;
551   using ServerContextBase::AddTrailingMetadata;
552   using ServerContextBase::auth_context;
553   using ServerContextBase::c_call;
554   using ServerContextBase::census_context;
555   using ServerContextBase::client_metadata;
556   using ServerContextBase::compression_algorithm;
557   using ServerContextBase::compression_level;
558   using ServerContextBase::compression_level_set;
559   using ServerContextBase::deadline;
560   using ServerContextBase::IsCancelled;
561   using ServerContextBase::peer;
562   using ServerContextBase::raw_deadline;
563   using ServerContextBase::set_compression_algorithm;
564   using ServerContextBase::set_compression_level;
565   using ServerContextBase::SetLoadReportingCosts;
566   using ServerContextBase::TryCancel;
567 
568   // Sync/CQ-based Async ServerContext only
569   using ServerContextBase::AsyncNotifyWhenDone;
570 
571  private:
572   // Constructor for internal use by server only
573   friend class ::grpc::Server;
ServerContext(gpr_timespec deadline,grpc_metadata_array * arr)574   ServerContext(gpr_timespec deadline, grpc_metadata_array* arr)
575       : ServerContextBase(deadline, arr) {}
576 
577   // CallbackServerContext only
578   using ServerContextBase::DefaultReactor;
579   using ServerContextBase::GetRpcAllocatorState;
580 
581   /// Prevent copying.
582   ServerContext(const ServerContext&) = delete;
583   ServerContext& operator=(const ServerContext&) = delete;
584 };
585 
586 class CallbackServerContext : public ServerContextBase {
587  public:
588   /// Public constructors are for direct use only by mocking tests. In practice,
589   /// these objects will be owned by the library.
CallbackServerContext()590   CallbackServerContext() {}
591 
592   using ServerContextBase::AddInitialMetadata;
593   using ServerContextBase::AddTrailingMetadata;
594   using ServerContextBase::auth_context;
595   using ServerContextBase::c_call;
596   using ServerContextBase::census_context;
597   using ServerContextBase::client_metadata;
598   using ServerContextBase::compression_algorithm;
599   using ServerContextBase::compression_level;
600   using ServerContextBase::compression_level_set;
601   using ServerContextBase::context_allocator;
602   using ServerContextBase::deadline;
603   using ServerContextBase::IsCancelled;
604   using ServerContextBase::peer;
605   using ServerContextBase::raw_deadline;
606   using ServerContextBase::set_compression_algorithm;
607   using ServerContextBase::set_compression_level;
608   using ServerContextBase::set_context_allocator;
609   using ServerContextBase::SetLoadReportingCosts;
610   using ServerContextBase::TryCancel;
611 
612   // CallbackServerContext only
613   using ServerContextBase::DefaultReactor;
614   using ServerContextBase::GetRpcAllocatorState;
615 
616  private:
617   // Sync/CQ-based Async ServerContext only
618   using ServerContextBase::AsyncNotifyWhenDone;
619 
620   /// Prevent copying.
621   CallbackServerContext(const CallbackServerContext&) = delete;
622   CallbackServerContext& operator=(const CallbackServerContext&) = delete;
623 };
624 
625 /// A CallbackServerContext allows users to use the contents of the
626 /// CallbackServerContext or GenericCallbackServerContext structure for the
627 /// callback API.
628 /// The library will invoke the allocator any time a new call is initiated.
629 /// and call the Release method after the server OnDone.
630 class ContextAllocator {
631  public:
~ContextAllocator()632   virtual ~ContextAllocator() {}
633 
NewCallbackServerContext()634   virtual CallbackServerContext* NewCallbackServerContext() { return nullptr; }
635 
636 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
637   virtual experimental::GenericCallbackServerContext*
NewGenericCallbackServerContext()638   NewGenericCallbackServerContext() {
639     return nullptr;
640   }
641 #else
NewGenericCallbackServerContext()642   virtual GenericCallbackServerContext* NewGenericCallbackServerContext() {
643     return nullptr;
644   }
645 #endif
646 
Release(CallbackServerContext *)647   virtual void Release(CallbackServerContext*) {}
648 
649 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
Release(experimental::GenericCallbackServerContext *)650   virtual void Release(experimental::GenericCallbackServerContext*) {}
651 #else
Release(GenericCallbackServerContext *)652   virtual void Release(GenericCallbackServerContext*) {}
653 #endif
654 };
655 
656 }  // namespace grpc
657 
658 static_assert(
659     std::is_base_of<::grpc::ServerContextBase, ::grpc::ServerContext>::value,
660     "improper base class");
661 static_assert(std::is_base_of<::grpc::ServerContextBase,
662                               ::grpc::CallbackServerContext>::value,
663               "improper base class");
664 static_assert(sizeof(::grpc::ServerContextBase) ==
665                   sizeof(::grpc::ServerContext),
666               "wrong size");
667 static_assert(sizeof(::grpc::ServerContextBase) ==
668                   sizeof(::grpc::CallbackServerContext),
669               "wrong size");
670 
671 #endif  // GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
672