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