async_stream.h 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  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,
  305. R* response, 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,
  611. void* tag) = 0;
  612. /// Indicate that the stream is to be finished with a certain
  613. /// non-OK status code.
  614. /// Request notification for when the server has sent the appropriate
  615. /// signals to the client to end the call.
  616. /// Should not be used concurrently with other operations.
  617. ///
  618. /// This call is meant to end the call with some error, and can be called at
  619. /// any point that the server would like to "fail" the call (though note
  620. /// this shouldn't be called concurrently with any other "sending" call, like
  621. /// \a AsyncWriterInterface::Write).
  622. ///
  623. /// This operation will end when the server has finished sending out initial
  624. /// metadata (if not sent already), and status, or if some failure occurred
  625. /// when trying to do so.
  626. ///
  627. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  628. /// to deallocate once FinishWithError returns.
  629. ///
  630. /// \param[in] tag Tag identifying this request.
  631. /// \param[in] status To be sent to the client as the result of this call.
  632. /// - Note: \a status must have a non-OK code.
  633. virtual void FinishWithError(const ::grpc::Status& status, void* tag) = 0;
  634. };
  635. /// Async server-side API for doing client-streaming RPCs,
  636. /// where the incoming message stream from the client has messages of type \a R,
  637. /// and the single response message sent from the server is type \a W.
  638. template <class W, class R>
  639. class ServerAsyncReader final : public ServerAsyncReaderInterface<W, R> {
  640. public:
  641. explicit ServerAsyncReader(::grpc::ServerContext* ctx)
  642. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  643. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  644. ///
  645. /// Implicit input parameter:
  646. /// - The initial metadata that will be sent to the client from this op will
  647. /// be taken from the \a ServerContext associated with the call.
  648. void SendInitialMetadata(void* tag) override {
  649. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  650. meta_ops_.set_output_tag(tag);
  651. meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  652. ctx_->initial_metadata_flags());
  653. if (ctx_->compression_level_set()) {
  654. meta_ops_.set_compression_level(ctx_->compression_level());
  655. }
  656. ctx_->sent_initial_metadata_ = true;
  657. call_.PerformOps(&meta_ops_);
  658. }
  659. void Read(R* msg, void* tag) override {
  660. read_ops_.set_output_tag(tag);
  661. read_ops_.RecvMessage(msg);
  662. call_.PerformOps(&read_ops_);
  663. }
  664. /// See the \a ServerAsyncReaderInterface.Read method for semantics
  665. ///
  666. /// Side effect:
  667. /// - also sends initial metadata if not alreay sent.
  668. /// - uses the \a ServerContext associated with this call to send possible
  669. /// initial and trailing metadata.
  670. ///
  671. /// Note: \a msg is not sent if \a status has a non-OK code.
  672. ///
  673. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  674. /// is safe to deallocate once Finish returns.
  675. void Finish(const W& msg, const ::grpc::Status& status, void* tag) override {
  676. finish_ops_.set_output_tag(tag);
  677. if (!ctx_->sent_initial_metadata_) {
  678. finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  679. ctx_->initial_metadata_flags());
  680. if (ctx_->compression_level_set()) {
  681. finish_ops_.set_compression_level(ctx_->compression_level());
  682. }
  683. ctx_->sent_initial_metadata_ = true;
  684. }
  685. // The response is dropped if the status is not OK.
  686. if (status.ok()) {
  687. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_,
  688. finish_ops_.SendMessage(msg));
  689. } else {
  690. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  691. }
  692. call_.PerformOps(&finish_ops_);
  693. }
  694. /// See the \a ServerAsyncReaderInterface.Read method for semantics
  695. ///
  696. /// Side effect:
  697. /// - also sends initial metadata if not alreay sent.
  698. /// - uses the \a ServerContext associated with this call to send possible
  699. /// initial and trailing metadata.
  700. ///
  701. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  702. /// to deallocate once FinishWithError returns.
  703. void FinishWithError(const ::grpc::Status& status, void* tag) override {
  704. GPR_CODEGEN_ASSERT(!status.ok());
  705. finish_ops_.set_output_tag(tag);
  706. if (!ctx_->sent_initial_metadata_) {
  707. finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  708. ctx_->initial_metadata_flags());
  709. if (ctx_->compression_level_set()) {
  710. finish_ops_.set_compression_level(ctx_->compression_level());
  711. }
  712. ctx_->sent_initial_metadata_ = true;
  713. }
  714. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  715. call_.PerformOps(&finish_ops_);
  716. }
  717. private:
  718. void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
  719. ::grpc::internal::Call call_;
  720. ::grpc::ServerContext* ctx_;
  721. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
  722. meta_ops_;
  723. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
  724. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  725. ::grpc::internal::CallOpSendMessage,
  726. ::grpc::internal::CallOpServerSendStatus>
  727. finish_ops_;
  728. };
  729. template <class W>
  730. class ServerAsyncWriterInterface
  731. : public ::grpc::internal::ServerAsyncStreamingInterface,
  732. public internal::AsyncWriterInterface<W> {
  733. public:
  734. /// Indicate that the stream is to be finished with a certain status code.
  735. /// Request notification for when the server has sent the appropriate
  736. /// signals to the client to end the call.
  737. /// Should not be used concurrently with other operations.
  738. ///
  739. /// It is appropriate to call this method when either:
  740. /// * all messages from the client have been received (either known
  741. /// implictly, or explicitly because a previous \a
  742. /// AsyncReaderInterface::Read operation with a non-ok
  743. /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'.
  744. /// * it is desired to end the call early with some non-OK status code.
  745. ///
  746. /// This operation will end when the server has finished sending out initial
  747. /// metadata (if not sent already), response message, and status, or if
  748. /// some failure occurred when trying to do so.
  749. ///
  750. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  751. /// to deallocate once Finish returns.
  752. ///
  753. /// \param[in] tag Tag identifying this request.
  754. /// \param[in] status To be sent to the client as the result of this call.
  755. virtual void Finish(const ::grpc::Status& status, void* tag) = 0;
  756. /// Request the writing of \a msg and coalesce it with trailing metadata which
  757. /// contains \a status, using WriteOptions options with
  758. /// identifying tag \a tag.
  759. ///
  760. /// WriteAndFinish is equivalent of performing WriteLast and Finish
  761. /// in a single step.
  762. ///
  763. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  764. /// is safe to deallocate once WriteAndFinish returns.
  765. ///
  766. /// \param[in] msg The message to be written.
  767. /// \param[in] options The WriteOptions to be used to write this message.
  768. /// \param[in] status The Status that server returns to client.
  769. /// \param[in] tag The tag identifying the operation.
  770. virtual void WriteAndFinish(const W& msg, ::grpc::WriteOptions options,
  771. const ::grpc::Status& status, void* tag) = 0;
  772. };
  773. /// Async server-side API for doing server streaming RPCs,
  774. /// where the outgoing message stream from the server has messages of type \a W.
  775. template <class W>
  776. class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
  777. public:
  778. explicit ServerAsyncWriter(::grpc::ServerContext* ctx)
  779. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  780. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  781. ///
  782. /// Implicit input parameter:
  783. /// - The initial metadata that will be sent to the client from this op will
  784. /// be taken from the \a ServerContext associated with the call.
  785. ///
  786. /// \param[in] tag Tag identifying this request.
  787. void SendInitialMetadata(void* tag) override {
  788. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  789. meta_ops_.set_output_tag(tag);
  790. meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  791. ctx_->initial_metadata_flags());
  792. if (ctx_->compression_level_set()) {
  793. meta_ops_.set_compression_level(ctx_->compression_level());
  794. }
  795. ctx_->sent_initial_metadata_ = true;
  796. call_.PerformOps(&meta_ops_);
  797. }
  798. void Write(const W& msg, void* tag) override {
  799. write_ops_.set_output_tag(tag);
  800. EnsureInitialMetadataSent(&write_ops_);
  801. // TODO(ctiller): don't assert
  802. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  803. call_.PerformOps(&write_ops_);
  804. }
  805. void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override {
  806. write_ops_.set_output_tag(tag);
  807. if (options.is_last_message()) {
  808. options.set_buffer_hint();
  809. }
  810. EnsureInitialMetadataSent(&write_ops_);
  811. // TODO(ctiller): don't assert
  812. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  813. call_.PerformOps(&write_ops_);
  814. }
  815. /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics.
  816. ///
  817. /// Implicit input parameter:
  818. /// - the \a ServerContext associated with this call is used
  819. /// for sending trailing (and initial) metadata to the client.
  820. ///
  821. /// Note: \a status must have an OK code.
  822. ///
  823. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  824. /// is safe to deallocate once WriteAndFinish returns.
  825. void WriteAndFinish(const W& msg, ::grpc::WriteOptions options,
  826. const ::grpc::Status& status, void* tag) override {
  827. write_ops_.set_output_tag(tag);
  828. EnsureInitialMetadataSent(&write_ops_);
  829. options.set_buffer_hint();
  830. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  831. write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  832. call_.PerformOps(&write_ops_);
  833. }
  834. /// See the \a ServerAsyncWriterInterface.Finish method for semantics.
  835. ///
  836. /// Implicit input parameter:
  837. /// - the \a ServerContext associated with this call is used for sending
  838. /// trailing (and initial if not already sent) metadata to the client.
  839. ///
  840. /// Note: there are no restrictions are the code of
  841. /// \a status,it may be non-OK
  842. ///
  843. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  844. /// to deallocate once Finish returns.
  845. void Finish(const ::grpc::Status& status, void* tag) override {
  846. finish_ops_.set_output_tag(tag);
  847. EnsureInitialMetadataSent(&finish_ops_);
  848. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  849. call_.PerformOps(&finish_ops_);
  850. }
  851. private:
  852. void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
  853. template <class T>
  854. void EnsureInitialMetadataSent(T* ops) {
  855. if (!ctx_->sent_initial_metadata_) {
  856. ops->SendInitialMetadata(&ctx_->initial_metadata_,
  857. ctx_->initial_metadata_flags());
  858. if (ctx_->compression_level_set()) {
  859. ops->set_compression_level(ctx_->compression_level());
  860. }
  861. ctx_->sent_initial_metadata_ = true;
  862. }
  863. }
  864. ::grpc::internal::Call call_;
  865. ::grpc::ServerContext* ctx_;
  866. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
  867. meta_ops_;
  868. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  869. ::grpc::internal::CallOpSendMessage,
  870. ::grpc::internal::CallOpServerSendStatus>
  871. write_ops_;
  872. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  873. ::grpc::internal::CallOpServerSendStatus>
  874. finish_ops_;
  875. };
  876. /// Server-side interface for asynchronous bi-directional streaming.
  877. template <class W, class R>
  878. class ServerAsyncReaderWriterInterface
  879. : public ::grpc::internal::ServerAsyncStreamingInterface,
  880. public internal::AsyncWriterInterface<W>,
  881. public internal::AsyncReaderInterface<R> {
  882. public:
  883. /// Indicate that the stream is to be finished with a certain status code.
  884. /// Request notification for when the server has sent the appropriate
  885. /// signals to the client to end the call.
  886. /// Should not be used concurrently with other operations.
  887. ///
  888. /// It is appropriate to call this method when either:
  889. /// * all messages from the client have been received (either known
  890. /// implictly, or explicitly because a previous \a
  891. /// AsyncReaderInterface::Read operation
  892. /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok'
  893. /// with 'false'.
  894. /// * it is desired to end the call early with some non-OK status code.
  895. ///
  896. /// This operation will end when the server has finished sending out initial
  897. /// metadata (if not sent already), response message, and status, or if some
  898. /// failure occurred when trying to do so.
  899. ///
  900. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  901. /// to deallocate once Finish returns.
  902. ///
  903. /// \param[in] tag Tag identifying this request.
  904. /// \param[in] status To be sent to the client as the result of this call.
  905. virtual void Finish(const ::grpc::Status& status, void* tag) = 0;
  906. /// Request the writing of \a msg and coalesce it with trailing metadata which
  907. /// contains \a status, using WriteOptions options with
  908. /// identifying tag \a tag.
  909. ///
  910. /// WriteAndFinish is equivalent of performing WriteLast and Finish in a
  911. /// single step.
  912. ///
  913. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  914. /// is safe to deallocate once WriteAndFinish returns.
  915. ///
  916. /// \param[in] msg The message to be written.
  917. /// \param[in] options The WriteOptions to be used to write this message.
  918. /// \param[in] status The Status that server returns to client.
  919. /// \param[in] tag The tag identifying the operation.
  920. virtual void WriteAndFinish(const W& msg, ::grpc::WriteOptions options,
  921. const ::grpc::Status& status, void* tag) = 0;
  922. };
  923. /// Async server-side API for doing bidirectional streaming RPCs,
  924. /// where the incoming message stream coming from the client has messages of
  925. /// type \a R, and the outgoing message stream coming from the server has
  926. /// messages of type \a W.
  927. template <class W, class R>
  928. class ServerAsyncReaderWriter final
  929. : public ServerAsyncReaderWriterInterface<W, R> {
  930. public:
  931. explicit ServerAsyncReaderWriter(::grpc::ServerContext* ctx)
  932. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  933. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  934. ///
  935. /// Implicit input parameter:
  936. /// - The initial metadata that will be sent to the client from this op will
  937. /// be taken from the \a ServerContext associated with the call.
  938. ///
  939. /// \param[in] tag Tag identifying this request.
  940. void SendInitialMetadata(void* tag) override {
  941. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  942. meta_ops_.set_output_tag(tag);
  943. meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  944. ctx_->initial_metadata_flags());
  945. if (ctx_->compression_level_set()) {
  946. meta_ops_.set_compression_level(ctx_->compression_level());
  947. }
  948. ctx_->sent_initial_metadata_ = true;
  949. call_.PerformOps(&meta_ops_);
  950. }
  951. void Read(R* msg, void* tag) override {
  952. read_ops_.set_output_tag(tag);
  953. read_ops_.RecvMessage(msg);
  954. call_.PerformOps(&read_ops_);
  955. }
  956. void Write(const W& msg, void* tag) override {
  957. write_ops_.set_output_tag(tag);
  958. EnsureInitialMetadataSent(&write_ops_);
  959. // TODO(ctiller): don't assert
  960. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  961. call_.PerformOps(&write_ops_);
  962. }
  963. void Write(const W& msg, ::grpc::WriteOptions options, void* tag) override {
  964. write_ops_.set_output_tag(tag);
  965. if (options.is_last_message()) {
  966. options.set_buffer_hint();
  967. }
  968. EnsureInitialMetadataSent(&write_ops_);
  969. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  970. call_.PerformOps(&write_ops_);
  971. }
  972. /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish
  973. /// method for semantics.
  974. ///
  975. /// Implicit input parameter:
  976. /// - the \a ServerContext associated with this call is used
  977. /// for sending trailing (and initial) metadata to the client.
  978. ///
  979. /// Note: \a status must have an OK code.
  980. //
  981. /// gRPC doesn't take ownership or a reference to \a msg and \a status, so it
  982. /// is safe to deallocate once WriteAndFinish returns.
  983. void WriteAndFinish(const W& msg, ::grpc::WriteOptions options,
  984. const ::grpc::Status& status, void* tag) override {
  985. write_ops_.set_output_tag(tag);
  986. EnsureInitialMetadataSent(&write_ops_);
  987. options.set_buffer_hint();
  988. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  989. write_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  990. call_.PerformOps(&write_ops_);
  991. }
  992. /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics.
  993. ///
  994. /// Implicit input parameter:
  995. /// - the \a ServerContext associated with this call is used for sending
  996. /// trailing (and initial if not already sent) metadata to the client.
  997. ///
  998. /// Note: there are no restrictions are the code of \a status,
  999. /// it may be non-OK
  1000. //
  1001. /// gRPC doesn't take ownership or a reference to \a status, so it is safe to
  1002. /// to deallocate once Finish returns.
  1003. void Finish(const ::grpc::Status& status, void* tag) override {
  1004. finish_ops_.set_output_tag(tag);
  1005. EnsureInitialMetadataSent(&finish_ops_);
  1006. finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, status);
  1007. call_.PerformOps(&finish_ops_);
  1008. }
  1009. private:
  1010. friend class ::grpc::Server;
  1011. void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
  1012. template <class T>
  1013. void EnsureInitialMetadataSent(T* ops) {
  1014. if (!ctx_->sent_initial_metadata_) {
  1015. ops->SendInitialMetadata(&ctx_->initial_metadata_,
  1016. ctx_->initial_metadata_flags());
  1017. if (ctx_->compression_level_set()) {
  1018. ops->set_compression_level(ctx_->compression_level());
  1019. }
  1020. ctx_->sent_initial_metadata_ = true;
  1021. }
  1022. }
  1023. ::grpc::internal::Call call_;
  1024. ::grpc::ServerContext* ctx_;
  1025. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
  1026. meta_ops_;
  1027. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
  1028. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  1029. ::grpc::internal::CallOpSendMessage,
  1030. ::grpc::internal::CallOpServerSendStatus>
  1031. write_ops_;
  1032. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  1033. ::grpc::internal::CallOpServerSendStatus>
  1034. finish_ops_;
  1035. };
  1036. } // namespace grpc
  1037. #endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H