server_cc.cc 47 KB

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