server_cc.cc 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369
  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. explicit 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. ctx_(server_->context_allocator() != nullptr
  500. ? server_->context_allocator()->NewCallbackServerContext()
  501. : nullptr) {
  502. CommonSetup(server, data);
  503. data->deadline = &deadline_;
  504. data->optional_payload = has_request_payload_ ? &request_payload_ : nullptr;
  505. }
  506. // For generic services, method is nullptr since these services don't have
  507. // pre-defined methods.
  508. CallbackRequest(Server* server, grpc::CompletionQueue* cq,
  509. grpc_core::Server::BatchCallAllocation* data)
  510. : server_(server),
  511. method_(nullptr),
  512. has_request_payload_(false),
  513. call_details_(new grpc_call_details),
  514. cq_(cq),
  515. tag_(this),
  516. ctx_(server_->context_allocator() != nullptr
  517. ? server_->context_allocator()
  518. ->NewGenericCallbackServerContext()
  519. : nullptr) {
  520. CommonSetup(server, data);
  521. grpc_call_details_init(call_details_);
  522. data->details = call_details_;
  523. }
  524. ~CallbackRequest() override {
  525. delete call_details_;
  526. grpc_metadata_array_destroy(&request_metadata_);
  527. if (has_request_payload_ && request_payload_) {
  528. grpc_byte_buffer_destroy(request_payload_);
  529. }
  530. if (server_->context_allocator() == nullptr || ctx_alloc_by_default_) {
  531. delete ctx_;
  532. }
  533. server_->UnrefWithPossibleNotify();
  534. }
  535. // Needs specialization to account for different processing of metadata
  536. // in generic API
  537. bool FinalizeResult(void** tag, bool* status) override;
  538. private:
  539. // method_name needs to be specialized between named method and generic
  540. const char* method_name() const;
  541. class CallbackCallTag : public grpc_experimental_completion_queue_functor {
  542. public:
  543. explicit CallbackCallTag(Server::CallbackRequest<ServerContextType>* req)
  544. : req_(req) {
  545. functor_run = &CallbackCallTag::StaticRun;
  546. // Set inlineable to true since this callback is internally-controlled
  547. // without taking any locks, and thus does not need to be run from the
  548. // executor (which triggers a thread hop). This should only be used by
  549. // internal callbacks like this and not by user application code. The work
  550. // here is actually non-trivial, but there is no chance of having user
  551. // locks conflict with each other so it's ok to run inlined.
  552. inlineable = true;
  553. }
  554. // force_run can not be performed on a tag if operations using this tag
  555. // have been sent to PerformOpsOnCall. It is intended for error conditions
  556. // that are detected before the operations are internally processed.
  557. void force_run(bool ok) { Run(ok); }
  558. private:
  559. Server::CallbackRequest<ServerContextType>* req_;
  560. grpc::internal::Call* call_;
  561. static void StaticRun(grpc_experimental_completion_queue_functor* cb,
  562. int ok) {
  563. static_cast<CallbackCallTag*>(cb)->Run(static_cast<bool>(ok));
  564. }
  565. void Run(bool ok) {
  566. void* ignored = req_;
  567. bool new_ok = ok;
  568. GPR_ASSERT(!req_->FinalizeResult(&ignored, &new_ok));
  569. GPR_ASSERT(ignored == req_);
  570. if (!ok) {
  571. // The call has been shutdown.
  572. // Delete its contents to free up the request.
  573. delete req_;
  574. return;
  575. }
  576. // Bind the call, deadline, and metadata from what we got
  577. req_->ctx_->set_call(req_->call_);
  578. req_->ctx_->cq_ = req_->cq_;
  579. req_->ctx_->BindDeadlineAndMetadata(req_->deadline_,
  580. &req_->request_metadata_);
  581. req_->request_metadata_.count = 0;
  582. // Create a C++ Call to control the underlying core call
  583. call_ =
  584. new (grpc_call_arena_alloc(req_->call_, sizeof(grpc::internal::Call)))
  585. grpc::internal::Call(
  586. req_->call_, req_->server_, req_->cq_,
  587. req_->server_->max_receive_message_size(),
  588. req_->ctx_->set_server_rpc_info(
  589. req_->method_name(),
  590. (req_->method_ != nullptr)
  591. ? req_->method_->method_type()
  592. : grpc::internal::RpcMethod::BIDI_STREAMING,
  593. req_->server_->interceptor_creators_));
  594. req_->interceptor_methods_.SetCall(call_);
  595. req_->interceptor_methods_.SetReverse();
  596. // Set interception point for RECV INITIAL METADATA
  597. req_->interceptor_methods_.AddInterceptionHookPoint(
  598. grpc::experimental::InterceptionHookPoints::
  599. POST_RECV_INITIAL_METADATA);
  600. req_->interceptor_methods_.SetRecvInitialMetadata(
  601. &req_->ctx_->client_metadata_);
  602. if (req_->has_request_payload_) {
  603. // Set interception point for RECV MESSAGE
  604. req_->request_ = req_->method_->handler()->Deserialize(
  605. req_->call_, req_->request_payload_, &req_->request_status_,
  606. &req_->handler_data_);
  607. req_->request_payload_ = nullptr;
  608. req_->interceptor_methods_.AddInterceptionHookPoint(
  609. grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE);
  610. req_->interceptor_methods_.SetRecvMessage(req_->request_, nullptr);
  611. }
  612. if (req_->interceptor_methods_.RunInterceptors(
  613. [this] { ContinueRunAfterInterception(); })) {
  614. ContinueRunAfterInterception();
  615. } else {
  616. // There were interceptors to be run, so ContinueRunAfterInterception
  617. // will be run when interceptors are done.
  618. }
  619. }
  620. void ContinueRunAfterInterception() {
  621. auto* handler = (req_->method_ != nullptr)
  622. ? req_->method_->handler()
  623. : req_->server_->generic_handler_.get();
  624. handler->RunHandler(grpc::internal::MethodHandler::HandlerParameter(
  625. call_, req_->ctx_, req_->request_, req_->request_status_,
  626. req_->handler_data_, [this] { delete req_; }));
  627. }
  628. };
  629. template <class CallAllocation>
  630. void CommonSetup(Server* server, CallAllocation* data) {
  631. server->Ref();
  632. grpc_metadata_array_init(&request_metadata_);
  633. data->tag = &tag_;
  634. data->call = &call_;
  635. data->initial_metadata = &request_metadata_;
  636. if (ctx_ == nullptr) {
  637. // TODO(ddyihai): allocate the context with grpc_call_arena_alloc.
  638. ctx_ = new ServerContextType();
  639. ctx_alloc_by_default_ = true;
  640. }
  641. ctx_->set_context_allocator(server->context_allocator());
  642. }
  643. Server* const server_;
  644. grpc::internal::RpcServiceMethod* const method_;
  645. const bool has_request_payload_;
  646. grpc_byte_buffer* request_payload_ = nullptr;
  647. void* request_ = nullptr;
  648. void* handler_data_ = nullptr;
  649. grpc::Status request_status_;
  650. grpc_call_details* const call_details_ = nullptr;
  651. grpc_call* call_;
  652. gpr_timespec deadline_;
  653. grpc_metadata_array request_metadata_;
  654. grpc::CompletionQueue* const cq_;
  655. bool ctx_alloc_by_default_ = false;
  656. CallbackCallTag tag_;
  657. ServerContextType* ctx_ = nullptr;
  658. grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_;
  659. };
  660. template <>
  661. bool Server::CallbackRequest<grpc::CallbackServerContext>::FinalizeResult(
  662. void** /*tag*/, bool* /*status*/) {
  663. return false;
  664. }
  665. template <>
  666. bool Server::CallbackRequest<
  667. grpc::GenericCallbackServerContext>::FinalizeResult(void** /*tag*/,
  668. bool* status) {
  669. if (*status) {
  670. deadline_ = call_details_->deadline;
  671. // TODO(yangg) remove the copy here
  672. ctx_->method_ = grpc::StringFromCopiedSlice(call_details_->method);
  673. ctx_->host_ = grpc::StringFromCopiedSlice(call_details_->host);
  674. }
  675. grpc_slice_unref(call_details_->method);
  676. grpc_slice_unref(call_details_->host);
  677. return false;
  678. }
  679. template <>
  680. const char* Server::CallbackRequest<grpc::CallbackServerContext>::method_name()
  681. const {
  682. return method_->name();
  683. }
  684. template <>
  685. const char* Server::CallbackRequest<
  686. grpc::GenericCallbackServerContext>::method_name() const {
  687. return ctx_->method().c_str();
  688. }
  689. // Implementation of ThreadManager. Each instance of SyncRequestThreadManager
  690. // manages a pool of threads that poll for incoming Sync RPCs and call the
  691. // appropriate RPC handlers
  692. class Server::SyncRequestThreadManager : public grpc::ThreadManager {
  693. public:
  694. SyncRequestThreadManager(Server* server, grpc::CompletionQueue* server_cq,
  695. std::shared_ptr<GlobalCallbacks> global_callbacks,
  696. grpc_resource_quota* rq, int min_pollers,
  697. int max_pollers, int cq_timeout_msec)
  698. : ThreadManager("SyncServer", rq, min_pollers, max_pollers),
  699. server_(server),
  700. server_cq_(server_cq),
  701. cq_timeout_msec_(cq_timeout_msec),
  702. global_callbacks_(std::move(global_callbacks)) {}
  703. WorkStatus PollForWork(void** tag, bool* ok) override {
  704. *tag = nullptr;
  705. // TODO(ctiller): workaround for GPR_TIMESPAN based deadlines not working
  706. // right now
  707. gpr_timespec deadline =
  708. gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
  709. gpr_time_from_millis(cq_timeout_msec_, GPR_TIMESPAN));
  710. switch (server_cq_->AsyncNext(tag, ok, deadline)) {
  711. case grpc::CompletionQueue::TIMEOUT:
  712. return TIMEOUT;
  713. case grpc::CompletionQueue::SHUTDOWN:
  714. return SHUTDOWN;
  715. case grpc::CompletionQueue::GOT_EVENT:
  716. return WORK_FOUND;
  717. }
  718. GPR_UNREACHABLE_CODE(return TIMEOUT);
  719. }
  720. void DoWork(void* tag, bool ok, bool resources) override {
  721. SyncRequest* sync_req = static_cast<SyncRequest*>(tag);
  722. if (!sync_req) {
  723. // No tag. Nothing to work on. This is an unlikley scenario and possibly a
  724. // bug in RPC Manager implementation.
  725. gpr_log(GPR_ERROR, "Sync server. DoWork() was called with NULL tag");
  726. return;
  727. }
  728. if (ok) {
  729. // Calldata takes ownership of the completion queue and interceptors
  730. // inside sync_req
  731. auto* cd = new SyncRequest::CallData(server_, sync_req);
  732. // Prepare for the next request
  733. if (!IsShutdown()) {
  734. sync_req->SetupRequest(); // Create new completion queue for sync_req
  735. sync_req->Request(server_->c_server(), server_cq_->cq());
  736. }
  737. GPR_TIMER_SCOPE("cd.Run()", 0);
  738. cd->Run(global_callbacks_, resources);
  739. }
  740. // TODO (sreek) If ok is false here (which it isn't in case of
  741. // grpc_request_registered_call), we should still re-queue the request
  742. // object
  743. }
  744. void AddSyncMethod(grpc::internal::RpcServiceMethod* method, void* tag) {
  745. sync_requests_.emplace_back(new SyncRequest(method, tag));
  746. }
  747. void AddUnknownSyncMethod() {
  748. if (!sync_requests_.empty()) {
  749. unknown_method_ = absl::make_unique<grpc::internal::RpcServiceMethod>(
  750. "unknown", grpc::internal::RpcMethod::BIDI_STREAMING,
  751. new grpc::internal::UnknownMethodHandler);
  752. sync_requests_.emplace_back(
  753. new SyncRequest(unknown_method_.get(), nullptr));
  754. }
  755. }
  756. void Shutdown() override {
  757. ThreadManager::Shutdown();
  758. server_cq_->Shutdown();
  759. }
  760. void Wait() override {
  761. ThreadManager::Wait();
  762. // Drain any pending items from the queue
  763. void* tag;
  764. bool ok;
  765. while (server_cq_->Next(&tag, &ok)) {
  766. if (ok) {
  767. // If a request was pulled off the queue, it means that the thread
  768. // handling the request added it to the completion queue after shutdown
  769. // was called - because the thread had already started and checked the
  770. // shutdown flag before shutdown was called. In this case, we simply
  771. // clean it up here, *after* calling wait on all the worker threads, at
  772. // which point we are certain no in-flight requests will add more to the
  773. // queue. This fixes an intermittent memory leak on shutdown.
  774. SyncRequest* sync_req = static_cast<SyncRequest*>(tag);
  775. sync_req->PostShutdownCleanup();
  776. }
  777. }
  778. }
  779. void Start() {
  780. if (!sync_requests_.empty()) {
  781. for (const auto& value : sync_requests_) {
  782. value->SetupRequest();
  783. value->Request(server_->c_server(), server_cq_->cq());
  784. }
  785. Initialize(); // ThreadManager's Initialize()
  786. }
  787. }
  788. private:
  789. Server* server_;
  790. grpc::CompletionQueue* server_cq_;
  791. int cq_timeout_msec_;
  792. std::vector<std::unique_ptr<SyncRequest>> sync_requests_;
  793. std::unique_ptr<grpc::internal::RpcServiceMethod> unknown_method_;
  794. std::shared_ptr<Server::GlobalCallbacks> global_callbacks_;
  795. };
  796. static grpc::internal::GrpcLibraryInitializer g_gli_initializer;
  797. Server::Server(
  798. grpc::ChannelArguments* args,
  799. std::shared_ptr<std::vector<std::unique_ptr<grpc::ServerCompletionQueue>>>
  800. sync_server_cqs,
  801. int min_pollers, int max_pollers, int sync_cq_timeout_msec,
  802. std::vector<std::shared_ptr<grpc::internal::ExternalConnectionAcceptorImpl>>
  803. acceptors,
  804. grpc_server_config_fetcher* server_config_fetcher,
  805. grpc_resource_quota* server_rq,
  806. std::vector<
  807. std::unique_ptr<grpc::experimental::ServerInterceptorFactoryInterface>>
  808. interceptor_creators)
  809. : acceptors_(std::move(acceptors)),
  810. interceptor_creators_(std::move(interceptor_creators)),
  811. max_receive_message_size_(INT_MIN),
  812. sync_server_cqs_(std::move(sync_server_cqs)),
  813. started_(false),
  814. shutdown_(false),
  815. shutdown_notified_(false),
  816. server_(nullptr),
  817. server_initializer_(new ServerInitializer(this)),
  818. health_check_service_disabled_(false) {
  819. g_gli_initializer.summon();
  820. gpr_once_init(&grpc::g_once_init_callbacks, grpc::InitGlobalCallbacks);
  821. global_callbacks_ = grpc::g_callbacks;
  822. global_callbacks_->UpdateArguments(args);
  823. if (sync_server_cqs_ != nullptr) {
  824. bool default_rq_created = false;
  825. if (server_rq == nullptr) {
  826. server_rq = grpc_resource_quota_create("SyncServer-default-rq");
  827. grpc_resource_quota_set_max_threads(server_rq,
  828. DEFAULT_MAX_SYNC_SERVER_THREADS);
  829. default_rq_created = true;
  830. }
  831. for (const auto& it : *sync_server_cqs_) {
  832. sync_req_mgrs_.emplace_back(new SyncRequestThreadManager(
  833. this, it.get(), global_callbacks_, server_rq, min_pollers,
  834. max_pollers, sync_cq_timeout_msec));
  835. }
  836. if (default_rq_created) {
  837. grpc_resource_quota_unref(server_rq);
  838. }
  839. }
  840. for (auto& acceptor : acceptors_) {
  841. acceptor->SetToChannelArgs(args);
  842. }
  843. grpc_channel_args channel_args;
  844. args->SetChannelArgs(&channel_args);
  845. for (size_t i = 0; i < channel_args.num_args; i++) {
  846. if (0 == strcmp(channel_args.args[i].key,
  847. grpc::kHealthCheckServiceInterfaceArg)) {
  848. if (channel_args.args[i].value.pointer.p == nullptr) {
  849. health_check_service_disabled_ = true;
  850. } else {
  851. health_check_service_.reset(
  852. static_cast<grpc::HealthCheckServiceInterface*>(
  853. channel_args.args[i].value.pointer.p));
  854. }
  855. }
  856. if (0 ==
  857. strcmp(channel_args.args[i].key, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH)) {
  858. max_receive_message_size_ = channel_args.args[i].value.integer;
  859. }
  860. }
  861. server_ = grpc_server_create(&channel_args, nullptr);
  862. grpc_server_set_config_fetcher(server_, server_config_fetcher);
  863. }
  864. Server::~Server() {
  865. {
  866. grpc::internal::ReleasableMutexLock lock(&mu_);
  867. if (started_ && !shutdown_) {
  868. lock.Unlock();
  869. Shutdown();
  870. } else if (!started_) {
  871. // Shutdown the completion queues
  872. for (const auto& value : sync_req_mgrs_) {
  873. value->Shutdown();
  874. }
  875. if (callback_cq_ != nullptr) {
  876. callback_cq_->Shutdown();
  877. callback_cq_ = nullptr;
  878. }
  879. }
  880. }
  881. // Destroy health check service before we destroy the C server so that
  882. // it does not call grpc_server_request_registered_call() after the C
  883. // server has been destroyed.
  884. health_check_service_.reset();
  885. grpc_server_destroy(server_);
  886. }
  887. void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) {
  888. GPR_ASSERT(!grpc::g_callbacks);
  889. GPR_ASSERT(callbacks);
  890. grpc::g_callbacks.reset(callbacks);
  891. }
  892. grpc_server* Server::c_server() { return server_; }
  893. std::shared_ptr<grpc::Channel> Server::InProcessChannel(
  894. const grpc::ChannelArguments& args) {
  895. grpc_channel_args channel_args = args.c_channel_args();
  896. return grpc::CreateChannelInternal(
  897. "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr),
  898. std::vector<std::unique_ptr<
  899. grpc::experimental::ClientInterceptorFactoryInterface>>());
  900. }
  901. std::shared_ptr<grpc::Channel>
  902. Server::experimental_type::InProcessChannelWithInterceptors(
  903. const grpc::ChannelArguments& args,
  904. std::vector<
  905. std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>
  906. interceptor_creators) {
  907. grpc_channel_args channel_args = args.c_channel_args();
  908. return grpc::CreateChannelInternal(
  909. "inproc",
  910. grpc_inproc_channel_create(server_->server_, &channel_args, nullptr),
  911. std::move(interceptor_creators));
  912. }
  913. static grpc_server_register_method_payload_handling PayloadHandlingForMethod(
  914. grpc::internal::RpcServiceMethod* method) {
  915. switch (method->method_type()) {
  916. case grpc::internal::RpcMethod::NORMAL_RPC:
  917. case grpc::internal::RpcMethod::SERVER_STREAMING:
  918. return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER;
  919. case grpc::internal::RpcMethod::CLIENT_STREAMING:
  920. case grpc::internal::RpcMethod::BIDI_STREAMING:
  921. return GRPC_SRM_PAYLOAD_NONE;
  922. }
  923. GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;);
  924. }
  925. bool Server::RegisterService(const std::string* addr, grpc::Service* service) {
  926. bool has_async_methods = service->has_async_methods();
  927. if (has_async_methods) {
  928. GPR_ASSERT(service->server_ == nullptr &&
  929. "Can only register an asynchronous service against one server.");
  930. service->server_ = this;
  931. }
  932. const char* method_name = nullptr;
  933. for (const auto& method : service->methods_) {
  934. if (method == nullptr) { // Handled by generic service if any.
  935. continue;
  936. }
  937. void* method_registration_tag = grpc_server_register_method(
  938. server_, method->name(), addr ? addr->c_str() : nullptr,
  939. PayloadHandlingForMethod(method.get()), 0);
  940. if (method_registration_tag == nullptr) {
  941. gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
  942. method->name());
  943. return false;
  944. }
  945. if (method->handler() == nullptr) { // Async method without handler
  946. method->set_server_tag(method_registration_tag);
  947. } else if (method->api_type() ==
  948. grpc::internal::RpcServiceMethod::ApiType::SYNC) {
  949. for (const auto& value : sync_req_mgrs_) {
  950. value->AddSyncMethod(method.get(), method_registration_tag);
  951. }
  952. } else {
  953. has_callback_methods_ = true;
  954. grpc::internal::RpcServiceMethod* method_value = method.get();
  955. grpc::CompletionQueue* cq = CallbackCQ();
  956. server_->core_server->SetRegisteredMethodAllocator(
  957. cq->cq(), method_registration_tag, [this, cq, method_value] {
  958. grpc_core::Server::RegisteredCallAllocation result;
  959. new CallbackRequest<grpc::CallbackServerContext>(this, method_value,
  960. cq, &result);
  961. return result;
  962. });
  963. }
  964. method_name = method->name();
  965. }
  966. // Parse service name.
  967. if (method_name != nullptr) {
  968. std::stringstream ss(method_name);
  969. std::string service_name;
  970. if (std::getline(ss, service_name, '/') &&
  971. std::getline(ss, service_name, '/')) {
  972. services_.push_back(service_name);
  973. }
  974. }
  975. return true;
  976. }
  977. void Server::RegisterAsyncGenericService(grpc::AsyncGenericService* service) {
  978. GPR_ASSERT(service->server_ == nullptr &&
  979. "Can only register an async generic service against one server.");
  980. service->server_ = this;
  981. has_async_generic_service_ = true;
  982. }
  983. void Server::RegisterCallbackGenericService(
  984. grpc::CallbackGenericService* service) {
  985. GPR_ASSERT(
  986. service->server_ == nullptr &&
  987. "Can only register a callback generic service against one server.");
  988. service->server_ = this;
  989. has_callback_generic_service_ = true;
  990. generic_handler_.reset(service->Handler());
  991. grpc::CompletionQueue* cq = CallbackCQ();
  992. server_->core_server->SetBatchMethodAllocator(cq->cq(), [this, cq] {
  993. grpc_core::Server::BatchCallAllocation result;
  994. new CallbackRequest<grpc::GenericCallbackServerContext>(this, cq, &result);
  995. return result;
  996. });
  997. }
  998. int Server::AddListeningPort(const std::string& addr,
  999. grpc::ServerCredentials* creds) {
  1000. GPR_ASSERT(!started_);
  1001. int port = creds->AddPortToServer(addr, server_);
  1002. global_callbacks_->AddPort(this, addr, creds, port);
  1003. return port;
  1004. }
  1005. void Server::Ref() {
  1006. shutdown_refs_outstanding_.fetch_add(1, std::memory_order_relaxed);
  1007. }
  1008. void Server::UnrefWithPossibleNotify() {
  1009. if (GPR_UNLIKELY(shutdown_refs_outstanding_.fetch_sub(
  1010. 1, std::memory_order_acq_rel) == 1)) {
  1011. // No refs outstanding means that shutdown has been initiated and no more
  1012. // callback requests are outstanding.
  1013. grpc::internal::MutexLock lock(&mu_);
  1014. GPR_ASSERT(shutdown_);
  1015. shutdown_done_ = true;
  1016. shutdown_done_cv_.Signal();
  1017. }
  1018. }
  1019. void Server::UnrefAndWaitLocked() {
  1020. if (GPR_UNLIKELY(shutdown_refs_outstanding_.fetch_sub(
  1021. 1, std::memory_order_acq_rel) == 1)) {
  1022. shutdown_done_ = true;
  1023. return; // no need to wait on CV since done condition already set
  1024. }
  1025. shutdown_done_cv_.WaitUntil(&mu_, [this] { return shutdown_done_; });
  1026. }
  1027. void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) {
  1028. GPR_ASSERT(!started_);
  1029. global_callbacks_->PreServerStart(this);
  1030. started_ = true;
  1031. // Only create default health check service when user did not provide an
  1032. // explicit one.
  1033. grpc::ServerCompletionQueue* health_check_cq = nullptr;
  1034. grpc::DefaultHealthCheckService::HealthCheckServiceImpl*
  1035. default_health_check_service_impl = nullptr;
  1036. if (health_check_service_ == nullptr && !health_check_service_disabled_ &&
  1037. grpc::DefaultHealthCheckServiceEnabled()) {
  1038. auto* default_hc_service = new grpc::DefaultHealthCheckService;
  1039. health_check_service_.reset(default_hc_service);
  1040. // We create a non-polling CQ to avoid impacting application
  1041. // performance. This ensures that we don't introduce thread hops
  1042. // for application requests that wind up on this CQ, which is polled
  1043. // in its own thread.
  1044. health_check_cq = new grpc::ServerCompletionQueue(
  1045. GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr);
  1046. grpc_server_register_completion_queue(server_, health_check_cq->cq(),
  1047. nullptr);
  1048. default_health_check_service_impl =
  1049. default_hc_service->GetHealthCheckService(
  1050. std::unique_ptr<grpc::ServerCompletionQueue>(health_check_cq));
  1051. RegisterService(nullptr, default_health_check_service_impl);
  1052. }
  1053. for (auto& acceptor : acceptors_) {
  1054. acceptor->GetCredentials()->AddPortToServer(acceptor->name(), server_);
  1055. }
  1056. // If this server uses callback methods, then create a callback generic
  1057. // service to handle any unimplemented methods using the default reactor
  1058. // creator
  1059. if (has_callback_methods_ && !has_callback_generic_service_) {
  1060. unimplemented_service_ = absl::make_unique<grpc::CallbackGenericService>();
  1061. RegisterCallbackGenericService(unimplemented_service_.get());
  1062. }
  1063. #ifndef NDEBUG
  1064. for (size_t i = 0; i < num_cqs; i++) {
  1065. cq_list_.push_back(cqs[i]);
  1066. }
  1067. #endif
  1068. grpc_server_start(server_);
  1069. if (!has_async_generic_service_ && !has_callback_generic_service_) {
  1070. for (const auto& value : sync_req_mgrs_) {
  1071. value->AddUnknownSyncMethod();
  1072. }
  1073. for (size_t i = 0; i < num_cqs; i++) {
  1074. if (cqs[i]->IsFrequentlyPolled()) {
  1075. new UnimplementedAsyncRequest(this, cqs[i]);
  1076. }
  1077. }
  1078. if (health_check_cq != nullptr) {
  1079. new UnimplementedAsyncRequest(this, health_check_cq);
  1080. }
  1081. }
  1082. // If this server has any support for synchronous methods (has any sync
  1083. // server CQs), make sure that we have a ResourceExhausted handler
  1084. // to deal with the case of thread exhaustion
  1085. if (sync_server_cqs_ != nullptr && !sync_server_cqs_->empty()) {
  1086. resource_exhausted_handler_ =
  1087. absl::make_unique<grpc::internal::ResourceExhaustedHandler>();
  1088. }
  1089. for (const auto& value : sync_req_mgrs_) {
  1090. value->Start();
  1091. }
  1092. if (default_health_check_service_impl != nullptr) {
  1093. default_health_check_service_impl->StartServingThread();
  1094. }
  1095. for (auto& acceptor : acceptors_) {
  1096. acceptor->Start();
  1097. }
  1098. }
  1099. void Server::ShutdownInternal(gpr_timespec deadline) {
  1100. grpc::internal::MutexLock lock(&mu_);
  1101. if (shutdown_) {
  1102. return;
  1103. }
  1104. shutdown_ = true;
  1105. for (auto& acceptor : acceptors_) {
  1106. acceptor->Shutdown();
  1107. }
  1108. /// The completion queue to use for server shutdown completion notification
  1109. grpc::CompletionQueue shutdown_cq;
  1110. grpc::ShutdownTag shutdown_tag; // Dummy shutdown tag
  1111. grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag);
  1112. shutdown_cq.Shutdown();
  1113. void* tag;
  1114. bool ok;
  1115. grpc::CompletionQueue::NextStatus status =
  1116. shutdown_cq.AsyncNext(&tag, &ok, deadline);
  1117. // If this timed out, it means we are done with the grace period for a clean
  1118. // shutdown. We should force a shutdown now by cancelling all inflight calls
  1119. if (status == grpc::CompletionQueue::NextStatus::TIMEOUT) {
  1120. grpc_server_cancel_all_calls(server_);
  1121. }
  1122. // Else in case of SHUTDOWN or GOT_EVENT, it means that the server has
  1123. // successfully shutdown
  1124. // Shutdown all ThreadManagers. This will try to gracefully stop all the
  1125. // threads in the ThreadManagers (once they process any inflight requests)
  1126. for (const auto& value : sync_req_mgrs_) {
  1127. value->Shutdown(); // ThreadManager's Shutdown()
  1128. }
  1129. // In case any calls were started in the sync request managers while they were
  1130. // still in the process of shutting down, do another round of cancellations.
  1131. // None of these should be matched since the accept_streams have already been
  1132. // shutdown, but their existence could still tie up a CQ waiting for a match.
  1133. grpc_server_cancel_all_calls(server_);
  1134. // Wait for threads in all ThreadManagers to terminate
  1135. for (const auto& value : sync_req_mgrs_) {
  1136. value->Wait();
  1137. }
  1138. // Drop the shutdown ref and wait for all other refs to drop as well.
  1139. UnrefAndWaitLocked();
  1140. // Shutdown the callback CQ. The CQ is owned by its own shutdown tag, so it
  1141. // will delete itself at true shutdown.
  1142. if (callback_cq_ != nullptr) {
  1143. callback_cq_->Shutdown();
  1144. callback_cq_ = nullptr;
  1145. }
  1146. // Drain the shutdown queue (if the previous call to AsyncNext() timed out
  1147. // and we didn't remove the tag from the queue yet)
  1148. while (shutdown_cq.Next(&tag, &ok)) {
  1149. // Nothing to be done here. Just ignore ok and tag values
  1150. }
  1151. shutdown_notified_ = true;
  1152. shutdown_cv_.Broadcast();
  1153. #ifndef NDEBUG
  1154. // Unregister this server with the CQs passed into it by the user so that
  1155. // those can be checked for properly-ordered shutdown.
  1156. for (auto* cq : cq_list_) {
  1157. cq->UnregisterServer(this);
  1158. }
  1159. cq_list_.clear();
  1160. #endif
  1161. }
  1162. void Server::Wait() {
  1163. grpc::internal::MutexLock lock(&mu_);
  1164. while (started_ && !shutdown_notified_) {
  1165. shutdown_cv_.Wait(&mu_);
  1166. }
  1167. }
  1168. void Server::PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops,
  1169. grpc::internal::Call* call) {
  1170. ops->FillOps(call);
  1171. }
  1172. bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag,
  1173. bool* status) {
  1174. if (GenericAsyncRequest::FinalizeResult(tag, status)) {
  1175. // We either had no interceptors run or we are done intercepting
  1176. if (*status) {
  1177. // Create a new request/response pair using the server and CQ values
  1178. // stored in this object's base class.
  1179. new UnimplementedAsyncRequest(server_, notification_cq_);
  1180. new UnimplementedAsyncResponse(this);
  1181. } else {
  1182. delete this;
  1183. }
  1184. } else {
  1185. // The tag was swallowed due to interception. We will see it again.
  1186. }
  1187. return false;
  1188. }
  1189. Server::UnimplementedAsyncResponse::UnimplementedAsyncResponse(
  1190. UnimplementedAsyncRequest* request)
  1191. : request_(request) {
  1192. grpc::Status status(grpc::StatusCode::UNIMPLEMENTED, "");
  1193. grpc::internal::UnknownMethodHandler::FillOps(request_->context(), this);
  1194. request_->stream()->call_.PerformOps(this);
  1195. }
  1196. grpc::ServerInitializer* Server::initializer() {
  1197. return server_initializer_.get();
  1198. }
  1199. grpc::CompletionQueue* Server::CallbackCQ() {
  1200. // TODO(vjpai): Consider using a single global CQ for the default CQ
  1201. // if there is no explicit per-server CQ registered
  1202. grpc::internal::MutexLock l(&mu_);
  1203. if (callback_cq_ != nullptr) {
  1204. return callback_cq_;
  1205. }
  1206. auto* shutdown_callback = new grpc::ShutdownCallback;
  1207. callback_cq_ = new grpc::CompletionQueue(grpc_completion_queue_attributes{
  1208. GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING,
  1209. shutdown_callback});
  1210. // Transfer ownership of the new cq to its own shutdown callback
  1211. shutdown_callback->TakeCQ(callback_cq_);
  1212. return callback_cq_;
  1213. }
  1214. } // namespace grpc