server_cc.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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 <grpc++/server.h>
  18. #include <sstream>
  19. #include <utility>
  20. #include <grpc++/completion_queue.h>
  21. #include <grpc++/generic/async_generic_service.h>
  22. #include <grpc++/impl/codegen/async_unary_call.h>
  23. #include <grpc++/impl/codegen/completion_queue_tag.h>
  24. #include <grpc++/impl/grpc_library.h>
  25. #include <grpc++/impl/method_handler_impl.h>
  26. #include <grpc++/impl/rpc_service_method.h>
  27. #include <grpc++/impl/server_initializer.h>
  28. #include <grpc++/impl/service_type.h>
  29. #include <grpc++/security/server_credentials.h>
  30. #include <grpc++/server_context.h>
  31. #include <grpc++/support/time.h>
  32. #include <grpc/grpc.h>
  33. #include <grpc/support/alloc.h>
  34. #include <grpc/support/log.h>
  35. #include "src/core/lib/profiling/timers.h"
  36. #include "src/cpp/server/health/default_health_check_service.h"
  37. #include "src/cpp/thread_manager/thread_manager.h"
  38. namespace grpc {
  39. class DefaultGlobalCallbacks final : public Server::GlobalCallbacks {
  40. public:
  41. ~DefaultGlobalCallbacks() override {}
  42. void PreSynchronousRequest(ServerContext* context) override {}
  43. void PostSynchronousRequest(ServerContext* context) override {}
  44. };
  45. static std::shared_ptr<Server::GlobalCallbacks> g_callbacks = nullptr;
  46. static gpr_once g_once_init_callbacks = GPR_ONCE_INIT;
  47. static void InitGlobalCallbacks() {
  48. if (!g_callbacks) {
  49. g_callbacks.reset(new DefaultGlobalCallbacks());
  50. }
  51. }
  52. class Server::UnimplementedAsyncRequestContext {
  53. protected:
  54. UnimplementedAsyncRequestContext() : generic_stream_(&server_context_) {}
  55. GenericServerContext server_context_;
  56. GenericServerAsyncReaderWriter generic_stream_;
  57. };
  58. class Server::UnimplementedAsyncRequest final
  59. : public UnimplementedAsyncRequestContext,
  60. public GenericAsyncRequest {
  61. public:
  62. UnimplementedAsyncRequest(Server* server, ServerCompletionQueue* cq)
  63. : GenericAsyncRequest(server, &server_context_, &generic_stream_, cq, cq,
  64. NULL, false),
  65. server_(server),
  66. cq_(cq) {}
  67. bool FinalizeResult(void** tag, bool* status) override;
  68. ServerContext* context() { return &server_context_; }
  69. GenericServerAsyncReaderWriter* stream() { return &generic_stream_; }
  70. private:
  71. Server* const server_;
  72. ServerCompletionQueue* const cq_;
  73. };
  74. typedef SneakyCallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus>
  75. UnimplementedAsyncResponseOp;
  76. class Server::UnimplementedAsyncResponse final
  77. : public UnimplementedAsyncResponseOp {
  78. public:
  79. UnimplementedAsyncResponse(UnimplementedAsyncRequest* request);
  80. ~UnimplementedAsyncResponse() { delete request_; }
  81. bool FinalizeResult(void** tag, bool* status) override {
  82. bool r = UnimplementedAsyncResponseOp::FinalizeResult(tag, status);
  83. delete this;
  84. return r;
  85. }
  86. private:
  87. UnimplementedAsyncRequest* const request_;
  88. };
  89. class ShutdownTag : public CompletionQueueTag {
  90. public:
  91. bool FinalizeResult(void** tag, bool* status) { return false; }
  92. };
  93. class DummyTag : public CompletionQueueTag {
  94. public:
  95. bool FinalizeResult(void** tag, bool* status) {
  96. *status = true;
  97. return true;
  98. }
  99. };
  100. class Server::SyncRequest final : public CompletionQueueTag {
  101. public:
  102. SyncRequest(RpcServiceMethod* method, void* tag)
  103. : method_(method),
  104. tag_(tag),
  105. in_flight_(false),
  106. has_request_payload_(method->method_type() == RpcMethod::NORMAL_RPC ||
  107. method->method_type() ==
  108. RpcMethod::SERVER_STREAMING),
  109. call_details_(nullptr),
  110. cq_(nullptr) {
  111. grpc_metadata_array_init(&request_metadata_);
  112. }
  113. ~SyncRequest() {
  114. if (call_details_) {
  115. delete call_details_;
  116. }
  117. grpc_metadata_array_destroy(&request_metadata_);
  118. }
  119. void SetupRequest() { cq_ = grpc_completion_queue_create_for_pluck(nullptr); }
  120. void TeardownRequest() {
  121. grpc_completion_queue_destroy(cq_);
  122. cq_ = nullptr;
  123. }
  124. void Request(grpc_server* server, grpc_completion_queue* notify_cq) {
  125. GPR_ASSERT(cq_ && !in_flight_);
  126. in_flight_ = true;
  127. if (tag_) {
  128. GPR_ASSERT(GRPC_CALL_OK ==
  129. grpc_server_request_registered_call(
  130. server, tag_, &call_, &deadline_, &request_metadata_,
  131. has_request_payload_ ? &request_payload_ : nullptr, cq_,
  132. notify_cq, this));
  133. } else {
  134. if (!call_details_) {
  135. call_details_ = new grpc_call_details;
  136. grpc_call_details_init(call_details_);
  137. }
  138. GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
  139. server, &call_, call_details_,
  140. &request_metadata_, cq_, notify_cq, this));
  141. }
  142. }
  143. bool FinalizeResult(void** tag, bool* status) override {
  144. if (!*status) {
  145. grpc_completion_queue_destroy(cq_);
  146. }
  147. if (call_details_) {
  148. deadline_ = call_details_->deadline;
  149. grpc_call_details_destroy(call_details_);
  150. grpc_call_details_init(call_details_);
  151. }
  152. return true;
  153. }
  154. class CallData final {
  155. public:
  156. explicit CallData(Server* server, SyncRequest* mrd)
  157. : cq_(mrd->cq_),
  158. call_(mrd->call_, server, &cq_, server->max_receive_message_size()),
  159. ctx_(mrd->deadline_, &mrd->request_metadata_),
  160. has_request_payload_(mrd->has_request_payload_),
  161. request_payload_(mrd->request_payload_),
  162. method_(mrd->method_) {
  163. ctx_.set_call(mrd->call_);
  164. ctx_.cq_ = &cq_;
  165. GPR_ASSERT(mrd->in_flight_);
  166. mrd->in_flight_ = false;
  167. mrd->request_metadata_.count = 0;
  168. }
  169. ~CallData() {
  170. if (has_request_payload_ && request_payload_) {
  171. grpc_byte_buffer_destroy(request_payload_);
  172. }
  173. }
  174. void Run(std::shared_ptr<GlobalCallbacks> global_callbacks) {
  175. ctx_.BeginCompletionOp(&call_);
  176. global_callbacks->PreSynchronousRequest(&ctx_);
  177. method_->handler()->RunHandler(
  178. MethodHandler::HandlerParameter(&call_, &ctx_, request_payload_));
  179. global_callbacks->PostSynchronousRequest(&ctx_);
  180. request_payload_ = nullptr;
  181. cq_.Shutdown();
  182. CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag();
  183. cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME));
  184. /* Ensure the cq_ is shutdown */
  185. DummyTag ignored_tag;
  186. GPR_ASSERT(cq_.Pluck(&ignored_tag) == false);
  187. }
  188. private:
  189. CompletionQueue cq_;
  190. Call call_;
  191. ServerContext ctx_;
  192. const bool has_request_payload_;
  193. grpc_byte_buffer* request_payload_;
  194. RpcServiceMethod* const method_;
  195. };
  196. private:
  197. RpcServiceMethod* const method_;
  198. void* const tag_;
  199. bool in_flight_;
  200. const bool has_request_payload_;
  201. grpc_call* call_;
  202. grpc_call_details* call_details_;
  203. gpr_timespec deadline_;
  204. grpc_metadata_array request_metadata_;
  205. grpc_byte_buffer* request_payload_;
  206. grpc_completion_queue* cq_;
  207. };
  208. // Implementation of ThreadManager. Each instance of SyncRequestThreadManager
  209. // manages a pool of threads that poll for incoming Sync RPCs and call the
  210. // appropriate RPC handlers
  211. class Server::SyncRequestThreadManager : public ThreadManager {
  212. public:
  213. SyncRequestThreadManager(Server* server, CompletionQueue* server_cq,
  214. std::shared_ptr<GlobalCallbacks> global_callbacks,
  215. int min_pollers, int max_pollers,
  216. int cq_timeout_msec)
  217. : ThreadManager(min_pollers, max_pollers),
  218. server_(server),
  219. server_cq_(server_cq),
  220. cq_timeout_msec_(cq_timeout_msec),
  221. global_callbacks_(global_callbacks) {}
  222. WorkStatus PollForWork(void** tag, bool* ok) override {
  223. *tag = nullptr;
  224. gpr_timespec deadline =
  225. gpr_time_from_millis(cq_timeout_msec_, GPR_TIMESPAN);
  226. switch (server_cq_->AsyncNext(tag, ok, deadline)) {
  227. case CompletionQueue::TIMEOUT:
  228. return TIMEOUT;
  229. case CompletionQueue::SHUTDOWN:
  230. return SHUTDOWN;
  231. case CompletionQueue::GOT_EVENT:
  232. return WORK_FOUND;
  233. }
  234. GPR_UNREACHABLE_CODE(return TIMEOUT);
  235. }
  236. void DoWork(void* tag, bool ok) override {
  237. SyncRequest* sync_req = static_cast<SyncRequest*>(tag);
  238. if (!sync_req) {
  239. // No tag. Nothing to work on. This is an unlikley scenario and possibly a
  240. // bug in RPC Manager implementation.
  241. gpr_log(GPR_ERROR, "Sync server. DoWork() was called with NULL tag");
  242. return;
  243. }
  244. if (ok) {
  245. // Calldata takes ownership of the completion queue inside sync_req
  246. SyncRequest::CallData cd(server_, sync_req);
  247. {
  248. // Prepare for the next request
  249. if (!IsShutdown()) {
  250. sync_req->SetupRequest(); // Create new completion queue for sync_req
  251. sync_req->Request(server_->c_server(), server_cq_->cq());
  252. }
  253. }
  254. GPR_TIMER_SCOPE("cd.Run()", 0);
  255. cd.Run(global_callbacks_);
  256. }
  257. // TODO (sreek) If ok is false here (which it isn't in case of
  258. // grpc_request_registered_call), we should still re-queue the request
  259. // object
  260. }
  261. void AddSyncMethod(RpcServiceMethod* method, void* tag) {
  262. sync_requests_.emplace_back(new SyncRequest(method, tag));
  263. }
  264. void AddUnknownSyncMethod() {
  265. if (!sync_requests_.empty()) {
  266. unknown_method_.reset(new RpcServiceMethod(
  267. "unknown", RpcMethod::BIDI_STREAMING, new UnknownMethodHandler));
  268. sync_requests_.emplace_back(
  269. new SyncRequest(unknown_method_.get(), nullptr));
  270. }
  271. }
  272. void Shutdown() override {
  273. server_cq_->Shutdown();
  274. ThreadManager::Shutdown();
  275. }
  276. void Wait() override {
  277. ThreadManager::Wait();
  278. // Drain any pending items from the queue
  279. void* tag;
  280. bool ok;
  281. while (server_cq_->Next(&tag, &ok)) {
  282. // Do nothing
  283. }
  284. }
  285. void Start() {
  286. if (!sync_requests_.empty()) {
  287. for (auto m = sync_requests_.begin(); m != sync_requests_.end(); m++) {
  288. (*m)->SetupRequest();
  289. (*m)->Request(server_->c_server(), server_cq_->cq());
  290. }
  291. Initialize(); // ThreadManager's Initialize()
  292. }
  293. }
  294. private:
  295. Server* server_;
  296. CompletionQueue* server_cq_;
  297. int cq_timeout_msec_;
  298. std::vector<std::unique_ptr<SyncRequest>> sync_requests_;
  299. std::unique_ptr<RpcServiceMethod> unknown_method_;
  300. std::unique_ptr<RpcServiceMethod> health_check_;
  301. std::shared_ptr<Server::GlobalCallbacks> global_callbacks_;
  302. };
  303. static internal::GrpcLibraryInitializer g_gli_initializer;
  304. Server::Server(
  305. int max_receive_message_size, ChannelArguments* args,
  306. std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
  307. sync_server_cqs,
  308. int min_pollers, int max_pollers, int sync_cq_timeout_msec)
  309. : max_receive_message_size_(max_receive_message_size),
  310. sync_server_cqs_(sync_server_cqs),
  311. started_(false),
  312. shutdown_(false),
  313. shutdown_notified_(false),
  314. has_generic_service_(false),
  315. server_(nullptr),
  316. server_initializer_(new ServerInitializer(this)),
  317. health_check_service_disabled_(false) {
  318. g_gli_initializer.summon();
  319. gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks);
  320. global_callbacks_ = g_callbacks;
  321. global_callbacks_->UpdateArguments(args);
  322. for (auto it = sync_server_cqs_->begin(); it != sync_server_cqs_->end();
  323. it++) {
  324. sync_req_mgrs_.emplace_back(new SyncRequestThreadManager(
  325. this, (*it).get(), global_callbacks_, min_pollers, max_pollers,
  326. sync_cq_timeout_msec));
  327. }
  328. grpc_channel_args channel_args;
  329. args->SetChannelArgs(&channel_args);
  330. for (size_t i = 0; i < channel_args.num_args; i++) {
  331. if (0 ==
  332. strcmp(channel_args.args[i].key, kHealthCheckServiceInterfaceArg)) {
  333. if (channel_args.args[i].value.pointer.p == nullptr) {
  334. health_check_service_disabled_ = true;
  335. } else {
  336. health_check_service_.reset(static_cast<HealthCheckServiceInterface*>(
  337. channel_args.args[i].value.pointer.p));
  338. }
  339. break;
  340. }
  341. }
  342. server_ = grpc_server_create(&channel_args, nullptr);
  343. }
  344. Server::~Server() {
  345. {
  346. std::unique_lock<std::mutex> lock(mu_);
  347. if (started_ && !shutdown_) {
  348. lock.unlock();
  349. Shutdown();
  350. } else if (!started_) {
  351. // Shutdown the completion queues
  352. for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
  353. (*it)->Shutdown();
  354. }
  355. }
  356. }
  357. grpc_server_destroy(server_);
  358. }
  359. void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) {
  360. GPR_ASSERT(!g_callbacks);
  361. GPR_ASSERT(callbacks);
  362. g_callbacks.reset(callbacks);
  363. }
  364. grpc_server* Server::c_server() { return server_; }
  365. static grpc_server_register_method_payload_handling PayloadHandlingForMethod(
  366. RpcServiceMethod* method) {
  367. switch (method->method_type()) {
  368. case RpcMethod::NORMAL_RPC:
  369. case RpcMethod::SERVER_STREAMING:
  370. return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER;
  371. case RpcMethod::CLIENT_STREAMING:
  372. case RpcMethod::BIDI_STREAMING:
  373. return GRPC_SRM_PAYLOAD_NONE;
  374. }
  375. GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;);
  376. }
  377. bool Server::RegisterService(const grpc::string* host, Service* service) {
  378. bool has_async_methods = service->has_async_methods();
  379. if (has_async_methods) {
  380. GPR_ASSERT(service->server_ == nullptr &&
  381. "Can only register an asynchronous service against one server.");
  382. service->server_ = this;
  383. }
  384. const char* method_name = nullptr;
  385. for (auto it = service->methods_.begin(); it != service->methods_.end();
  386. ++it) {
  387. if (it->get() == nullptr) { // Handled by generic service if any.
  388. continue;
  389. }
  390. RpcServiceMethod* method = it->get();
  391. void* tag = grpc_server_register_method(
  392. server_, method->name(), host ? host->c_str() : nullptr,
  393. PayloadHandlingForMethod(method), 0);
  394. if (tag == nullptr) {
  395. gpr_log(GPR_DEBUG, "Attempt to register %s multiple times",
  396. method->name());
  397. return false;
  398. }
  399. if (method->handler() == nullptr) { // Async method
  400. method->set_server_tag(tag);
  401. } else {
  402. for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
  403. (*it)->AddSyncMethod(method, tag);
  404. }
  405. }
  406. method_name = method->name();
  407. }
  408. // Parse service name.
  409. if (method_name != nullptr) {
  410. std::stringstream ss(method_name);
  411. grpc::string service_name;
  412. if (std::getline(ss, service_name, '/') &&
  413. std::getline(ss, service_name, '/')) {
  414. services_.push_back(service_name);
  415. }
  416. }
  417. return true;
  418. }
  419. void Server::RegisterAsyncGenericService(AsyncGenericService* service) {
  420. GPR_ASSERT(service->server_ == nullptr &&
  421. "Can only register an async generic service against one server.");
  422. service->server_ = this;
  423. has_generic_service_ = true;
  424. }
  425. int Server::AddListeningPort(const grpc::string& addr,
  426. ServerCredentials* creds) {
  427. GPR_ASSERT(!started_);
  428. int port = creds->AddPortToServer(addr, server_);
  429. global_callbacks_->AddPort(this, addr, creds, port);
  430. return port;
  431. }
  432. void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) {
  433. GPR_ASSERT(!started_);
  434. global_callbacks_->PreServerStart(this);
  435. started_ = true;
  436. // Only create default health check service when user did not provide an
  437. // explicit one.
  438. if (health_check_service_ == nullptr && !health_check_service_disabled_ &&
  439. DefaultHealthCheckServiceEnabled()) {
  440. if (sync_server_cqs_->empty()) {
  441. gpr_log(GPR_INFO,
  442. "Default health check service disabled at async-only server.");
  443. } else {
  444. auto* default_hc_service = new DefaultHealthCheckService;
  445. health_check_service_.reset(default_hc_service);
  446. RegisterService(nullptr, default_hc_service->GetHealthCheckService());
  447. }
  448. }
  449. grpc_server_start(server_);
  450. if (!has_generic_service_) {
  451. for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
  452. (*it)->AddUnknownSyncMethod();
  453. }
  454. for (size_t i = 0; i < num_cqs; i++) {
  455. if (cqs[i]->IsFrequentlyPolled()) {
  456. new UnimplementedAsyncRequest(this, cqs[i]);
  457. }
  458. }
  459. }
  460. for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
  461. (*it)->Start();
  462. }
  463. }
  464. void Server::ShutdownInternal(gpr_timespec deadline) {
  465. std::unique_lock<std::mutex> lock(mu_);
  466. if (!shutdown_) {
  467. shutdown_ = true;
  468. /// The completion queue to use for server shutdown completion notification
  469. CompletionQueue shutdown_cq;
  470. ShutdownTag shutdown_tag; // Dummy shutdown tag
  471. grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag);
  472. shutdown_cq.Shutdown();
  473. void* tag;
  474. bool ok;
  475. CompletionQueue::NextStatus status =
  476. shutdown_cq.AsyncNext(&tag, &ok, deadline);
  477. // If this timed out, it means we are done with the grace period for a clean
  478. // shutdown. We should force a shutdown now by cancelling all inflight calls
  479. if (status == CompletionQueue::NextStatus::TIMEOUT) {
  480. grpc_server_cancel_all_calls(server_);
  481. }
  482. // Else in case of SHUTDOWN or GOT_EVENT, it means that the server has
  483. // successfully shutdown
  484. // Shutdown all ThreadManagers. This will try to gracefully stop all the
  485. // threads in the ThreadManagers (once they process any inflight requests)
  486. for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
  487. (*it)->Shutdown(); // ThreadManager's Shutdown()
  488. }
  489. // Wait for threads in all ThreadManagers to terminate
  490. for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) {
  491. (*it)->Wait();
  492. }
  493. // Drain the shutdown queue (if the previous call to AsyncNext() timed out
  494. // and we didn't remove the tag from the queue yet)
  495. while (shutdown_cq.Next(&tag, &ok)) {
  496. // Nothing to be done here. Just ignore ok and tag values
  497. }
  498. shutdown_notified_ = true;
  499. shutdown_cv_.notify_all();
  500. }
  501. }
  502. void Server::Wait() {
  503. std::unique_lock<std::mutex> lock(mu_);
  504. while (started_ && !shutdown_notified_) {
  505. shutdown_cv_.wait(lock);
  506. }
  507. }
  508. void Server::PerformOpsOnCall(CallOpSetInterface* ops, Call* call) {
  509. static const size_t MAX_OPS = 8;
  510. size_t nops = 0;
  511. grpc_op cops[MAX_OPS];
  512. ops->FillOps(call->call(), cops, &nops);
  513. auto result = grpc_call_start_batch(call->call(), cops, nops, ops, nullptr);
  514. GPR_ASSERT(GRPC_CALL_OK == result);
  515. }
  516. ServerInterface::BaseAsyncRequest::BaseAsyncRequest(
  517. ServerInterface* server, ServerContext* context,
  518. ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, void* tag,
  519. bool delete_on_finalize)
  520. : server_(server),
  521. context_(context),
  522. stream_(stream),
  523. call_cq_(call_cq),
  524. tag_(tag),
  525. delete_on_finalize_(delete_on_finalize),
  526. call_(nullptr) {
  527. call_cq_->RegisterAvalanching(); // This op will trigger more ops
  528. }
  529. ServerInterface::BaseAsyncRequest::~BaseAsyncRequest() {
  530. call_cq_->CompleteAvalanching();
  531. }
  532. bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag,
  533. bool* status) {
  534. if (*status) {
  535. context_->client_metadata_.FillMap();
  536. }
  537. context_->set_call(call_);
  538. context_->cq_ = call_cq_;
  539. Call call(call_, server_, call_cq_, server_->max_receive_message_size());
  540. if (*status && call_) {
  541. context_->BeginCompletionOp(&call);
  542. }
  543. // just the pointers inside call are copied here
  544. stream_->BindCall(&call);
  545. *tag = tag_;
  546. if (delete_on_finalize_) {
  547. delete this;
  548. }
  549. return true;
  550. }
  551. ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest(
  552. ServerInterface* server, ServerContext* context,
  553. ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, void* tag)
  554. : BaseAsyncRequest(server, context, stream, call_cq, tag, true) {}
  555. void ServerInterface::RegisteredAsyncRequest::IssueRequest(
  556. void* registered_method, grpc_byte_buffer** payload,
  557. ServerCompletionQueue* notification_cq) {
  558. grpc_server_request_registered_call(
  559. server_->server(), registered_method, &call_, &context_->deadline_,
  560. context_->client_metadata_.arr(), payload, call_cq_->cq(),
  561. notification_cq->cq(), this);
  562. }
  563. ServerInterface::GenericAsyncRequest::GenericAsyncRequest(
  564. ServerInterface* server, GenericServerContext* context,
  565. ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
  566. ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize)
  567. : BaseAsyncRequest(server, context, stream, call_cq, tag,
  568. delete_on_finalize) {
  569. grpc_call_details_init(&call_details_);
  570. GPR_ASSERT(notification_cq);
  571. GPR_ASSERT(call_cq);
  572. grpc_server_request_call(server->server(), &call_, &call_details_,
  573. context->client_metadata_.arr(), call_cq->cq(),
  574. notification_cq->cq(), this);
  575. }
  576. bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag,
  577. bool* status) {
  578. // TODO(yangg) remove the copy here.
  579. if (*status) {
  580. static_cast<GenericServerContext*>(context_)->method_ =
  581. StringFromCopiedSlice(call_details_.method);
  582. static_cast<GenericServerContext*>(context_)->host_ =
  583. StringFromCopiedSlice(call_details_.host);
  584. context_->deadline_ = call_details_.deadline;
  585. }
  586. grpc_slice_unref(call_details_.method);
  587. grpc_slice_unref(call_details_.host);
  588. return BaseAsyncRequest::FinalizeResult(tag, status);
  589. }
  590. bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag,
  591. bool* status) {
  592. if (GenericAsyncRequest::FinalizeResult(tag, status) && *status) {
  593. new UnimplementedAsyncRequest(server_, cq_);
  594. new UnimplementedAsyncResponse(this);
  595. } else {
  596. delete this;
  597. }
  598. return false;
  599. }
  600. Server::UnimplementedAsyncResponse::UnimplementedAsyncResponse(
  601. UnimplementedAsyncRequest* request)
  602. : request_(request) {
  603. Status status(StatusCode::UNIMPLEMENTED, "");
  604. UnknownMethodHandler::FillOps(request_->context(), this);
  605. request_->stream()->call_.PerformOps(this);
  606. }
  607. ServerInitializer* Server::initializer() { return server_initializer_.get(); }
  608. } // namespace grpc