async_stream.h 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. /*
  2. *
  3. * Copyright 2019 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H
  18. #define GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H
  19. // IWYU pragma: private, include <grpcpp/support/async_stream.h>
  20. #include <grpcpp/impl/codegen/call.h>
  21. #include <grpcpp/impl/codegen/channel_interface.h>
  22. #include <grpcpp/impl/codegen/core_codegen_interface.h>
  23. #include <grpcpp/impl/codegen/server_context.h>
  24. #include <grpcpp/impl/codegen/service_type.h>
  25. #include <grpcpp/impl/codegen/status.h>
  26. namespace grpc {
  27. namespace internal {
  28. /// Common interface for all client side asynchronous streaming.
  29. class ClientAsyncStreamingInterface {
  30. public:
  31. virtual ~ClientAsyncStreamingInterface() {}
  32. /// Start the call that was set up by the constructor, but only if the
  33. /// constructor was invoked through the "Prepare" API which doesn't actually
  34. /// start the call
  35. virtual void StartCall(void* tag) = 0;
  36. /// Request notification of the reading of the initial metadata. Completion
  37. /// will be notified by \a tag on the associated completion queue.
  38. /// This call is optional, but if it is used, it cannot be used concurrently
  39. /// with or after the \a AsyncReaderInterface::Read method.
  40. ///
  41. /// \param[in] tag Tag identifying this request.
  42. virtual void ReadInitialMetadata(void* tag) = 0;
  43. /// Indicate that the stream is to be finished and request notification for
  44. /// when the call has been ended.
  45. /// Should not be used concurrently with other operations.
  46. ///
  47. /// It is appropriate to call this method exactly once when both:
  48. /// * the client side has no more message to send
  49. /// (this can be declared implicitly by calling this method, or
  50. /// explicitly through an earlier call to the <i>WritesDone</i> method
  51. /// of the class in use, e.g. \a ClientAsyncWriterInterface::WritesDone or
  52. /// \a ClientAsyncReaderWriterInterface::WritesDone).
  53. /// * there are no more messages to be received from the server (this can
  54. /// be known implicitly by the calling code, or explicitly from an
  55. /// earlier call to \a AsyncReaderInterface::Read that yielded a failed
  56. /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false').
  57. ///
  58. /// The tag will be returned when either:
  59. /// - all incoming messages have been read and the server has returned
  60. /// a status.
  61. /// - the server has returned a non-OK status.
  62. /// - the call failed for some reason and the library generated a
  63. /// status.
  64. ///
  65. /// Note that implementations of this method attempt to receive initial
  66. /// metadata from the server if initial metadata hasn't yet been received.
  67. ///
  68. /// \param[in] tag Tag identifying this request.
  69. /// \param[out] status To be updated with the operation status.
  70. virtual void Finish(grpc::Status* status, void* tag) = 0;
  71. };
  72. /// An interface that yields a sequence of messages of type \a R.
  73. template <class R>
  74. class AsyncReaderInterface {
  75. public:
  76. virtual ~AsyncReaderInterface() {}
  77. /// Read a message of type \a R into \a msg. Completion will be notified by \a
  78. /// tag on the associated completion queue.
  79. /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
  80. /// should not be called concurrently with other streaming APIs
  81. /// on the same stream. It is not meaningful to call it concurrently
  82. /// with another \a AsyncReaderInterface::Read on the same stream since reads
  83. /// on the same stream are delivered in order.
  84. ///
  85. /// \param[out] msg Where to eventually store the read message.
  86. /// \param[in] tag The tag identifying the operation.
  87. ///
  88. /// Side effect: note that this method attempt to receive initial metadata for
  89. /// a stream if it hasn't yet been received.
  90. virtual void Read(R* msg, void* tag) = 0;
  91. };
  92. /// An interface that can be fed a sequence of messages of type \a W.
  93. template <class W>
  94. class AsyncWriterInterface {
  95. public:
  96. virtual ~AsyncWriterInterface() {}
  97. /// Request the writing of \a msg with identifying tag \a tag.
  98. ///
  99. /// Only one write may be outstanding at any given time. This means that
  100. /// after calling Write, one must wait to receive \a tag from the completion
  101. /// queue BEFORE calling Write again.
  102. /// This is thread-safe with respect to \a AsyncReaderInterface::Read
  103. ///
  104. /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to
  105. /// to deallocate once Write returns.
  106. ///
  107. /// \param[in] msg The message to be written.
  108. /// \param[in] tag The tag identifying the operation.
  109. virtual void Write(const W& msg, void* tag) = 0;
  110. /// Request the writing of \a msg using WriteOptions \a options with
  111. /// identifying tag \a tag.
  112. ///
  113. /// Only one write may be outstanding at any given time. This means that
  114. /// after calling Write, one must wait to receive \a tag from the completion
  115. /// queue BEFORE calling Write again.
  116. /// WriteOptions \a options is used to set the write options of this message.
  117. /// This is thread-safe with respect to \a AsyncReaderInterface::Read
  118. ///
  119. /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to
  120. /// to deallocate once Write returns.
  121. ///
  122. /// \param[in] msg The message to be written.
  123. /// \param[in] options The WriteOptions to be used to write this message.
  124. /// \param[in] tag The tag identifying the operation.
  125. virtual void Write(const W& msg, grpc::WriteOptions options, void* tag) = 0;
  126. /// Request the writing of \a msg and coalesce it with the writing
  127. /// of trailing metadata, using WriteOptions \a options with
  128. /// identifying tag \a tag.
  129. ///
  130. /// For client, WriteLast is equivalent of performing Write and
  131. /// WritesDone in a single step.
  132. /// For server, WriteLast buffers the \a msg. The writing of \a msg is held
  133. /// until Finish is called, where \a msg and trailing metadata are coalesced
  134. /// and write is initiated. Note that WriteLast can only buffer \a msg up to
  135. /// the flow control window size. If \a msg size is larger than the window
  136. /// size, it will be sent on wire without buffering.
  137. ///
  138. /// gRPC doesn't take ownership or a reference to \a msg, so it is safe to
  139. /// to deallocate once Write returns.
  140. ///
  141. /// \param[in] msg The message to be written.
  142. /// \param[in] options The WriteOptions to be used to write this message.
  143. /// \param[in] tag The tag identifying the operation.
  144. void WriteLast(const W& msg, grpc::WriteOptions options, void* tag) {
  145. Write(msg, options.set_last_message(), tag);
  146. }
  147. };
  148. } // namespace internal
  149. template <class R>
  150. class ClientAsyncReaderInterface
  151. : public internal::ClientAsyncStreamingInterface,
  152. public internal::AsyncReaderInterface<R> {};
  153. namespace internal {
  154. template <class R>
  155. class ClientAsyncReaderFactory {
  156. public:
  157. /// Create a stream object.
  158. /// Write the first request out if \a start is set.
  159. /// \a tag will be notified on \a cq when the call has been started and
  160. /// \a request has been written out. If \a start is not set, \a tag must be
  161. /// nullptr and the actual call must be initiated by StartCall
  162. /// Note that \a context will be used to fill in custom initial metadata
  163. /// used to send to the server when starting the call.
  164. template <class W>
  165. static ClientAsyncReader<R>* Create(grpc::ChannelInterface* channel,
  166. grpc::CompletionQueue* cq,
  167. const grpc::internal::RpcMethod& method,
  168. grpc::ClientContext* context,
  169. const W& request, bool start, void* tag) {
  170. grpc::internal::Call call = channel->CreateCall(method, context, cq);
  171. return new (grpc::g_core_codegen_interface->grpc_call_arena_alloc(
  172. call.call(), sizeof(ClientAsyncReader<R>)))
  173. ClientAsyncReader<R>(call, context, request, start, tag);
  174. }
  175. };
  176. } // namespace internal
  177. /// Async client-side API for doing server-streaming RPCs,
  178. /// where the incoming message stream coming from the server has
  179. /// messages of type \a R.
  180. template <class R>
  181. class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
  182. public:
  183. // always allocated against a call arena, no memory free required
  184. static void operator delete(void* /*ptr*/, std::size_t size) {
  185. GPR_CODEGEN_ASSERT(size == sizeof(ClientAsyncReader));
  186. }
  187. // This operator should never be called as the memory should be freed as part
  188. // of the arena destruction. It only exists to provide a matching operator
  189. // delete to the operator new so that some compilers will not complain (see
  190. // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
  191. // there are no tests catching the compiler warning.
  192. static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
  193. void StartCall(void* tag) override {
  194. GPR_CODEGEN_ASSERT(!started_);
  195. started_ = true;
  196. StartCallInternal(tag);
  197. }
  198. /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata
  199. /// method for semantics.
  200. ///
  201. /// Side effect:
  202. /// - upon receiving initial metadata from the server,
  203. /// the \a ClientContext associated with this call is updated, and the
  204. /// calling code can access the received metadata through the
  205. /// \a ClientContext.
  206. void ReadInitialMetadata(void* tag) override {
  207. GPR_CODEGEN_ASSERT(started_);
  208. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  209. meta_ops_.set_output_tag(tag);
  210. meta_ops_.RecvInitialMetadata(context_);
  211. call_.PerformOps(&meta_ops_);
  212. }
  213. void Read(R* msg, void* tag) override {
  214. GPR_CODEGEN_ASSERT(started_);
  215. read_ops_.set_output_tag(tag);
  216. if (!context_->initial_metadata_received_) {
  217. read_ops_.RecvInitialMetadata(context_);
  218. }
  219. read_ops_.RecvMessage(msg);
  220. call_.PerformOps(&read_ops_);
  221. }
  222. /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
  223. ///
  224. /// Side effect:
  225. /// - the \a ClientContext associated with this call is updated with
  226. /// possible initial and trailing metadata received from the server.
  227. void Finish(grpc::Status* status, void* tag) override {
  228. GPR_CODEGEN_ASSERT(started_);
  229. finish_ops_.set_output_tag(tag);
  230. if (!context_->initial_metadata_received_) {
  231. finish_ops_.RecvInitialMetadata(context_);
  232. }
  233. finish_ops_.ClientRecvStatus(context_, status);
  234. call_.PerformOps(&finish_ops_);
  235. }
  236. private:
  237. friend class internal::ClientAsyncReaderFactory<R>;
  238. template <class W>
  239. ClientAsyncReader(grpc::internal::Call call, grpc::ClientContext* context,
  240. const W& request, bool start, void* tag)
  241. : context_(context), call_(call), started_(start) {
  242. // TODO(ctiller): don't assert
  243. GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
  244. init_ops_.ClientSendClose();
  245. if (start) {
  246. StartCallInternal(tag);
  247. } else {
  248. GPR_CODEGEN_ASSERT(tag == nullptr);
  249. }
  250. }
  251. void StartCallInternal(void* tag) {
  252. init_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
  253. context_->initial_metadata_flags());
  254. init_ops_.set_output_tag(tag);
  255. call_.PerformOps(&init_ops_);
  256. }
  257. grpc::ClientContext* context_;
  258. grpc::internal::Call call_;
  259. bool started_;
  260. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  261. grpc::internal::CallOpSendMessage,
  262. grpc::internal::CallOpClientSendClose>
  263. init_ops_;
  264. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata>
  265. meta_ops_;
  266. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  267. grpc::internal::CallOpRecvMessage<R>>
  268. read_ops_;
  269. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  270. grpc::internal::CallOpClientRecvStatus>
  271. finish_ops_;
  272. };
  273. /// Common interface for client side asynchronous writing.
  274. template <class W>
  275. class ClientAsyncWriterInterface
  276. : public internal::ClientAsyncStreamingInterface,
  277. public internal::AsyncWriterInterface<W> {
  278. public:
  279. /// Signal the client is done with the writes (half-close the client stream).
  280. /// Thread-safe with respect to \a AsyncReaderInterface::Read
  281. ///
  282. /// \param[in] tag The tag identifying the operation.
  283. virtual void WritesDone(void* tag) = 0;
  284. };
  285. namespace internal {
  286. template <class W>
  287. class ClientAsyncWriterFactory {
  288. public:
  289. /// Create a stream object.
  290. /// Start the RPC if \a start is set
  291. /// \a tag will be notified on \a cq when the call has been started (i.e.
  292. /// intitial metadata sent) and \a request has been written out.
  293. /// If \a start is not set, \a tag must be nullptr and the actual call
  294. /// must be initiated by StartCall
  295. /// Note that \a context will be used to fill in custom initial metadata
  296. /// used to send to the server when starting the call.
  297. /// \a response will be filled in with the single expected response
  298. /// message from the server upon a successful call to the \a Finish
  299. /// method of this instance.
  300. template <class R>
  301. static ClientAsyncWriter<W>* Create(grpc::ChannelInterface* channel,
  302. grpc::CompletionQueue* cq,
  303. const grpc::internal::RpcMethod& method,
  304. grpc::ClientContext* context, R* response,
  305. bool start, void* tag) {
  306. grpc::internal::Call call = channel->CreateCall(method, context, cq);
  307. return new (grpc::g_core_codegen_interface->grpc_call_arena_alloc(
  308. call.call(), sizeof(ClientAsyncWriter<W>)))
  309. ClientAsyncWriter<W>(call, context, response, start, tag);
  310. }
  311. };
  312. } // namespace internal
  313. /// Async API on the client side for doing client-streaming RPCs,
  314. /// where the outgoing message stream going to the server contains
  315. /// messages of type \a W.
  316. template <class W>
  317. class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
  318. public:
  319. // always allocated against a call arena, no memory free required
  320. static void operator delete(void* /*ptr*/, std::size_t size) {
  321. GPR_CODEGEN_ASSERT(size == sizeof(ClientAsyncWriter));
  322. }
  323. // This operator should never be called as the memory should be freed as part
  324. // of the arena destruction. It only exists to provide a matching operator
  325. // delete to the operator new so that some compilers will not complain (see
  326. // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
  327. // there are no tests catching the compiler warning.
  328. static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
  329. void StartCall(void* tag) override {
  330. GPR_CODEGEN_ASSERT(!started_);
  331. started_ = true;
  332. StartCallInternal(tag);
  333. }
  334. /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for
  335. /// semantics.
  336. ///
  337. /// Side effect:
  338. /// - upon receiving initial metadata from the server, the \a ClientContext
  339. /// associated with this call is updated, and the calling code can access
  340. /// the received metadata through the \a ClientContext.
  341. void ReadInitialMetadata(void* tag) override {
  342. GPR_CODEGEN_ASSERT(started_);
  343. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  344. meta_ops_.set_output_tag(tag);
  345. meta_ops_.RecvInitialMetadata(context_);
  346. call_.PerformOps(&meta_ops_);
  347. }
  348. void Write(const W& msg, void* tag) override {
  349. GPR_CODEGEN_ASSERT(started_);
  350. write_ops_.set_output_tag(tag);
  351. // TODO(ctiller): don't assert
  352. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  353. call_.PerformOps(&write_ops_);
  354. }
  355. void Write(const W& msg, grpc::WriteOptions options, void* tag) override {
  356. GPR_CODEGEN_ASSERT(started_);
  357. write_ops_.set_output_tag(tag);
  358. if (options.is_last_message()) {
  359. options.set_buffer_hint();
  360. write_ops_.ClientSendClose();
  361. }
  362. // TODO(ctiller): don't assert
  363. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  364. call_.PerformOps(&write_ops_);
  365. }
  366. void WritesDone(void* tag) override {
  367. GPR_CODEGEN_ASSERT(started_);
  368. write_ops_.set_output_tag(tag);
  369. write_ops_.ClientSendClose();
  370. call_.PerformOps(&write_ops_);
  371. }
  372. /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
  373. ///
  374. /// Side effect:
  375. /// - the \a ClientContext associated with this call is updated with
  376. /// possible initial and trailing metadata received from the server.
  377. /// - attempts to fill in the \a response parameter passed to this class's
  378. /// constructor with the server's response message.
  379. void Finish(grpc::Status* status, void* tag) override {
  380. GPR_CODEGEN_ASSERT(started_);
  381. finish_ops_.set_output_tag(tag);
  382. if (!context_->initial_metadata_received_) {
  383. finish_ops_.RecvInitialMetadata(context_);
  384. }
  385. finish_ops_.ClientRecvStatus(context_, status);
  386. call_.PerformOps(&finish_ops_);
  387. }
  388. private:
  389. friend class internal::ClientAsyncWriterFactory<W>;
  390. template <class R>
  391. ClientAsyncWriter(grpc::internal::Call call, grpc::ClientContext* context,
  392. R* response, bool start, void* tag)
  393. : context_(context), call_(call), started_(start) {
  394. finish_ops_.RecvMessage(response);
  395. finish_ops_.AllowNoMessage();
  396. if (start) {
  397. StartCallInternal(tag);
  398. } else {
  399. GPR_CODEGEN_ASSERT(tag == nullptr);
  400. }
  401. }
  402. void StartCallInternal(void* tag) {
  403. write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
  404. context_->initial_metadata_flags());
  405. // if corked bit is set in context, we just keep the initial metadata
  406. // buffered up to coalesce with later message send. No op is performed.
  407. if (!context_->initial_metadata_corked_) {
  408. write_ops_.set_output_tag(tag);
  409. call_.PerformOps(&write_ops_);
  410. }
  411. }
  412. grpc::ClientContext* context_;
  413. grpc::internal::Call call_;
  414. bool started_;
  415. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata>
  416. meta_ops_;
  417. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  418. grpc::internal::CallOpSendMessage,
  419. grpc::internal::CallOpClientSendClose>
  420. write_ops_;
  421. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  422. grpc::internal::CallOpGenericRecvMessage,
  423. grpc::internal::CallOpClientRecvStatus>
  424. finish_ops_;
  425. };
  426. /// Async client-side interface for bi-directional streaming,
  427. /// where the client-to-server message stream has messages of type \a W,
  428. /// and the server-to-client message stream has messages of type \a R.
  429. template <class W, class R>
  430. class ClientAsyncReaderWriterInterface
  431. : public internal::ClientAsyncStreamingInterface,
  432. public internal::AsyncWriterInterface<W>,
  433. public internal::AsyncReaderInterface<R> {
  434. public:
  435. /// Signal the client is done with the writes (half-close the client stream).
  436. /// Thread-safe with respect to \a AsyncReaderInterface::Read
  437. ///
  438. /// \param[in] tag The tag identifying the operation.
  439. virtual void WritesDone(void* tag) = 0;
  440. };
  441. namespace internal {
  442. template <class W, class R>
  443. class ClientAsyncReaderWriterFactory {
  444. public:
  445. /// Create a stream object.
  446. /// Start the RPC request if \a start is set.
  447. /// \a tag will be notified on \a cq when the call has been started (i.e.
  448. /// intitial metadata sent). If \a start is not set, \a tag must be
  449. /// nullptr and the actual call must be initiated by StartCall
  450. /// Note that \a context will be used to fill in custom initial metadata
  451. /// used to send to the server when starting the call.
  452. static ClientAsyncReaderWriter<W, R>* Create(
  453. grpc::ChannelInterface* channel, grpc::CompletionQueue* cq,
  454. const grpc::internal::RpcMethod& method, grpc::ClientContext* context,
  455. bool start, void* tag) {
  456. grpc::internal::Call call = channel->CreateCall(method, context, cq);
  457. return new (grpc::g_core_codegen_interface->grpc_call_arena_alloc(
  458. call.call(), sizeof(ClientAsyncReaderWriter<W, R>)))
  459. ClientAsyncReaderWriter<W, R>(call, context, start, tag);
  460. }
  461. };
  462. } // namespace internal
  463. /// Async client-side interface for bi-directional streaming,
  464. /// where the outgoing message stream going to the server
  465. /// has messages of type \a W, and the incoming message stream coming
  466. /// from the server has messages of type \a R.
  467. template <class W, class R>
  468. class ClientAsyncReaderWriter final
  469. : public ClientAsyncReaderWriterInterface<W, R> {
  470. public:
  471. // always allocated against a call arena, no memory free required
  472. static void operator delete(void* /*ptr*/, std::size_t size) {
  473. GPR_CODEGEN_ASSERT(size == sizeof(ClientAsyncReaderWriter));
  474. }
  475. // This operator should never be called as the memory should be freed as part
  476. // of the arena destruction. It only exists to provide a matching operator
  477. // delete to the operator new so that some compilers will not complain (see
  478. // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
  479. // there are no tests catching the compiler warning.
  480. static void operator delete(void*, void*) { GPR_CODEGEN_ASSERT(false); }
  481. void StartCall(void* tag) override {
  482. GPR_CODEGEN_ASSERT(!started_);
  483. started_ = true;
  484. StartCallInternal(tag);
  485. }
  486. /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method
  487. /// for semantics of this method.
  488. ///
  489. /// Side effect:
  490. /// - upon receiving initial metadata from the server, the \a ClientContext
  491. /// is updated with it, and then the receiving initial metadata can
  492. /// be accessed through this \a ClientContext.
  493. void ReadInitialMetadata(void* tag) override {
  494. GPR_CODEGEN_ASSERT(started_);
  495. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  496. meta_ops_.set_output_tag(tag);
  497. meta_ops_.RecvInitialMetadata(context_);
  498. call_.PerformOps(&meta_ops_);
  499. }
  500. void Read(R* msg, void* tag) override {
  501. GPR_CODEGEN_ASSERT(started_);
  502. read_ops_.set_output_tag(tag);
  503. if (!context_->initial_metadata_received_) {
  504. read_ops_.RecvInitialMetadata(context_);
  505. }
  506. read_ops_.RecvMessage(msg);
  507. call_.PerformOps(&read_ops_);
  508. }
  509. void Write(const W& msg, void* tag) override {
  510. GPR_CODEGEN_ASSERT(started_);
  511. write_ops_.set_output_tag(tag);
  512. // TODO(ctiller): don't assert
  513. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  514. call_.PerformOps(&write_ops_);
  515. }
  516. void Write(const W& msg, grpc::WriteOptions options, void* tag) override {
  517. GPR_CODEGEN_ASSERT(started_);
  518. write_ops_.set_output_tag(tag);
  519. if (options.is_last_message()) {
  520. options.set_buffer_hint();
  521. write_ops_.ClientSendClose();
  522. }
  523. // TODO(ctiller): don't assert
  524. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  525. call_.PerformOps(&write_ops_);
  526. }
  527. void WritesDone(void* tag) override {
  528. GPR_CODEGEN_ASSERT(started_);
  529. write_ops_.set_output_tag(tag);
  530. write_ops_.ClientSendClose();
  531. call_.PerformOps(&write_ops_);
  532. }
  533. /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
  534. /// Side effect
  535. /// - the \a ClientContext associated with this call is updated with
  536. /// possible initial and trailing metadata sent from the server.
  537. void Finish(grpc::Status* status, void* tag) override {
  538. GPR_CODEGEN_ASSERT(started_);
  539. finish_ops_.set_output_tag(tag);
  540. if (!context_->initial_metadata_received_) {
  541. finish_ops_.RecvInitialMetadata(context_);
  542. }
  543. finish_ops_.ClientRecvStatus(context_, status);
  544. call_.PerformOps(&finish_ops_);
  545. }
  546. private:
  547. friend class internal::ClientAsyncReaderWriterFactory<W, R>;
  548. ClientAsyncReaderWriter(grpc::internal::Call call,
  549. grpc::ClientContext* context, bool start, void* tag)
  550. : context_(context), call_(call), started_(start) {
  551. if (start) {
  552. StartCallInternal(tag);
  553. } else {
  554. GPR_CODEGEN_ASSERT(tag == nullptr);
  555. }
  556. }
  557. void StartCallInternal(void* tag) {
  558. write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
  559. context_->initial_metadata_flags());
  560. // if corked bit is set in context, we just keep the initial metadata
  561. // buffered up to coalesce with later message send. No op is performed.
  562. if (!context_->initial_metadata_corked_) {
  563. write_ops_.set_output_tag(tag);
  564. call_.PerformOps(&write_ops_);
  565. }
  566. }
  567. grpc::ClientContext* context_;
  568. grpc::internal::Call call_;
  569. bool started_;
  570. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata>
  571. meta_ops_;
  572. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  573. grpc::internal::CallOpRecvMessage<R>>
  574. read_ops_;
  575. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  576. grpc::internal::CallOpSendMessage,
  577. grpc::internal::CallOpClientSendClose>
  578. write_ops_;
  579. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  580. grpc::internal::CallOpClientRecvStatus>
  581. finish_ops_;
  582. };
  583. template <class W, class R>
  584. class ServerAsyncReaderInterface
  585. : public grpc::internal::ServerAsyncStreamingInterface,
  586. public internal::AsyncReaderInterface<R> {
  587. public:
  588. /// Indicate that the stream is to be finished with a certain status code
  589. /// and also send out \a msg response to the client.
  590. /// Request notification for when the server has sent the response and the
  591. /// appropriate signals to the client to end the call.
  592. /// Should not be used concurrently with other operations.
  593. ///
  594. /// It is appropriate to call this method when:
  595. /// * all messages from the client have been received (either known
  596. /// implictly, or explicitly because a previous
  597. /// \a AsyncReaderInterface::Read operation with a non-ok result,
  598. /// e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false').
  599. ///
  600. /// This operation will end when the server has finished sending out initial
  601. /// metadata (if not sent already), response message, and status, or if
  602. /// some failure occurred when trying to do so.
  603. ///
  604. /// gRPC doesn't take ownership or a reference to \a msg or \a status, so it
  605. /// is safe to deallocate once Finish returns.
  606. ///
  607. /// \param[in] tag Tag identifying this request.
  608. /// \param[in] status To be sent to the client as the result of this call.
  609. /// \param[in] msg To be sent to the client as the response for this call.
  610. virtual void Finish(const W& msg, const grpc::Status& status, void* tag) = 0;
  611. /// Indicate that the stream is to be finished with a certain
  612. /// non-OK status code.
  613. /// Request notification for when the server has sent the appropriate
  614. /// signals to the client to end the call.
  615. /// Should not be used concurrently with other operations.
  616. ///
  617. /// This call is meant to end the call with some error, and can be called at
  618. /// any point that the server would like to "fail" the call (though note
  619. /// this shouldn't be called concurrently with any other "sending" call, like
  620. /// \a AsyncWriterInterface::Write).
  621. ///
  622. /// This operation will end when the server has finished sending out initial
  623. /// metadata (if not sent already), and status, or if some failure occurred
  624. /// when trying to do so.
  625. ///
  626. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  627. /// to deallocate once FinishWithError returns.
  628. ///
  629. /// \param[in] tag Tag identifying this request.
  630. /// \param[in] status To be sent to the client as the result of this call.
  631. /// - Note: \a status must have a non-OK code.
  632. virtual void FinishWithError(const grpc::Status& status, void* tag) = 0;
  633. };
  634. /// Async server-side API for doing client-streaming RPCs,
  635. /// where the incoming message stream from the client has messages of type \a R,
  636. /// and the single response message sent from the server is type \a W.
  637. template <class W, class R>
  638. class ServerAsyncReader final : public ServerAsyncReaderInterface<W, R> {
  639. public:
  640. explicit ServerAsyncReader(grpc::ServerContext* ctx)
  641. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  642. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  643. ///
  644. /// Implicit input parameter:
  645. /// - The initial metadata that will be sent to the client from this op will
  646. /// be taken from the \a ServerContext associated with the call.
  647. void SendInitialMetadata(void* tag) override {
  648. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  649. meta_ops_.set_output_tag(tag);
  650. meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  651. ctx_->initial_metadata_flags());
  652. if (ctx_->compression_level_set()) {
  653. meta_ops_.set_compression_level(ctx_->compression_level());
  654. }
  655. ctx_->sent_initial_metadata_ = true;
  656. call_.PerformOps(&meta_ops_);
  657. }
  658. void Read(R* msg, void* tag) override {
  659. read_ops_.set_output_tag(tag);
  660. read_ops_.RecvMessage(msg);
  661. call_.PerformOps(&read_ops_);
  662. }
  663. /// See the \a ServerAsyncReaderInterface.Read method for semantics
  664. ///
  665. /// Side effect:
  666. /// - also sends initial metadata if not alreay sent.
  667. /// - uses the \a ServerContext associated with this call to send possible
  668. /// initial and trailing metadata.
  669. ///
  670. /// Note: \a msg is not sent if \a status has a non-OK code.
  671. ///
  672. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  673. /// is safe to deallocate once Finish returns.
  674. void Finish(const W& msg, const grpc::Status& status, void* tag) override {
  675. finish_ops_.set_output_tag(tag);
  676. if (!ctx_->sent_initial_metadata_) {
  677. finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  678. ctx_->initial_metadata_flags());
  679. if (ctx_->compression_level_set()) {
  680. finish_ops_.set_compression_level(ctx_->compression_level());
  681. }
  682. ctx_->sent_initial_metadata_ = true;
  683. }
  684. // The response is dropped if the status is not OK.
  685. if (status.ok()) {
  686. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_,
  687. finish_ops_.SendMessage(msg));
  688. } else {
  689. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  690. }
  691. call_.PerformOps(&finish_ops_);
  692. }
  693. /// See the \a ServerAsyncReaderInterface.Read method for semantics
  694. ///
  695. /// Side effect:
  696. /// - also sends initial metadata if not alreay sent.
  697. /// - uses the \a ServerContext associated with this call to send possible
  698. /// initial and trailing metadata.
  699. ///
  700. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  701. /// to deallocate once FinishWithError returns.
  702. void FinishWithError(const grpc::Status& status, void* tag) override {
  703. GPR_CODEGEN_ASSERT(!status.ok());
  704. finish_ops_.set_output_tag(tag);
  705. if (!ctx_->sent_initial_metadata_) {
  706. finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  707. ctx_->initial_metadata_flags());
  708. if (ctx_->compression_level_set()) {
  709. finish_ops_.set_compression_level(ctx_->compression_level());
  710. }
  711. ctx_->sent_initial_metadata_ = true;
  712. }
  713. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  714. call_.PerformOps(&finish_ops_);
  715. }
  716. private:
  717. void BindCall(grpc::internal::Call* call) override { call_ = *call; }
  718. grpc::internal::Call call_;
  719. grpc::ServerContext* ctx_;
  720. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata>
  721. meta_ops_;
  722. grpc::internal::CallOpSet<grpc::internal::CallOpRecvMessage<R>> read_ops_;
  723. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  724. grpc::internal::CallOpSendMessage,
  725. grpc::internal::CallOpServerSendStatus>
  726. finish_ops_;
  727. };
  728. template <class W>
  729. class ServerAsyncWriterInterface
  730. : public grpc::internal::ServerAsyncStreamingInterface,
  731. public internal::AsyncWriterInterface<W> {
  732. public:
  733. /// Indicate that the stream is to be finished with a certain status code.
  734. /// Request notification for when the server has sent the appropriate
  735. /// signals to the client to end the call.
  736. /// Should not be used concurrently with other operations.
  737. ///
  738. /// It is appropriate to call this method when either:
  739. /// * all messages from the client have been received (either known
  740. /// implictly, or explicitly because a previous \a
  741. /// AsyncReaderInterface::Read operation with a non-ok
  742. /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'.
  743. /// * it is desired to end the call early with some non-OK status code.
  744. ///
  745. /// This operation will end when the server has finished sending out initial
  746. /// metadata (if not sent already), response message, and status, or if
  747. /// some failure occurred when trying to do so.
  748. ///
  749. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  750. /// to deallocate once Finish returns.
  751. ///
  752. /// \param[in] tag Tag identifying this request.
  753. /// \param[in] status To be sent to the client as the result of this call.
  754. virtual void Finish(const grpc::Status& status, void* tag) = 0;
  755. /// Request the writing of \a msg and coalesce it with trailing metadata which
  756. /// contains \a status, using WriteOptions options with
  757. /// identifying tag \a tag.
  758. ///
  759. /// WriteAndFinish is equivalent of performing WriteLast and Finish
  760. /// in a single step.
  761. ///
  762. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  763. /// is safe to deallocate once WriteAndFinish returns.
  764. ///
  765. /// \param[in] msg The message to be written.
  766. /// \param[in] options The WriteOptions to be used to write this message.
  767. /// \param[in] status The Status that server returns to client.
  768. /// \param[in] tag The tag identifying the operation.
  769. virtual void WriteAndFinish(const W& msg, grpc::WriteOptions options,
  770. const grpc::Status& status, void* tag) = 0;
  771. };
  772. /// Async server-side API for doing server streaming RPCs,
  773. /// where the outgoing message stream from the server has messages of type \a W.
  774. template <class W>
  775. class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
  776. public:
  777. explicit ServerAsyncWriter(grpc::ServerContext* ctx)
  778. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  779. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  780. ///
  781. /// Implicit input parameter:
  782. /// - The initial metadata that will be sent to the client from this op will
  783. /// be taken from the \a ServerContext associated with the call.
  784. ///
  785. /// \param[in] tag Tag identifying this request.
  786. void SendInitialMetadata(void* tag) override {
  787. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  788. meta_ops_.set_output_tag(tag);
  789. meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  790. ctx_->initial_metadata_flags());
  791. if (ctx_->compression_level_set()) {
  792. meta_ops_.set_compression_level(ctx_->compression_level());
  793. }
  794. ctx_->sent_initial_metadata_ = true;
  795. call_.PerformOps(&meta_ops_);
  796. }
  797. void Write(const W& msg, void* tag) override {
  798. write_ops_.set_output_tag(tag);
  799. EnsureInitialMetadataSent(&write_ops_);
  800. // TODO(ctiller): don't assert
  801. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  802. call_.PerformOps(&write_ops_);
  803. }
  804. void Write(const W& msg, grpc::WriteOptions options, void* tag) override {
  805. write_ops_.set_output_tag(tag);
  806. if (options.is_last_message()) {
  807. options.set_buffer_hint();
  808. }
  809. EnsureInitialMetadataSent(&write_ops_);
  810. // TODO(ctiller): don't assert
  811. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  812. call_.PerformOps(&write_ops_);
  813. }
  814. /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics.
  815. ///
  816. /// Implicit input parameter:
  817. /// - the \a ServerContext associated with this call is used
  818. /// for sending trailing (and initial) metadata to the client.
  819. ///
  820. /// Note: \a status must have an OK code.
  821. ///
  822. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  823. /// is safe to deallocate once WriteAndFinish returns.
  824. void WriteAndFinish(const W& msg, grpc::WriteOptions options,
  825. const grpc::Status& status, void* tag) override {
  826. write_ops_.set_output_tag(tag);
  827. EnsureInitialMetadataSent(&write_ops_);
  828. options.set_buffer_hint();
  829. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  830. write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  831. call_.PerformOps(&write_ops_);
  832. }
  833. /// See the \a ServerAsyncWriterInterface.Finish method for semantics.
  834. ///
  835. /// Implicit input parameter:
  836. /// - the \a ServerContext associated with this call is used for sending
  837. /// trailing (and initial if not already sent) metadata to the client.
  838. ///
  839. /// Note: there are no restrictions are the code of
  840. /// \a status,it may be non-OK
  841. ///
  842. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  843. /// to deallocate once Finish returns.
  844. void Finish(const grpc::Status& status, void* tag) override {
  845. finish_ops_.set_output_tag(tag);
  846. EnsureInitialMetadataSent(&finish_ops_);
  847. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  848. call_.PerformOps(&finish_ops_);
  849. }
  850. private:
  851. void BindCall(grpc::internal::Call* call) override { call_ = *call; }
  852. template <class T>
  853. void EnsureInitialMetadataSent(T* ops) {
  854. if (!ctx_->sent_initial_metadata_) {
  855. ops->SendInitialMetadata(&ctx_->initial_metadata_,
  856. ctx_->initial_metadata_flags());
  857. if (ctx_->compression_level_set()) {
  858. ops->set_compression_level(ctx_->compression_level());
  859. }
  860. ctx_->sent_initial_metadata_ = true;
  861. }
  862. }
  863. grpc::internal::Call call_;
  864. grpc::ServerContext* ctx_;
  865. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata>
  866. meta_ops_;
  867. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  868. grpc::internal::CallOpSendMessage,
  869. grpc::internal::CallOpServerSendStatus>
  870. write_ops_;
  871. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  872. grpc::internal::CallOpServerSendStatus>
  873. finish_ops_;
  874. };
  875. /// Server-side interface for asynchronous bi-directional streaming.
  876. template <class W, class R>
  877. class ServerAsyncReaderWriterInterface
  878. : public grpc::internal::ServerAsyncStreamingInterface,
  879. public internal::AsyncWriterInterface<W>,
  880. public internal::AsyncReaderInterface<R> {
  881. public:
  882. /// Indicate that the stream is to be finished with a certain status code.
  883. /// Request notification for when the server has sent the appropriate
  884. /// signals to the client to end the call.
  885. /// Should not be used concurrently with other operations.
  886. ///
  887. /// It is appropriate to call this method when either:
  888. /// * all messages from the client have been received (either known
  889. /// implictly, or explicitly because a previous \a
  890. /// AsyncReaderInterface::Read operation
  891. /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok'
  892. /// with 'false'.
  893. /// * it is desired to end the call early with some non-OK status code.
  894. ///
  895. /// This operation will end when the server has finished sending out initial
  896. /// metadata (if not sent already), response message, and status, or if some
  897. /// failure occurred when trying to do so.
  898. ///
  899. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  900. /// to deallocate once Finish returns.
  901. ///
  902. /// \param[in] tag Tag identifying this request.
  903. /// \param[in] status To be sent to the client as the result of this call.
  904. virtual void Finish(const grpc::Status& status, void* tag) = 0;
  905. /// Request the writing of \a msg and coalesce it with trailing metadata which
  906. /// contains \a status, using WriteOptions options with
  907. /// identifying tag \a tag.
  908. ///
  909. /// WriteAndFinish is equivalent of performing WriteLast and Finish in a
  910. /// single step.
  911. ///
  912. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  913. /// is safe to deallocate once WriteAndFinish returns.
  914. ///
  915. /// \param[in] msg The message to be written.
  916. /// \param[in] options The WriteOptions to be used to write this message.
  917. /// \param[in] status The Status that server returns to client.
  918. /// \param[in] tag The tag identifying the operation.
  919. virtual void WriteAndFinish(const W& msg, grpc::WriteOptions options,
  920. const grpc::Status& status, void* tag) = 0;
  921. };
  922. /// Async server-side API for doing bidirectional streaming RPCs,
  923. /// where the incoming message stream coming from the client has messages of
  924. /// type \a R, and the outgoing message stream coming from the server has
  925. /// messages of type \a W.
  926. template <class W, class R>
  927. class ServerAsyncReaderWriter final
  928. : public ServerAsyncReaderWriterInterface<W, R> {
  929. public:
  930. explicit ServerAsyncReaderWriter(grpc::ServerContext* ctx)
  931. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  932. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  933. ///
  934. /// Implicit input parameter:
  935. /// - The initial metadata that will be sent to the client from this op will
  936. /// be taken from the \a ServerContext associated with the call.
  937. ///
  938. /// \param[in] tag Tag identifying this request.
  939. void SendInitialMetadata(void* tag) override {
  940. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  941. meta_ops_.set_output_tag(tag);
  942. meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  943. ctx_->initial_metadata_flags());
  944. if (ctx_->compression_level_set()) {
  945. meta_ops_.set_compression_level(ctx_->compression_level());
  946. }
  947. ctx_->sent_initial_metadata_ = true;
  948. call_.PerformOps(&meta_ops_);
  949. }
  950. void Read(R* msg, void* tag) override {
  951. read_ops_.set_output_tag(tag);
  952. read_ops_.RecvMessage(msg);
  953. call_.PerformOps(&read_ops_);
  954. }
  955. void Write(const W& msg, void* tag) override {
  956. write_ops_.set_output_tag(tag);
  957. EnsureInitialMetadataSent(&write_ops_);
  958. // TODO(ctiller): don't assert
  959. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  960. call_.PerformOps(&write_ops_);
  961. }
  962. void Write(const W& msg, grpc::WriteOptions options, void* tag) override {
  963. write_ops_.set_output_tag(tag);
  964. if (options.is_last_message()) {
  965. options.set_buffer_hint();
  966. }
  967. EnsureInitialMetadataSent(&write_ops_);
  968. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  969. call_.PerformOps(&write_ops_);
  970. }
  971. /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish
  972. /// method for semantics.
  973. ///
  974. /// Implicit input parameter:
  975. /// - the \a ServerContext associated with this call is used
  976. /// for sending trailing (and initial) metadata to the client.
  977. ///
  978. /// Note: \a status must have an OK code.
  979. //
  980. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  981. /// is safe to deallocate once WriteAndFinish returns.
  982. void WriteAndFinish(const W& msg, grpc::WriteOptions options,
  983. const grpc::Status& status, void* tag) override {
  984. write_ops_.set_output_tag(tag);
  985. EnsureInitialMetadataSent(&write_ops_);
  986. options.set_buffer_hint();
  987. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  988. write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  989. call_.PerformOps(&write_ops_);
  990. }
  991. /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics.
  992. ///
  993. /// Implicit input parameter:
  994. /// - the \a ServerContext associated with this call is used for sending
  995. /// trailing (and initial if not already sent) metadata to the client.
  996. ///
  997. /// Note: there are no restrictions are the code of \a status,
  998. /// it may be non-OK
  999. //
  1000. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  1001. /// to deallocate once Finish returns.
  1002. void Finish(const grpc::Status& status, void* tag) override {
  1003. finish_ops_.set_output_tag(tag);
  1004. EnsureInitialMetadataSent(&finish_ops_);
  1005. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  1006. call_.PerformOps(&finish_ops_);
  1007. }
  1008. private:
  1009. friend class grpc::Server;
  1010. void BindCall(grpc::internal::Call* call) override { call_ = *call; }
  1011. template <class T>
  1012. void EnsureInitialMetadataSent(T* ops) {
  1013. if (!ctx_->sent_initial_metadata_) {
  1014. ops->SendInitialMetadata(&ctx_->initial_metadata_,
  1015. ctx_->initial_metadata_flags());
  1016. if (ctx_->compression_level_set()) {
  1017. ops->set_compression_level(ctx_->compression_level());
  1018. }
  1019. ctx_->sent_initial_metadata_ = true;
  1020. }
  1021. }
  1022. grpc::internal::Call call_;
  1023. grpc::ServerContext* ctx_;
  1024. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata>
  1025. meta_ops_;
  1026. grpc::internal::CallOpSet<grpc::internal::CallOpRecvMessage<R>> read_ops_;
  1027. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  1028. grpc::internal::CallOpSendMessage,
  1029. grpc::internal::CallOpServerSendStatus>
  1030. write_ops_;
  1031. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  1032. grpc::internal::CallOpServerSendStatus>
  1033. finish_ops_;
  1034. };
  1035. } // namespace grpc
  1036. #endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H