server_cc.cc 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341
  1. /*
  2. * Copyright 2015 gRPC authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. #include <grpcpp/server.h>
  18. #include <cstdlib>
  19. #include <sstream>
  20. #include <type_traits>
  21. #include <utility>
  22. #include <grpc/grpc.h>
  23. #include <grpc/impl/codegen/grpc_types.h>
  24. #include <grpc/support/alloc.h>
  25. #include <grpc/support/log.h>
  26. #include <grpcpp/completion_queue.h>
  27. #include <grpcpp/generic/async_generic_service.h>
  28. #include <grpcpp/impl/codegen/async_unary_call.h>
  29. #include <grpcpp/impl/codegen/byte_buffer.h>
  30. #include <grpcpp/impl/codegen/call.h>
  31. #include <grpcpp/impl/codegen/completion_queue_tag.h>
  32. #include <grpcpp/impl/codegen/method_handler.h>
  33. #include <grpcpp/impl/codegen/server_interceptor.h>
  34. #include <grpcpp/impl/grpc_library.h>
  35. #include <grpcpp/impl/rpc_service_method.h>
  36. #include <grpcpp/impl/server_initializer.h>
  37. #include <grpcpp/impl/service_type.h>
  38. #include <grpcpp/security/server_credentials.h>
  39. #include <grpcpp/server_context.h>
  40. #include <grpcpp/support/time.h>
  41. #include "absl/memory/memory.h"
  42. #include "src/core/ext/transport/inproc/inproc_transport.h"
  43. #include "src/core/lib/gprpp/manual_constructor.h"
  44. #include "src/core/lib/iomgr/exec_ctx.h"
  45. #include "src/core/lib/iomgr/iomgr.h"
  46. #include "src/core/lib/profiling/timers.h"
  47. #include "src/core/lib/surface/call.h"
  48. #include "src/core/lib/surface/completion_queue.h"
  49. #include "src/core/lib/surface/server.h"
  50. #include "src/cpp/client/create_channel_internal.h"
  51. #include "src/cpp/server/external_connection_acceptor_impl.h"
  52. #include "src/cpp/server/health/default_health_check_service.h"
  53. #include "src/cpp/thread_manager/thread_manager.h"
  54. namespace grpc {
  55. namespace {
  56. // The default value for maximum number of threads that can be created in the
  57. // sync server. This value of INT_MAX is chosen to match the default behavior if
  58. // no ResourceQuota is set. To modify the max number of threads in a sync
  59. // server, pass a custom ResourceQuota object (with the desired number of
  60. // max-threads set) to the server builder.
  61. #define DEFAULT_MAX_SYNC_SERVER_THREADS INT_MAX
  62. class DefaultGlobalCallbacks final : public Server::GlobalCallbacks {
  63. public:
  64. ~DefaultGlobalCallbacks() override {}
  65. void PreSynchronousRequest(ServerContext* /*context*/) override {}
  66. void PostSynchronousRequest(ServerContext* /*context*/) override {}
  67. };
  68. std::shared_ptr<Server::GlobalCallbacks> g_callbacks = nullptr;
  69. gpr_once g_once_init_callbacks = GPR_ONCE_INIT;
  70. void InitGlobalCallbacks() {
  71. if (!g_callbacks) {
  72. g_callbacks.reset(new DefaultGlobalCallbacks());
  73. }
  74. }
  75. class ShutdownTag : public internal::CompletionQueueTag {
  76. public:
  77. bool FinalizeResult(void** /*tag*/, bool* /*status*/) override {
  78. return false;
  79. }
  80. };
  81. class PhonyTag : public internal::CompletionQueueTag {
  82. public:
  83. bool FinalizeResult(void** /*tag*/, bool* /*status*/) override {
  84. return true;
  85. }
  86. };
  87. class UnimplementedAsyncRequestContext {
  88. protected:
  89. UnimplementedAsyncRequestContext() : generic_stream_(&server_context_) {}
  90. GenericServerContext server_context_;
  91. GenericServerAsyncReaderWriter generic_stream_;
  92. };
  93. // TODO(vjpai): Just for this file, use some contents of the experimental
  94. // namespace here to make the code easier to read below. Remove this when
  95. // de-experimentalized fully.
  96. #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL
  97. using ::grpc::experimental::CallbackGenericService;
  98. using ::grpc::experimental::CallbackServerContext;
  99. using ::grpc::experimental::GenericCallbackServerContext;
  100. #endif
  101. } // namespace
  102. ServerInterface::BaseAsyncRequest::BaseAsyncRequest(
  103. ServerInterface* server, ServerContext* context,
  104. internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
  105. ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize)
  106. : server_(server),
  107. context_(context),
  108. stream_(stream),
  109. call_cq_(call_cq),
  110. notification_cq_(notification_cq),
  111. tag_(tag),
  112. delete_on_finalize_(delete_on_finalize),
  113. call_(nullptr),
  114. done_intercepting_(false) {
  115. /* Set up interception state partially for the receive ops. call_wrapper_ is
  116. * not filled at this point, but it will be filled before the interceptors are
  117. * run. */
  118. interceptor_methods_.SetCall(&call_wrapper_);
  119. interceptor_methods_.SetReverse();
  120. call_cq_->RegisterAvalanching(); // This op will trigger more ops
  121. }
  122. ServerInterface::BaseAsyncRequest::~BaseAsyncRequest() {
  123. call_cq_->CompleteAvalanching();
  124. }
  125. bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag,
  126. bool* status) {
  127. if (done_intercepting_) {
  128. *tag = tag_;
  129. if (delete_on_finalize_) {
  130. delete this;
  131. }
  132. return true;
  133. }
  134. context_->set_call(call_);
  135. context_->cq_ = call_cq_;
  136. if (call_wrapper_.call() == nullptr) {
  137. // Fill it since it is empty.
  138. call_wrapper_ = internal::Call(
  139. call_, server_, call_cq_, server_->max_receive_message_size(), nullptr);
  140. }
  141. // just the pointers inside call are copied here
  142. stream_->BindCall(&call_wrapper_);
  143. if (*status && call_ && call_wrapper_.server_rpc_info()) {
  144. done_intercepting_ = true;
  145. // Set interception point for RECV INITIAL METADATA
  146. interceptor_methods_.AddInterceptionHookPoint(
  147. experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA);
  148. interceptor_methods_.SetRecvInitialMetadata(&context_->client_metadata_);
  149. if (interceptor_methods_.RunInterceptors(
  150. [this]() { ContinueFinalizeResultAfterInterception(); })) {
  151. // There are no interceptors to run. Continue
  152. } else {
  153. // There were interceptors to be run, so
  154. // ContinueFinalizeResultAfterInterception will be run when interceptors
  155. // are done.
  156. return false;
  157. }
  158. }
  159. if (*status && call_) {
  160. context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr);
  161. }
  162. *tag = tag_;
  163. if (delete_on_finalize_) {
  164. delete this;
  165. }
  166. return true;
  167. }
  168. void ServerInterface::BaseAsyncRequest::
  169. ContinueFinalizeResultAfterInterception() {
  170. context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr);
  171. // Queue a tag which will be returned immediately
  172. grpc_core::ExecCtx exec_ctx;
  173. grpc_cq_begin_op(notification_cq_->cq(), this);
  174. grpc_cq_end_op(
  175. notification_cq_->cq(), this, GRPC_ERROR_NONE,
  176. [](void* /*arg*/, grpc_cq_completion* completion) { delete completion; },
  177. nullptr, new grpc_cq_completion());
  178. }
  179. ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest(
  180. ServerInterface* server, ServerContext* context,
  181. internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
  182. ServerCompletionQueue* notification_cq, void* tag, const char* name,
  183. internal::RpcMethod::RpcType type)
  184. : BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag,
  185. true),
  186. name_(name),
  187. type_(type) {}
  188. void ServerInterface::RegisteredAsyncRequest::IssueRequest(
  189. void* registered_method, grpc_byte_buffer** payload,
  190. ServerCompletionQueue* notification_cq) {
  191. // The following call_start_batch is internally-generated so no need for an
  192. // explanatory log on failure.
  193. GPR_ASSERT(grpc_server_request_registered_call(
  194. server_->server(), registered_method, &call_,
  195. &context_->deadline_, context_->client_metadata_.arr(),
  196. payload, call_cq_->cq(), notification_cq->cq(),
  197. this) == GRPC_CALL_OK);
  198. }
  199. ServerInterface::GenericAsyncRequest::GenericAsyncRequest(
  200. ServerInterface* server, GenericServerContext* context,
  201. internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
  202. ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize)
  203. : BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag,
  204. delete_on_finalize) {
  205. grpc_call_details_init(&call_details_);
  206. GPR_ASSERT(notification_cq);
  207. GPR_ASSERT(call_cq);
  208. // The following call_start_batch is internally-generated so no need for an
  209. // explanatory log on failure.
  210. GPR_ASSERT(grpc_server_request_call(server->server(), &call_, &call_details_,
  211. context->client_metadata_.arr(),
  212. call_cq->cq(), notification_cq->cq(),
  213. this) == GRPC_CALL_OK);
  214. }
  215. bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag,
  216. bool* status) {
  217. // If we are done intercepting, there is nothing more for us to do
  218. if (done_intercepting_) {
  219. return BaseAsyncRequest::FinalizeResult(tag, status);
  220. }
  221. // TODO(yangg) remove the copy here.
  222. if (*status) {
  223. static_cast<GenericServerContext*>(context_)->method_ =
  224. StringFromCopiedSlice(call_details_.method);
  225. static_cast<GenericServerContext*>(context_)->host_ =
  226. StringFromCopiedSlice(call_details_.host);
  227. context_->deadline_ = call_details_.deadline;
  228. }
  229. grpc_slice_unref(call_details_.method);
  230. grpc_slice_unref(call_details_.host);
  231. call_wrapper_ = internal::Call(
  232. call_, server_, call_cq_, server_->max_receive_message_size(),
  233. context_->set_server_rpc_info(
  234. static_cast<GenericServerContext*>(context_)->method_.c_str(),
  235. internal::RpcMethod::BIDI_STREAMING,
  236. *server_->interceptor_creators()));
  237. return BaseAsyncRequest::FinalizeResult(tag, status);
  238. }
  239. namespace {
  240. class ShutdownCallback : public grpc_experimental_completion_queue_functor {
  241. public:
  242. ShutdownCallback() {
  243. functor_run = &ShutdownCallback::Run;
  244. // Set inlineable to true since this callback is trivial and thus does not
  245. // need to be run from the executor (triggering a thread hop). This should
  246. // only be used by internal callbacks like this and not by user application
  247. // code.
  248. inlineable = true;
  249. }
  250. // TakeCQ takes ownership of the cq into the shutdown callback
  251. // so that the shutdown callback will be responsible for destroying it
  252. void TakeCQ(CompletionQueue* cq) { cq_ = cq; }
  253. // The Run function will get invoked by the completion queue library
  254. // when the shutdown is actually complete
  255. static void Run(grpc_experimental_completion_queue_functor* cb, int) {
  256. auto* callback = static_cast<ShutdownCallback*>(cb);
  257. delete callback->cq_;
  258. delete callback;
  259. }
  260. private:
  261. CompletionQueue* cq_ = nullptr;
  262. };
  263. } // namespace
  264. /// Use private inheritance rather than composition only to establish order
  265. /// of construction, since the public base class should be constructed after the
  266. /// elements belonging to the private base class are constructed. This is not
  267. /// possible using true composition.
  268. class Server::UnimplementedAsyncRequest final
  269. : private grpc::UnimplementedAsyncRequestContext,
  270. public GenericAsyncRequest {
  271. public:
  272. UnimplementedAsyncRequest(ServerInterface* server,
  273. grpc::ServerCompletionQueue* cq)
  274. : GenericAsyncRequest(server, &server_context_, &generic_stream_, cq, cq,
  275. nullptr, false) {}
  276. bool FinalizeResult(void** tag, bool* status) override;
  277. grpc::ServerContext* context() { return &server_context_; }
  278. grpc::GenericServerAsyncReaderWriter* stream() { return &generic_stream_; }
  279. };
  280. /// UnimplementedAsyncResponse should not post user-visible completions to the
  281. /// C++ completion queue, but is generated as a CQ event by the core
  282. class Server::UnimplementedAsyncResponse final
  283. : public grpc::internal::CallOpSet<
  284. grpc::internal::CallOpSendInitialMetadata,
  285. grpc::internal::CallOpServerSendStatus> {
  286. public:
  287. explicit UnimplementedAsyncResponse(UnimplementedAsyncRequest* request);
  288. ~UnimplementedAsyncResponse() override { delete request_; }
  289. bool FinalizeResult(void** tag, bool* status) override {
  290. if (grpc::internal::CallOpSet<
  291. grpc::internal::CallOpSendInitialMetadata,
  292. grpc::internal::CallOpServerSendStatus>::FinalizeResult(tag,
  293. status)) {
  294. delete this;
  295. } else {
  296. // The tag was swallowed due to interception. We will see it again.
  297. }
  298. return false;
  299. }
  300. private:
  301. UnimplementedAsyncRequest* const request_;
  302. };
  303. class Server::SyncRequest final : public grpc::internal::CompletionQueueTag {
  304. public:
  305. SyncRequest(Server* server, grpc::internal::RpcServiceMethod* method,
  306. grpc_core::Server::RegisteredCallAllocation* data)
  307. : SyncRequest(server, method) {
  308. CommonSetup(data);
  309. data->deadline = &deadline_;
  310. data->optional_payload = has_request_payload_ ? &request_payload_ : nullptr;
  311. }
  312. SyncRequest(Server* server, grpc::internal::RpcServiceMethod* method,
  313. grpc_core::Server::BatchCallAllocation* data)
  314. : SyncRequest(server, method) {
  315. CommonSetup(data);
  316. call_details_ = new grpc_call_details;
  317. grpc_call_details_init(call_details_);
  318. data->details = call_details_;
  319. }
  320. ~SyncRequest() override {
  321. if (has_request_payload_ && request_payload_) {
  322. grpc_byte_buffer_destroy(request_payload_);
  323. }
  324. wrapped_call_.Destroy();
  325. ctx_.Destroy();
  326. if (call_details_ != nullptr) {
  327. grpc_call_details_destroy(call_details_);
  328. delete call_details_;
  329. }
  330. grpc_metadata_array_destroy(&request_metadata_);
  331. }
  332. bool FinalizeResult(void** /*tag*/, bool* status) override {
  333. if (!*status) {
  334. delete this;
  335. return false;
  336. }
  337. if (call_details_) {
  338. deadline_ = call_details_->deadline;
  339. }
  340. return true;
  341. }
  342. void Run(const std::shared_ptr<GlobalCallbacks>& global_callbacks,
  343. bool resources) {
  344. ctx_.Init(deadline_, &request_metadata_);
  345. wrapped_call_.Init(
  346. call_, server_, &cq_, server_->max_receive_message_size(),
  347. ctx_->ctx.set_server_rpc_info(method_->name(), method_->method_type(),
  348. server_->interceptor_creators_));
  349. ctx_->ctx.set_call(call_);
  350. ctx_->ctx.cq_ = &cq_;
  351. request_metadata_.count = 0;
  352. global_callbacks_ = global_callbacks;
  353. resources_ = resources;
  354. interceptor_methods_.SetCall(&*wrapped_call_);
  355. interceptor_methods_.SetReverse();
  356. // Set interception point for RECV INITIAL METADATA
  357. interceptor_methods_.AddInterceptionHookPoint(
  358. grpc::experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA);
  359. interceptor_methods_.SetRecvInitialMetadata(&ctx_->ctx.client_metadata_);
  360. if (has_request_payload_) {
  361. // Set interception point for RECV MESSAGE
  362. auto* handler = resources_ ? method_->handler()
  363. : server_->resource_exhausted_handler_.get();
  364. deserialized_request_ = handler->Deserialize(call_, request_payload_,
  365. &request_status_, nullptr);
  366. request_payload_ = nullptr;
  367. interceptor_methods_.AddInterceptionHookPoint(
  368. grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE);
  369. interceptor_methods_.SetRecvMessage(deserialized_request_, nullptr);
  370. }
  371. if (interceptor_methods_.RunInterceptors(
  372. [this]() { ContinueRunAfterInterception(); })) {
  373. ContinueRunAfterInterception();
  374. } else {
  375. // There were interceptors to be run, so ContinueRunAfterInterception
  376. // will be run when interceptors are done.
  377. }
  378. }
  379. void ContinueRunAfterInterception() {
  380. {
  381. ctx_->ctx.BeginCompletionOp(&*wrapped_call_, nullptr, nullptr);
  382. global_callbacks_->PreSynchronousRequest(&ctx_->ctx);
  383. auto* handler = resources_ ? method_->handler()
  384. : server_->resource_exhausted_handler_.get();
  385. handler->RunHandler(grpc::internal::MethodHandler::HandlerParameter(
  386. &*wrapped_call_, &ctx_->ctx, deserialized_request_, request_status_,
  387. nullptr, nullptr));
  388. global_callbacks_->PostSynchronousRequest(&ctx_->ctx);
  389. cq_.Shutdown();
  390. grpc::internal::CompletionQueueTag* op_tag =
  391. ctx_->ctx.GetCompletionOpTag();
  392. cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME));
  393. /* Ensure the cq_ is shutdown */
  394. grpc::PhonyTag ignored_tag;
  395. GPR_ASSERT(cq_.Pluck(&ignored_tag) == false);
  396. }
  397. delete this;
  398. }
  399. private:
  400. SyncRequest(Server* server, grpc::internal::RpcServiceMethod* method)
  401. : server_(server),
  402. method_(method),
  403. has_request_payload_(method->method_type() ==
  404. grpc::internal::RpcMethod::NORMAL_RPC ||
  405. method->method_type() ==
  406. grpc::internal::RpcMethod::SERVER_STREAMING),
  407. cq_(grpc_completion_queue_create_for_pluck(nullptr)) {}
  408. template <class CallAllocation>
  409. void CommonSetup(CallAllocation* data) {
  410. grpc_metadata_array_init(&request_metadata_);
  411. data->tag = static_cast<void*>(this);
  412. data->call = &call_;
  413. data->initial_metadata = &request_metadata_;
  414. data->cq = cq_.cq();
  415. }
  416. Server* const server_;
  417. grpc::internal::RpcServiceMethod* const method_;
  418. const bool has_request_payload_;
  419. grpc_call* call_;
  420. grpc_call_details* call_details_ = nullptr;
  421. gpr_timespec deadline_;
  422. grpc_metadata_array request_metadata_;
  423. grpc_byte_buffer* request_payload_;
  424. grpc::CompletionQueue cq_;
  425. grpc::Status request_status_;
  426. std::shared_ptr<GlobalCallbacks> global_callbacks_;
  427. bool resources_;
  428. void* deserialized_request_ = nullptr;
  429. grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_;
  430. // ServerContextWrapper allows ManualConstructor while using a private
  431. // contructor of ServerContext via this friend class.
  432. struct ServerContextWrapper {
  433. ServerContext ctx;
  434. ServerContextWrapper(gpr_timespec deadline, grpc_metadata_array* arr)
  435. : ctx(deadline, arr) {}
  436. };
  437. grpc_core::ManualConstructor<ServerContextWrapper> ctx_;
  438. grpc_core::ManualConstructor<internal::Call> wrapped_call_;
  439. };
  440. template <class ServerContextType>
  441. class Server::CallbackRequest final
  442. : public grpc::internal::CompletionQueueTag {
  443. public:
  444. static_assert(
  445. std::is_base_of<grpc::CallbackServerContext, ServerContextType>::value,
  446. "ServerContextType must be derived from CallbackServerContext");
  447. // For codegen services, the value of method represents the defined
  448. // characteristics of the method being requested. For generic services, method
  449. // is nullptr since these services don't have pre-defined methods.
  450. CallbackRequest(Server* server, grpc::internal::RpcServiceMethod* method,
  451. grpc::CompletionQueue* cq,
  452. grpc_core::Server::RegisteredCallAllocation* data)
  453. : server_(server),
  454. method_(method),
  455. has_request_payload_(method->method_type() ==
  456. grpc::internal::RpcMethod::NORMAL_RPC ||
  457. method->method_type() ==
  458. grpc::internal::RpcMethod::SERVER_STREAMING),
  459. cq_(cq),
  460. tag_(this),
  461. ctx_(server_->context_allocator() != nullptr
  462. ? server_->context_allocator()->NewCallbackServerContext()
  463. : nullptr) {
  464. CommonSetup(server, data);
  465. data->deadline = &deadline_;
  466. data->optional_payload = has_request_payload_ ? &request_payload_ : nullptr;
  467. }
  468. // For generic services, method is nullptr since these services don't have
  469. // pre-defined methods.
  470. CallbackRequest(Server* server, grpc::CompletionQueue* cq,
  471. grpc_core::Server::BatchCallAllocation* data)
  472. : server_(server),
  473. method_(nullptr),
  474. has_request_payload_(false),
  475. call_details_(new grpc_call_details),
  476. cq_(cq),
  477. tag_(this),
  478. ctx_(server_->context_allocator() != nullptr
  479. ? server_->context_allocator()
  480. ->NewGenericCallbackServerContext()
  481. : nullptr) {
  482. CommonSetup(server, data);
  483. grpc_call_details_init(call_details_);
  484. data->details = call_details_;
  485. }
  486. ~CallbackRequest() override {
  487. delete call_details_;
  488. grpc_metadata_array_destroy(&request_metadata_);
  489. if (has_request_payload_ && request_payload_) {
  490. grpc_byte_buffer_destroy(request_payload_);
  491. }
  492. if (server_->context_allocator() == nullptr || ctx_alloc_by_default_) {
  493. delete ctx_;
  494. }
  495. server_->UnrefWithPossibleNotify();
  496. }
  497. // Needs specialization to account for different processing of metadata
  498. // in generic API
  499. bool FinalizeResult(void** tag, bool* status) override;
  500. private:
  501. // method_name needs to be specialized between named method and generic
  502. const char* method_name() const;
  503. class CallbackCallTag : public grpc_experimental_completion_queue_functor {
  504. public:
  505. explicit CallbackCallTag(Server::CallbackRequest<ServerContextType>* req)
  506. : req_(req) {
  507. functor_run = &CallbackCallTag::StaticRun;
  508. // Set inlineable to true since this callback is internally-controlled
  509. // without taking any locks, and thus does not need to be run from the
  510. // executor (which triggers a thread hop). This should only be used by
  511. // internal callbacks like this and not by user application code. The work
  512. // here is actually non-trivial, but there is no chance of having user
  513. // locks conflict with each other so it's ok to run inlined.
  514. inlineable = true;
  515. }
  516. // force_run can not be performed on a tag if operations using this tag
  517. // have been sent to PerformOpsOnCall. It is intended for error conditions
  518. // that are detected before the operations are internally processed.
  519. void force_run(bool ok) { Run(ok); }
  520. private:
  521. Server::CallbackRequest<ServerContextType>* req_;
  522. grpc::internal::Call* call_;
  523. static void StaticRun(grpc_experimental_completion_queue_functor* cb,
  524. int ok) {
  525. static_cast<CallbackCallTag*>(cb)->Run(static_cast<bool>(ok));
  526. }
  527. void Run(bool ok) {
  528. void* ignored = req_;
  529. bool new_ok = ok;
  530. GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok));
  531. GPR_ASSERT(ignored == req_);
  532. if (!ok) {
  533. // The call has been shutdown.
  534. // Delete its contents to free up the request.
  535. delete req_;
  536. return;
  537. }
  538. // Bind the call, deadline, and metadata from what we got
  539. req_->ctx_->set_call(req_->call_);
  540. req_->ctx_->cq_ = req_->cq_;
  541. req_->ctx_->BindDeadlineAndMetadata(req_->deadline_,
  542. &req_->request_metadata_);
  543. req_->request_metadata_.count = 0;
  544. // Create a C++ Call to control the underlying core call
  545. call_ =
  546. new (grpc_call_arena_alloc(req_->call_, sizeof(grpc::internal::Call)))
  547. grpc::internal::Call(
  548. req_->call_, req_->server_, req_->cq_,
  549. req_->server_->max_receive_message_size(),
  550. req_->ctx_->set_server_rpc_info(
  551. req_->method_name(),
  552. (req_->method_ != nullptr)
  553. ? req_->method_->method_type()
  554. : grpc::internal::RpcMethod::BIDI_STREAMING,
  555. req_->server_->interceptor_creators_));
  556. req_->interceptor_methods_.SetCall(call_);
  557. req_->interceptor_methods_.SetReverse();
  558. // Set interception point for RECV INITIAL METADATA
  559. req_->interceptor_methods_.AddInterceptionHookPoint(
  560. grpc::experimental::InterceptionHookPoints::
  561. POST_RECV_INITIAL_METADATA);
  562. req_->interceptor_methods_.SetRecvInitialMetadata(
  563. &req_->ctx_->client_metadata_);
  564. if (req_->has_request_payload_) {
  565. // Set interception point for RECV MESSAGE
  566. req_->request_ = req_->method_->handler()->Deserialize(
  567. req_->call_, req_->request_payload_, &req_->request_status_,
  568. &req_->handler_data_);
  569. req_->request_payload_ = nullptr;
  570. req_->interceptor_methods_.AddInterceptionHookPoint(
  571. grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE);
  572. req_->interceptor_methods_.SetRecvMessage(req_->request_, nullptr);
  573. }
  574. if (req_->interceptor_methods_.RunInterceptors(
  575. [this] { ContinueRunAfterInterception(); })) {
  576. ContinueRunAfterInterception();
  577. } else {
  578. // There were interceptors to be run, so ContinueRunAfterInterception
  579. // will be run when interceptors are done.
  580. }
  581. }
  582. void ContinueRunAfterInterception() {
  583. auto* handler = (req_->method_ != nullptr)
  584. ? req_->method_->handler()
  585. : req_->server_->generic_handler_.get();
  586. handler->RunHandler(grpc::internal::MethodHandler::HandlerParameter(
  587. call_, req_->ctx_, req_->request_, req_->request_status_,
  588. req_->handler_data_, [this] { delete req_; }));
  589. }
  590. };
  591. template <class CallAllocation>
  592. void CommonSetup(Server* server, CallAllocation* data) {
  593. server->Ref();
  594. grpc_metadata_array_init(&request_metadata_);
  595. data->tag = static_cast<void*>(&tag_);
  596. data->call = &call_;
  597. data->initial_metadata = &request_metadata_;
  598. if (ctx_ == nullptr) {
  599. // TODO(ddyihai): allocate the context with grpc_call_arena_alloc.
  600. ctx_ = new ServerContextType();
  601. ctx_alloc_by_default_ = true;
  602. }
  603. ctx_->set_context_allocator(server->context_allocator());
  604. data->cq = cq_->cq();
  605. }
  606. Server* const server_;
  607. grpc::internal::RpcServiceMethod* const method_;
  608. const bool has_request_payload_;
  609. grpc_byte_buffer* request_payload_ = nullptr;
  610. void* request_ = nullptr;
  611. void* handler_data_ = nullptr;
  612. grpc::Status request_status_;
  613. grpc_call_details* const call_details_ = nullptr;
  614. grpc_call* call_;
  615. gpr_timespec deadline_;
  616. grpc_metadata_array request_metadata_;
  617. grpc::CompletionQueue* const cq_;
  618. bool ctx_alloc_by_default_ = false;
  619. CallbackCallTag tag_;
  620. ServerContextType* ctx_ = nullptr;
  621. grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_;
  622. };
  623. template <>
  624. bool Server::CallbackRequest<grpc::CallbackServerContext>::FinalizeResult(
  625. void** /*tag*/, bool* /*status*/) {
  626. return false;
  627. }
  628. template <>
  629. bool Server::CallbackRequest<
  630. grpc::GenericCallbackServerContext>::FinalizeResult(void** /*tag*/,
  631. bool* status) {
  632. if (*status) {
  633. deadline_ = call_details_->deadline;
  634. // TODO(yangg) remove the copy here
  635. ctx_->method_ = grpc::StringFromCopiedSlice(call_details_->method);
  636. ctx_->host_ = grpc::StringFromCopiedSlice(call_details_->host);
  637. }
  638. grpc_slice_unref(call_details_->method);
  639. grpc_slice_unref(call_details_->host);
  640. return false;
  641. }
  642. template <>
  643. const char* Server::CallbackRequest<grpc::CallbackServerContext>::method_name()
  644. const {
  645. return method_->name();
  646. }
  647. template <>
  648. const char* Server::CallbackRequest<
  649. grpc::GenericCallbackServerContext>::method_name() const {
  650. return ctx_->method().c_str();
  651. }
  652. // Implementation of ThreadManager. Each instance of SyncRequestThreadManager
  653. // manages a pool of threads that poll for incoming Sync RPCs and call the
  654. // appropriate RPC handlers
  655. class Server::SyncRequestThreadManager : public grpc::ThreadManager {
  656. public:
  657. SyncRequestThreadManager(Server* server, grpc::CompletionQueue* server_cq,
  658. std::shared_ptr<GlobalCallbacks> global_callbacks,
  659. grpc_resource_quota* rq, int min_pollers,
  660. int max_pollers, int cq_timeout_msec)
  661. : ThreadManager("SyncServer", rq, min_pollers, max_pollers),
  662. server_(server),
  663. server_cq_(server_cq),
  664. cq_timeout_msec_(cq_timeout_msec),
  665. global_callbacks_(std::move(global_callbacks)) {}
  666. WorkStatus PollForWork(void** tag, bool* ok) override {
  667. *tag = nullptr;
  668. // TODO(ctiller): workaround for GPR_TIMESPAN based deadlines not working
  669. // right now
  670. gpr_timespec deadline =
  671. gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
  672. gpr_time_from_millis(cq_timeout_msec_, GPR_TIMESPAN));
  673. switch (server_cq_->AsyncNext(tag, ok, deadline)) {
  674. case grpc::CompletionQueue::TIMEOUT:
  675. return TIMEOUT;
  676. case grpc::CompletionQueue::SHUTDOWN:
  677. return SHUTDOWN;
  678. case grpc::CompletionQueue::GOT_EVENT:
  679. return WORK_FOUND;
  680. }
  681. GPR_UNREACHABLE_CODE(return TIMEOUT);
  682. }
  683. void DoWork(void* tag, bool ok, bool resources) override {
  684. (void)ok;
  685. SyncRequest* sync_req = static_cast<SyncRequest*>(tag);
  686. // Under the AllocatingRequestMatcher model we will never see an invalid tag
  687. // here.
  688. GPR_DEBUG_ASSERT(sync_req != nullptr);
  689. GPR_DEBUG_ASSERT(ok);
  690. GPR_TIMER_SCOPE("sync_req->Run()", 0);
  691. sync_req->Run(global_callbacks_, resources);
  692. }
  693. void AddSyncMethod(grpc::internal::RpcServiceMethod* method, void* tag) {
  694. server_->server()->core_server->SetRegisteredMethodAllocator(
  695. server_cq_->cq(), tag, [this, method] {
  696. grpc_core::Server::RegisteredCallAllocation result;
  697. new SyncRequest(server_, method, &result);
  698. return result;
  699. });
  700. has_sync_method_ = true;
  701. }
  702. void AddUnknownSyncMethod() {
  703. if (has_sync_method_) {
  704. unknown_method_ = absl::make_unique<grpc::internal::RpcServiceMethod>(
  705. "unknown", grpc::internal::RpcMethod::BIDI_STREAMING,
  706. new grpc::internal::UnknownMethodHandler);
  707. server_->server()->core_server->SetBatchMethodAllocator(
  708. server_cq_->cq(), [this] {
  709. grpc_core::Server::BatchCallAllocation result;
  710. new SyncRequest(server_, unknown_method_.get(), &result);
  711. return result;
  712. });
  713. }
  714. }
  715. void Shutdown() override {
  716. ThreadManager::Shutdown();
  717. server_cq_->Shutdown();
  718. }
  719. void Wait() override {
  720. ThreadManager::Wait();
  721. // Drain any pending items from the queue
  722. void* tag;
  723. bool ok;
  724. while (server_cq_->Next(&tag, &ok)) {
  725. // Drain the item and don't do any work on it. It is possible to see this
  726. // if there is an explicit call to Wait that is not part of the actual
  727. // Shutdown.
  728. }
  729. }
  730. void Start() {
  731. if (has_sync_method_) {
  732. Initialize(); // ThreadManager's Initialize()
  733. }
  734. }
  735. private:
  736. Server* server_;
  737. grpc::CompletionQueue* server_cq_;
  738. int cq_timeout_msec_;
  739. bool has_sync_method_ = false;
  740. std::unique_ptr<grpc::internal::RpcServiceMethod> unknown_method_;
  741. std::shared_ptr<Server::GlobalCallbacks> global_callbacks_;
  742. };
  743. static grpc::internal::GrpcLibraryInitializer g_gli_initializer;
  744. Server::Server(
  745. grpc::ChannelArguments* args,
  746. std::shared_ptr<std::vector<std::unique_ptr<grpc::ServerCompletionQueue>>>
  747. sync_server_cqs,
  748. int min_pollers, int max_pollers, int sync_cq_timeout_msec,
  749. std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
  750. acceptors,
  751. grpc_server_config_fetcher* server_config_fetcher,
  752. grpc_resource_quota* server_rq,
  753. std::vector<
  754. std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>>
  755. interceptor_creators)
  756. : acceptors_(std::move(acceptors)),
  757. interceptor_creators_(std::move(interceptor_creators)),
  758. max_receive_message_size_(INT_MIN),
  759. sync_server_cqs_(std::move(sync_server_cqs)),
  760. started_(false),
  761. shutdown_(false),
  762. shutdown_notified_(false),
  763. server_(nullptr),
  764. server_initializer_(new ServerInitializer(this)),
  765. health_check_service_disabled_(false) {
  766. g_gli_initializer.summon();
  767. gpr_once_init(&grpc::g_once_init_callbacks, grpc::InitGlobalCallbacks);
  768. global_callbacks_ = grpc::g_callbacks;
  769. global_callbacks_->UpdateArguments(args);
  770. if (sync_server_cqs_ != nullptr) {
  771. bool default_rq_created = false;
  772. if (server_rq == nullptr) {
  773. server_rq = grpc_resource_quota_create("SyncServer-default-rq");
  774. grpc_resource_quota_set_max_threads(server_rq,
  775. DEFAULT_MAX_SYNC_SERVER_THREADS);
  776. default_rq_created = true;
  777. }
  778. for (const auto& it : *sync_server_cqs_) {
  779. sync_req_mgrs_.emplace_back(new SyncRequestThreadManager(
  780. this, it.get(), global_callbacks_, server_rq, min_pollers,
  781. max_pollers, sync_cq_timeout_msec));
  782. }
  783. if (default_rq_created) {
  784. grpc_resource_quota_unref(server_rq);
  785. }
  786. }
  787. for (auto& acceptor : acceptors_) {
  788. acceptor->SetToChannelArgs(args);
  789. }
  790. grpc_channel_args channel_args;
  791. args->SetChannelArgs(&channel_args);
  792. for (size_t i = 0; i < channel_args.num_args; i++) {
  793. if (0 == strcmp(channel_args.args[i].key,
  794. grpc::kHealthCheckServiceInterfaceArg)) {
  795. if (channel_args.args[i].value.pointer.p == nullptr) {
  796. health_check_service_disabled_ = true;
  797. } else {
  798. health_check_service_.reset(
  799. static_cast<grpc::HealthCheckServiceInterface*>(
  800. channel_args.args[i].value.pointer.p));
  801. }
  802. }
  803. if (0 ==
  804. strcmp(channel_args.args[i].key, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH)) {
  805. max_receive_message_size_ = channel_args.args[i].value.integer;
  806. }
  807. }
  808. server_ = grpc_server_create(&channel_args, nullptr);
  809. grpc_server_set_config_fetcher(server_, server_config_fetcher);
  810. }
  811. Server::~Server() {
  812. {
  813. grpc::internal::ReleasableMutexLock lock(&mu_);
  814. if (started_ && !shutdown_) {
  815. lock.Release();
  816. Shutdown();
  817. } else if (!started_) {
  818. // Shutdown the completion queues
  819. for (const auto& value : sync_req_mgrs_) {
  820. value->Shutdown();
  821. }
  822. if (callback_cq_ != nullptr) {
  823. if (grpc_iomgr_run_in_background()) {
  824. // gRPC-core provides the backing needed for the preferred CQ type
  825. callback_cq_->Shutdown();
  826. } else {
  827. CompletionQueue::ReleaseCallbackAlternativeCQ(callback_cq_);
  828. }
  829. callback_cq_ = nullptr;
  830. }
  831. }
  832. }
  833. // Destroy health check service before we destroy the C server so that
  834. // it does not call grpc_server_request_registered_call() after the C
  835. // server has been destroyed.
  836. health_check_service_.reset();
  837. grpc_server_destroy(server_);
  838. }
  839. void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) {
  840. GPR_ASSERT(!grpc::g_callbacks);
  841. GPR_ASSERT(callbacks);
  842. grpc::g_callbacks.reset(callbacks);
  843. }
  844. grpc_server* Server::c_server() { return server_; }
  845. std::shared_ptr<grpc::Channel> Server::InProcessChannel(
  846. const grpc::ChannelArguments& args) {
  847. grpc_channel_args channel_args = args.c_channel_args();
  848. return grpc::CreateChannelInternal(
  849. "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr),
  850. std::vector<std::unique_ptr<
  851. grpc::experimental::ClientInterceptorFactoryInterface>>());
  852. }
  853. std::shared_ptr<grpc::Channel>
  854. Server::experimental_type::InProcessChannelWithInterceptors(
  855. const grpc::ChannelArguments& args,
  856. std::vector<
  857. std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>
  858. interceptor_creators) {
  859. grpc_channel_args channel_args = args.c_channel_args();
  860. return grpc::CreateChannelInternal(
  861. "inproc",
  862. grpc_inproc_channel_create(server_->server_, &channel_args, nullptr),
  863. std::move(interceptor_creators));
  864. }
  865. static grpc_server_register_method_payload_handling PayloadHandlingForMethod(
  866. grpc::internal::RpcServiceMethod* method) {
  867. switch (method->method_type()) {
  868. case grpc::internal::RpcMethod::NORMAL_RPC:
  869. case grpc::internal::RpcMethod::SERVER_STREAMING:
  870. return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER;
  871. case grpc::internal::RpcMethod::CLIENT_STREAMING:
  872. case grpc::internal::RpcMethod::BIDI_STREAMING:
  873. return GRPC_SRM_PAYLOAD_NONE;
  874. }
  875. GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;);
  876. }
  877. bool Server::RegisterService(const std::string* addr, grpc::Service* service) {
  878. bool has_async_methods = service->has_async_methods();
  879. if (has_async_methods) {
  880. GPR_ASSERT(service->server_ == nullptr &&
  881. "Can only register an asynchronous service against one server.");
  882. service->server_ = this;
  883. }
  884. const char* method_name = nullptr;
  885. for (const auto& method : service->methods_) {
  886. if (method == nullptr) { // Handled by generic service if any.
  887. continue;
  888. }
  889. void* method_registration_tag = grpc_server_register_method(
  890. server_, method->name(), addr ? addr->c_str() : nullptr,
  891. PayloadHandlingForMethod(method.get()), 0);
  892. if (method_registration_tag == nullptr) {
  893. gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
  894. method->name());
  895. return false;
  896. }
  897. if (method->handler() == nullptr) { // Async method without handler
  898. method->set_server_tag(method_registration_tag);
  899. } else if (method->api_type() ==
  900. grpc::internal::RpcServiceMethod::ApiType::SYNC) {
  901. for (const auto& value : sync_req_mgrs_) {
  902. value->AddSyncMethod(method.get(), method_registration_tag);
  903. }
  904. } else {
  905. has_callback_methods_ = true;
  906. grpc::internal::RpcServiceMethod* method_value = method.get();
  907. grpc::CompletionQueue* cq = CallbackCQ();
  908. server_->core_server->SetRegisteredMethodAllocator(
  909. cq->cq(), method_registration_tag, [this, cq, method_value] {
  910. grpc_core::Server::RegisteredCallAllocation result;
  911. new CallbackRequest<grpc::CallbackServerContext>(this, method_value,
  912. cq, &result);
  913. return result;
  914. });
  915. }
  916. method_name = method->name();
  917. }
  918. // Parse service name.
  919. if (method_name != nullptr) {
  920. std::stringstream ss(method_name);
  921. std::string service_name;
  922. if (std::getline(ss, service_name, '/') &&
  923. std::getline(ss, service_name, '/')) {
  924. services_.push_back(service_name);
  925. }
  926. }
  927. return true;
  928. }
  929. void Server::RegisterAsyncGenericService(grpc::AsyncGenericService* service) {
  930. GPR_ASSERT(service->server_ == nullptr &&
  931. "Can only register an async generic service against one server.");
  932. service->server_ = this;
  933. has_async_generic_service_ = true;
  934. }
  935. void Server::RegisterCallbackGenericService(
  936. grpc::CallbackGenericService* service) {
  937. GPR_ASSERT(
  938. service->server_ == nullptr &&
  939. "Can only register a callback generic service against one server.");
  940. service->server_ = this;
  941. has_callback_generic_service_ = true;
  942. generic_handler_.reset(service->Handler());
  943. grpc::CompletionQueue* cq = CallbackCQ();
  944. server_->core_server->SetBatchMethodAllocator(cq->cq(), [this, cq] {
  945. grpc_core::Server::BatchCallAllocation result;
  946. new CallbackRequest<grpc::GenericCallbackServerContext>(this, cq, &result);
  947. return result;
  948. });
  949. }
  950. int Server::AddListeningPort(const std::string& addr,
  951. grpc::ServerCredentials* creds) {
  952. GPR_ASSERT(!started_);
  953. int port = creds->AddPortToServer(addr, server_);
  954. global_callbacks_->AddPort(this, addr, creds, port);
  955. return port;
  956. }
  957. void Server::Ref() {
  958. shutdown_refs_outstanding_.fetch_add(1, std::memory_order_relaxed);
  959. }
  960. void Server::UnrefWithPossibleNotify() {
  961. if (GPR_UNLIKELY(shutdown_refs_outstanding_.fetch_sub(
  962. 1, std::memory_order_acq_rel) == 1)) {
  963. // No refs outstanding means that shutdown has been initiated and no more
  964. // callback requests are outstanding.
  965. grpc::internal::MutexLock lock(&mu_);
  966. GPR_ASSERT(shutdown_);
  967. shutdown_done_ = true;
  968. shutdown_done_cv_.Signal();
  969. }
  970. }
  971. void Server::UnrefAndWaitLocked() {
  972. if (GPR_UNLIKELY(shutdown_refs_outstanding_.fetch_sub(
  973. 1, std::memory_order_acq_rel) == 1)) {
  974. shutdown_done_ = true;
  975. return; // no need to wait on CV since done condition already set
  976. }
  977. grpc::internal::WaitUntil(&shutdown_done_cv_, &mu_,
  978. [this] { return shutdown_done_; });
  979. }
  980. void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) {
  981. GPR_ASSERT(!started_);
  982. global_callbacks_->PreServerStart(this);
  983. started_ = true;
  984. // Only create default health check service when user did not provide an
  985. // explicit one.
  986. grpc::ServerCompletionQueue* health_check_cq = nullptr;
  987. grpc::DefaultHealthCheckService::HealthCheckServiceImpl*
  988. default_health_check_service_impl = nullptr;
  989. if (health_check_service_ == nullptr && !health_check_service_disabled_ &&
  990. grpc::DefaultHealthCheckServiceEnabled()) {
  991. auto* default_hc_service = new grpc::DefaultHealthCheckService;
  992. health_check_service_.reset(default_hc_service);
  993. // We create a non-polling CQ to avoid impacting application
  994. // performance. This ensures that we don't introduce thread hops
  995. // for application requests that wind up on this CQ, which is polled
  996. // in its own thread.
  997. health_check_cq = new grpc::ServerCompletionQueue(
  998. GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr);
  999. grpc_server_register_completion_queue(server_, health_check_cq->cq(),
  1000. nullptr);
  1001. default_health_check_service_impl =
  1002. default_hc_service->GetHealthCheckService(
  1003. std::unique_ptr<grpc::ServerCompletionQueue>(health_check_cq));
  1004. RegisterService(nullptr, default_health_check_service_impl);
  1005. }
  1006. for (auto& acceptor : acceptors_) {
  1007. acceptor->GetCredentials()->AddPortToServer(acceptor->name(), server_);
  1008. }
  1009. // If this server uses callback methods, then create a callback generic
  1010. // service to handle any unimplemented methods using the default reactor
  1011. // creator
  1012. if (has_callback_methods_ && !has_callback_generic_service_) {
  1013. unimplemented_service_ = absl::make_unique<grpc::CallbackGenericService>();
  1014. RegisterCallbackGenericService(unimplemented_service_.get());
  1015. }
  1016. #ifndef NDEBUG
  1017. for (size_t i = 0; i < num_cqs; i++) {
  1018. cq_list_.push_back(cqs[i]);
  1019. }
  1020. #endif
  1021. // If we have a generic service, all unmatched method names go there.
  1022. // Otherwise, we must provide at least one RPC request for an "unimplemented"
  1023. // RPC, which covers any RPC for a method name that isn't matched. If we
  1024. // have a sync service, let it be a sync unimplemented RPC, which must be
  1025. // registered before server start (to initialize an AllocatingRequestMatcher).
  1026. // If we have an AllocatingRequestMatcher, we can't also specify other
  1027. // unimplemented RPCs via explicit async requests, so we won't do so. If we
  1028. // only have async services, we can specify unimplemented RPCs on each async
  1029. // CQ so that some user polling thread will move them along as long as some
  1030. // progress is being made on any RPCs in the system.
  1031. bool unknown_rpc_needed =
  1032. !has_async_generic_service_ && !has_callback_generic_service_;
  1033. if (unknown_rpc_needed && !sync_req_mgrs_.empty()) {
  1034. sync_req_mgrs_[0]->AddUnknownSyncMethod();
  1035. unknown_rpc_needed = false;
  1036. }
  1037. grpc_server_start(server_);
  1038. if (unknown_rpc_needed) {
  1039. for (size_t i = 0; i < num_cqs; i++) {
  1040. if (cqs[i]->IsFrequentlyPolled()) {
  1041. new UnimplementedAsyncRequest(this, cqs[i]);
  1042. }
  1043. }
  1044. if (health_check_cq != nullptr) {
  1045. new UnimplementedAsyncRequest(this, health_check_cq);
  1046. }
  1047. unknown_rpc_needed = false;
  1048. }
  1049. // If this server has any support for synchronous methods (has any sync
  1050. // server CQs), make sure that we have a ResourceExhausted handler
  1051. // to deal with the case of thread exhaustion
  1052. if (sync_server_cqs_ != nullptr && !sync_server_cqs_->empty()) {
  1053. resource_exhausted_handler_ =
  1054. absl::make_unique<grpc::internal::ResourceExhaustedHandler>();
  1055. }
  1056. for (const auto& value : sync_req_mgrs_) {
  1057. value->Start();
  1058. }
  1059. if (default_health_check_service_impl != nullptr) {
  1060. default_health_check_service_impl->StartServingThread();
  1061. }
  1062. for (auto& acceptor : acceptors_) {
  1063. acceptor->Start();
  1064. }
  1065. }
  1066. void Server::ShutdownInternal(gpr_timespec deadline) {
  1067. grpc::internal::MutexLock lock(&mu_);
  1068. if (shutdown_) {
  1069. return;
  1070. }
  1071. shutdown_ = true;
  1072. for (auto& acceptor : acceptors_) {
  1073. acceptor->Shutdown();
  1074. }
  1075. /// The completion queue to use for server shutdown completion notification
  1076. grpc::CompletionQueue shutdown_cq;
  1077. grpc::ShutdownTag shutdown_tag; // Phony shutdown tag
  1078. grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag);
  1079. shutdown_cq.Shutdown();
  1080. void* tag;
  1081. bool ok;
  1082. grpc::CompletionQueue::NextStatus status =
  1083. shutdown_cq.AsyncNext(&tag, &ok, deadline);
  1084. // If this timed out, it means we are done with the grace period for a clean
  1085. // shutdown. We should force a shutdown now by cancelling all inflight calls
  1086. if (status == grpc::CompletionQueue::NextStatus::TIMEOUT) {
  1087. grpc_server_cancel_all_calls(server_);
  1088. }
  1089. // Else in case of SHUTDOWN or GOT_EVENT, it means that the server has
  1090. // successfully shutdown
  1091. // Shutdown all ThreadManagers. This will try to gracefully stop all the
  1092. // threads in the ThreadManagers (once they process any inflight requests)
  1093. for (const auto& value : sync_req_mgrs_) {
  1094. value->Shutdown(); // ThreadManager's Shutdown()
  1095. }
  1096. // Wait for threads in all ThreadManagers to terminate
  1097. for (const auto& value : sync_req_mgrs_) {
  1098. value->Wait();
  1099. }
  1100. // Drop the shutdown ref and wait for all other refs to drop as well.
  1101. UnrefAndWaitLocked();
  1102. // Shutdown the callback CQ. The CQ is owned by its own shutdown tag, so it
  1103. // will delete itself at true shutdown.
  1104. if (callback_cq_ != nullptr) {
  1105. if (grpc_iomgr_run_in_background()) {
  1106. // gRPC-core provides the backing needed for the preferred CQ type
  1107. callback_cq_->Shutdown();
  1108. } else {
  1109. CompletionQueue::ReleaseCallbackAlternativeCQ(callback_cq_);
  1110. }
  1111. callback_cq_ = nullptr;
  1112. }
  1113. // Drain the shutdown queue (if the previous call to AsyncNext() timed out
  1114. // and we didn't remove the tag from the queue yet)
  1115. while (shutdown_cq.Next(&tag, &ok)) {
  1116. // Nothing to be done here. Just ignore ok and tag values
  1117. }
  1118. shutdown_notified_ = true;
  1119. shutdown_cv_.SignalAll();
  1120. #ifndef NDEBUG
  1121. // Unregister this server with the CQs passed into it by the user so that
  1122. // those can be checked for properly-ordered shutdown.
  1123. for (auto* cq : cq_list_) {
  1124. cq->UnregisterServer(this);
  1125. }
  1126. cq_list_.clear();
  1127. #endif
  1128. }
  1129. void Server::Wait() {
  1130. grpc::internal::MutexLock lock(&mu_);
  1131. while (started_ && !shutdown_notified_) {
  1132. shutdown_cv_.Wait(&mu_);
  1133. }
  1134. }
  1135. void Server::PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops,
  1136. grpc::internal::Call* call) {
  1137. ops->FillOps(call);
  1138. }
  1139. bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag,
  1140. bool* status) {
  1141. if (GenericAsyncRequest::FinalizeResult(tag, status)) {
  1142. // We either had no interceptors run or we are done intercepting
  1143. if (*status) {
  1144. // Create a new request/response pair using the server and CQ values
  1145. // stored in this object's base class.
  1146. new UnimplementedAsyncRequest(server_, notification_cq_);
  1147. new UnimplementedAsyncResponse(this);
  1148. } else {
  1149. delete this;
  1150. }
  1151. } else {
  1152. // The tag was swallowed due to interception. We will see it again.
  1153. }
  1154. return false;
  1155. }
  1156. Server::UnimplementedAsyncResponse::UnimplementedAsyncResponse(
  1157. UnimplementedAsyncRequest* request)
  1158. : request_(request) {
  1159. grpc::Status status(grpc::StatusCode::UNIMPLEMENTED, "");
  1160. grpc::internal::UnknownMethodHandler::FillOps(request_->context(), this);
  1161. request_->stream()->call_.PerformOps(this);
  1162. }
  1163. grpc::ServerInitializer* Server::initializer() {
  1164. return server_initializer_.get();
  1165. }
  1166. grpc::CompletionQueue* Server::CallbackCQ() {
  1167. // TODO(vjpai): Consider using a single global CQ for the default CQ
  1168. // if there is no explicit per-server CQ registered
  1169. grpc::internal::MutexLock l(&mu_);
  1170. if (callback_cq_ != nullptr) {
  1171. return callback_cq_;
  1172. }
  1173. if (grpc_iomgr_run_in_background()) {
  1174. // gRPC-core provides the backing needed for the preferred CQ type
  1175. auto* shutdown_callback = new grpc::ShutdownCallback;
  1176. callback_cq_ = new grpc::CompletionQueue(grpc_completion_queue_attributes{
  1177. GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING,
  1178. shutdown_callback});
  1179. // Transfer ownership of the new cq to its own shutdown callback
  1180. shutdown_callback->TakeCQ(callback_cq_);
  1181. } else {
  1182. // Otherwise we need to use the alternative CQ variant
  1183. callback_cq_ = CompletionQueue::CallbackAlternativeCQ();
  1184. }
  1185. return callback_cq_;
  1186. }
  1187. } // namespace grpc