call.c 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757
  1. /*
  2. *
  3. * Copyright 2015, Google Inc.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are
  8. * met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above
  13. * copyright notice, this list of conditions and the following disclaimer
  14. * in the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of Google Inc. nor the names of its
  17. * contributors may be used to endorse or promote products derived from
  18. * this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. */
  33. #include <assert.h>
  34. #include <limits.h>
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <grpc/compression.h>
  39. #include <grpc/grpc.h>
  40. #include <grpc/support/alloc.h>
  41. #include <grpc/support/log.h>
  42. #include <grpc/support/slice.h>
  43. #include <grpc/support/string_util.h>
  44. #include <grpc/support/useful.h>
  45. #include "src/core/lib/channel/channel_stack.h"
  46. #include "src/core/lib/compression/algorithm_metadata.h"
  47. #include "src/core/lib/iomgr/timer.h"
  48. #include "src/core/lib/profiling/timers.h"
  49. #include "src/core/lib/support/string.h"
  50. #include "src/core/lib/surface/api_trace.h"
  51. #include "src/core/lib/surface/call.h"
  52. #include "src/core/lib/surface/channel.h"
  53. #include "src/core/lib/surface/completion_queue.h"
  54. #include "src/core/lib/transport/metadata.h"
  55. #include "src/core/lib/transport/static_metadata.h"
  56. #include "src/core/lib/transport/transport.h"
  57. /** The maximum number of concurrent batches possible.
  58. Based upon the maximum number of individually queueable ops in the batch
  59. api:
  60. - initial metadata send
  61. - message send
  62. - status/close send (depending on client/server)
  63. - initial metadata recv
  64. - message recv
  65. - status/close recv (depending on client/server) */
  66. #define MAX_CONCURRENT_BATCHES 6
  67. #define MAX_SEND_EXTRA_METADATA_COUNT 3
  68. /* Status data for a request can come from several sources; this
  69. enumerates them all, and acts as a priority sorting for which
  70. status to return to the application - earlier entries override
  71. later ones */
  72. typedef enum {
  73. /* Status came from the application layer overriding whatever
  74. the wire says */
  75. STATUS_FROM_API_OVERRIDE = 0,
  76. /* Status came from 'the wire' - or somewhere below the surface
  77. layer */
  78. STATUS_FROM_WIRE,
  79. /* Status was created by some internal channel stack operation */
  80. STATUS_FROM_CORE,
  81. /* Status came from the server sending status */
  82. STATUS_FROM_SERVER_STATUS,
  83. STATUS_SOURCE_COUNT
  84. } status_source;
  85. typedef struct {
  86. uint8_t is_set;
  87. grpc_status_code code;
  88. grpc_mdstr *details;
  89. } received_status;
  90. typedef struct batch_control {
  91. grpc_call *call;
  92. grpc_cq_completion cq_completion;
  93. grpc_closure finish_batch;
  94. void *notify_tag;
  95. gpr_refcount steps_to_complete;
  96. grpc_error *error;
  97. uint8_t send_initial_metadata;
  98. uint8_t send_message;
  99. uint8_t send_final_op;
  100. uint8_t recv_initial_metadata;
  101. uint8_t recv_message;
  102. uint8_t recv_final_op;
  103. uint8_t is_notify_tag_closure;
  104. /* TODO(ctiller): now that this is inlined, figure out how much of the above
  105. state can be eliminated */
  106. grpc_transport_stream_op op;
  107. } batch_control;
  108. struct grpc_call {
  109. grpc_completion_queue *cq;
  110. grpc_polling_entity pollent;
  111. grpc_channel *channel;
  112. grpc_call *parent;
  113. grpc_call *first_child;
  114. /* TODO(ctiller): share with cq if possible? */
  115. gpr_mu mu;
  116. /* client or server call */
  117. bool is_client;
  118. /** has grpc_call_destroy been called */
  119. bool destroy_called;
  120. /** flag indicating that cancellation is inherited */
  121. bool cancellation_is_inherited;
  122. /** bitmask of live batches */
  123. uint8_t used_batches;
  124. /** which ops are in-flight */
  125. bool sent_initial_metadata;
  126. bool sending_message;
  127. bool sent_final_op;
  128. bool received_initial_metadata;
  129. bool receiving_message;
  130. bool requested_final_op;
  131. bool received_final_op;
  132. /* have we received initial metadata */
  133. bool has_initial_md_been_received;
  134. batch_control active_batches[MAX_CONCURRENT_BATCHES];
  135. /* first idx: is_receiving, second idx: is_trailing */
  136. grpc_metadata_batch metadata_batch[2][2];
  137. /* Buffered read metadata waiting to be returned to the application.
  138. Element 0 is initial metadata, element 1 is trailing metadata. */
  139. grpc_metadata_array *buffered_metadata[2];
  140. /* Received call statuses from various sources */
  141. received_status status[STATUS_SOURCE_COUNT];
  142. /* Call data useful used for reporting. Only valid after the call has
  143. * completed */
  144. grpc_call_final_info final_info;
  145. /* Compression algorithm for *incoming* data */
  146. grpc_compression_algorithm incoming_compression_algorithm;
  147. /* Supported encodings (compression algorithms), a bitset */
  148. uint32_t encodings_accepted_by_peer;
  149. /* Contexts for various subsystems (security, tracing, ...). */
  150. grpc_call_context_element context[GRPC_CONTEXT_COUNT];
  151. /* for the client, extra metadata is initial metadata; for the
  152. server, it's trailing metadata */
  153. grpc_linked_mdelem send_extra_metadata[MAX_SEND_EXTRA_METADATA_COUNT];
  154. int send_extra_metadata_count;
  155. gpr_timespec send_deadline;
  156. /** siblings: children of the same parent form a list, and this list is
  157. protected under
  158. parent->mu */
  159. grpc_call *sibling_next;
  160. grpc_call *sibling_prev;
  161. grpc_slice_buffer_stream sending_stream;
  162. grpc_byte_stream *receiving_stream;
  163. grpc_byte_buffer **receiving_buffer;
  164. gpr_slice receiving_slice;
  165. grpc_closure receiving_slice_ready;
  166. grpc_closure receiving_stream_ready;
  167. grpc_closure receiving_initial_metadata_ready;
  168. uint32_t test_only_last_message_flags;
  169. union {
  170. struct {
  171. grpc_status_code *status;
  172. char **status_details;
  173. size_t *status_details_capacity;
  174. } client;
  175. struct {
  176. int *cancelled;
  177. } server;
  178. } final_op;
  179. void *saved_receiving_stream_ready_bctlp;
  180. };
  181. #define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1))
  182. #define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)
  183. #define CALL_ELEM_FROM_CALL(call, idx) \
  184. grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
  185. #define CALL_FROM_TOP_ELEM(top_elem) \
  186. CALL_FROM_CALL_STACK(grpc_call_stack_from_top_element(top_elem))
  187. static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
  188. grpc_transport_stream_op *op);
  189. static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
  190. grpc_status_code status,
  191. const char *description);
  192. static grpc_call_error close_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
  193. grpc_status_code status,
  194. const char *description);
  195. static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack,
  196. grpc_error *error);
  197. static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
  198. grpc_error *error);
  199. grpc_error *grpc_call_create(const grpc_call_create_args *args,
  200. grpc_call **out_call) {
  201. size_t i, j;
  202. grpc_channel_stack *channel_stack =
  203. grpc_channel_get_channel_stack(args->channel);
  204. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  205. grpc_call *call;
  206. GPR_TIMER_BEGIN("grpc_call_create", 0);
  207. call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
  208. *out_call = call;
  209. memset(call, 0, sizeof(grpc_call));
  210. gpr_mu_init(&call->mu);
  211. call->channel = args->channel;
  212. call->cq = args->cq;
  213. call->parent = args->parent_call;
  214. /* Always support no compression */
  215. GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
  216. call->is_client = args->server_transport_data == NULL;
  217. grpc_mdstr *path = NULL;
  218. if (call->is_client) {
  219. GPR_ASSERT(args->add_initial_metadata_count <
  220. MAX_SEND_EXTRA_METADATA_COUNT);
  221. for (i = 0; i < args->add_initial_metadata_count; i++) {
  222. call->send_extra_metadata[i].md = args->add_initial_metadata[i];
  223. if (args->add_initial_metadata[i]->key == GRPC_MDSTR_PATH) {
  224. path = GRPC_MDSTR_REF(args->add_initial_metadata[i]->value);
  225. }
  226. }
  227. call->send_extra_metadata_count = (int)args->add_initial_metadata_count;
  228. } else {
  229. GPR_ASSERT(args->add_initial_metadata_count == 0);
  230. call->send_extra_metadata_count = 0;
  231. }
  232. for (i = 0; i < 2; i++) {
  233. for (j = 0; j < 2; j++) {
  234. call->metadata_batch[i][j].deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
  235. }
  236. }
  237. gpr_timespec send_deadline =
  238. gpr_convert_clock_type(args->send_deadline, GPR_CLOCK_MONOTONIC);
  239. if (args->parent_call != NULL) {
  240. GRPC_CALL_INTERNAL_REF(args->parent_call, "child");
  241. GPR_ASSERT(call->is_client);
  242. GPR_ASSERT(!args->parent_call->is_client);
  243. gpr_mu_lock(&args->parent_call->mu);
  244. if (args->propagation_mask & GRPC_PROPAGATE_DEADLINE) {
  245. send_deadline = gpr_time_min(
  246. gpr_convert_clock_type(send_deadline,
  247. args->parent_call->send_deadline.clock_type),
  248. args->parent_call->send_deadline);
  249. }
  250. /* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with
  251. * GRPC_PROPAGATE_STATS_CONTEXT */
  252. /* TODO(ctiller): This should change to use the appropriate census start_op
  253. * call. */
  254. if (args->propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
  255. GPR_ASSERT(args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT);
  256. grpc_call_context_set(
  257. call, GRPC_CONTEXT_TRACING,
  258. args->parent_call->context[GRPC_CONTEXT_TRACING].value, NULL);
  259. } else {
  260. GPR_ASSERT(args->propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT);
  261. }
  262. if (args->propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
  263. call->cancellation_is_inherited = 1;
  264. }
  265. if (args->parent_call->first_child == NULL) {
  266. args->parent_call->first_child = call;
  267. call->sibling_next = call->sibling_prev = call;
  268. } else {
  269. call->sibling_next = args->parent_call->first_child;
  270. call->sibling_prev = args->parent_call->first_child->sibling_prev;
  271. call->sibling_next->sibling_prev = call->sibling_prev->sibling_next =
  272. call;
  273. }
  274. gpr_mu_unlock(&args->parent_call->mu);
  275. }
  276. call->send_deadline = send_deadline;
  277. GRPC_CHANNEL_INTERNAL_REF(args->channel, "call");
  278. /* initial refcount dropped by grpc_call_destroy */
  279. grpc_error *error =
  280. grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call,
  281. call->context, args->server_transport_data, path,
  282. send_deadline, CALL_STACK_FROM_CALL(call));
  283. if (error != GRPC_ERROR_NONE) {
  284. grpc_status_code status;
  285. const char *error_str;
  286. grpc_error_get_status(error, &status, &error_str);
  287. close_with_status(&exec_ctx, call, status, error_str);
  288. }
  289. if (args->cq != NULL) {
  290. GPR_ASSERT(
  291. args->pollset_set_alternative == NULL &&
  292. "Only one of 'cq' and 'pollset_set_alternative' should be non-NULL.");
  293. GRPC_CQ_INTERNAL_REF(args->cq, "bind");
  294. call->pollent =
  295. grpc_polling_entity_create_from_pollset(grpc_cq_pollset(args->cq));
  296. }
  297. if (args->pollset_set_alternative != NULL) {
  298. call->pollent = grpc_polling_entity_create_from_pollset_set(
  299. args->pollset_set_alternative);
  300. }
  301. if (!grpc_polling_entity_is_empty(&call->pollent)) {
  302. grpc_call_stack_set_pollset_or_pollset_set(
  303. &exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
  304. }
  305. if (path != NULL) GRPC_MDSTR_UNREF(path);
  306. grpc_exec_ctx_finish(&exec_ctx);
  307. GPR_TIMER_END("grpc_call_create", 0);
  308. return error;
  309. }
  310. void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call,
  311. grpc_completion_queue *cq) {
  312. GPR_ASSERT(cq);
  313. if (grpc_polling_entity_pollset_set(&call->pollent) != NULL) {
  314. gpr_log(GPR_ERROR, "A pollset_set is already registered for this call.");
  315. abort();
  316. }
  317. call->cq = cq;
  318. GRPC_CQ_INTERNAL_REF(cq, "bind");
  319. call->pollent = grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq));
  320. grpc_call_stack_set_pollset_or_pollset_set(
  321. exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
  322. }
  323. #ifdef GRPC_STREAM_REFCOUNT_DEBUG
  324. #define REF_REASON reason
  325. #define REF_ARG , const char *reason
  326. #else
  327. #define REF_REASON ""
  328. #define REF_ARG
  329. #endif
  330. void grpc_call_internal_ref(grpc_call *c REF_ARG) {
  331. GRPC_CALL_STACK_REF(CALL_STACK_FROM_CALL(c), REF_REASON);
  332. }
  333. void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) {
  334. GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON);
  335. }
  336. static void get_final_status(grpc_call *call,
  337. void (*set_value)(grpc_status_code code,
  338. void *user_data),
  339. void *set_value_user_data) {
  340. int i;
  341. for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
  342. if (call->status[i].is_set) {
  343. set_value(call->status[i].code, set_value_user_data);
  344. return;
  345. }
  346. }
  347. if (call->is_client) {
  348. set_value(GRPC_STATUS_UNKNOWN, set_value_user_data);
  349. } else {
  350. set_value(GRPC_STATUS_OK, set_value_user_data);
  351. }
  352. }
  353. static void set_status_value_directly(grpc_status_code status, void *dest);
  354. static void destroy_call(grpc_exec_ctx *exec_ctx, void *call,
  355. grpc_error *error) {
  356. size_t i;
  357. int ii;
  358. grpc_call *c = call;
  359. GPR_TIMER_BEGIN("destroy_call", 0);
  360. for (i = 0; i < 2; i++) {
  361. grpc_metadata_batch_destroy(
  362. &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
  363. }
  364. if (c->receiving_stream != NULL) {
  365. grpc_byte_stream_destroy(exec_ctx, c->receiving_stream);
  366. }
  367. gpr_mu_destroy(&c->mu);
  368. for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
  369. if (c->status[i].details) {
  370. GRPC_MDSTR_UNREF(c->status[i].details);
  371. }
  372. }
  373. for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
  374. GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md);
  375. }
  376. for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
  377. if (c->context[i].destroy) {
  378. c->context[i].destroy(c->context[i].value);
  379. }
  380. }
  381. if (c->cq) {
  382. GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
  383. }
  384. grpc_channel *channel = c->channel;
  385. get_final_status(call, set_status_value_directly,
  386. &c->final_info.final_status);
  387. grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info, c);
  388. GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
  389. GPR_TIMER_END("destroy_call", 0);
  390. }
  391. static void set_status_code(grpc_call *call, status_source source,
  392. uint32_t status) {
  393. if (call->status[source].is_set) return;
  394. call->status[source].is_set = 1;
  395. call->status[source].code = (grpc_status_code)status;
  396. }
  397. static void set_status_details(grpc_call *call, status_source source,
  398. grpc_mdstr *status) {
  399. if (call->status[source].details != NULL) {
  400. GRPC_MDSTR_UNREF(status);
  401. } else {
  402. call->status[source].details = status;
  403. }
  404. }
  405. static void set_status_from_error(grpc_call *call, status_source source,
  406. grpc_error *error) {
  407. grpc_status_code status;
  408. const char *msg;
  409. grpc_error_get_status(error, &status, &msg);
  410. set_status_code(call, source, (uint32_t)status);
  411. set_status_details(call, source, grpc_mdstr_from_string(msg));
  412. }
  413. static void set_incoming_compression_algorithm(
  414. grpc_call *call, grpc_compression_algorithm algo) {
  415. GPR_ASSERT(algo < GRPC_COMPRESS_ALGORITHMS_COUNT);
  416. call->incoming_compression_algorithm = algo;
  417. }
  418. grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
  419. grpc_call *call) {
  420. grpc_compression_algorithm algorithm;
  421. gpr_mu_lock(&call->mu);
  422. algorithm = call->incoming_compression_algorithm;
  423. gpr_mu_unlock(&call->mu);
  424. return algorithm;
  425. }
  426. static grpc_compression_algorithm compression_algorithm_for_level_locked(
  427. grpc_call *call, grpc_compression_level level) {
  428. return grpc_compression_algorithm_for_level(level,
  429. call->encodings_accepted_by_peer);
  430. }
  431. uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
  432. uint32_t flags;
  433. gpr_mu_lock(&call->mu);
  434. flags = call->test_only_last_message_flags;
  435. gpr_mu_unlock(&call->mu);
  436. return flags;
  437. }
  438. static void destroy_encodings_accepted_by_peer(void *p) { return; }
  439. static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
  440. size_t i;
  441. grpc_compression_algorithm algorithm;
  442. gpr_slice_buffer accept_encoding_parts;
  443. gpr_slice accept_encoding_slice;
  444. void *accepted_user_data;
  445. accepted_user_data =
  446. grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer);
  447. if (accepted_user_data != NULL) {
  448. call->encodings_accepted_by_peer =
  449. (uint32_t)(((uintptr_t)accepted_user_data) - 1);
  450. return;
  451. }
  452. accept_encoding_slice = mdel->value->slice;
  453. gpr_slice_buffer_init(&accept_encoding_parts);
  454. gpr_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
  455. /* No need to zero call->encodings_accepted_by_peer: grpc_call_create already
  456. * zeroes the whole grpc_call */
  457. /* Always support no compression */
  458. GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
  459. for (i = 0; i < accept_encoding_parts.count; i++) {
  460. const gpr_slice *accept_encoding_entry_slice =
  461. &accept_encoding_parts.slices[i];
  462. if (grpc_compression_algorithm_parse(
  463. (const char *)GPR_SLICE_START_PTR(*accept_encoding_entry_slice),
  464. GPR_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) {
  465. GPR_BITSET(&call->encodings_accepted_by_peer, algorithm);
  466. } else {
  467. char *accept_encoding_entry_str =
  468. gpr_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII);
  469. gpr_log(GPR_ERROR,
  470. "Invalid entry in accept encoding metadata: '%s'. Ignoring.",
  471. accept_encoding_entry_str);
  472. gpr_free(accept_encoding_entry_str);
  473. }
  474. }
  475. gpr_slice_buffer_destroy(&accept_encoding_parts);
  476. grpc_mdelem_set_user_data(
  477. mdel, destroy_encodings_accepted_by_peer,
  478. (void *)(((uintptr_t)call->encodings_accepted_by_peer) + 1));
  479. }
  480. uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
  481. uint32_t encodings_accepted_by_peer;
  482. gpr_mu_lock(&call->mu);
  483. encodings_accepted_by_peer = call->encodings_accepted_by_peer;
  484. gpr_mu_unlock(&call->mu);
  485. return encodings_accepted_by_peer;
  486. }
  487. static void get_final_details(grpc_call *call, char **out_details,
  488. size_t *out_details_capacity) {
  489. int i;
  490. for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
  491. if (call->status[i].is_set) {
  492. if (call->status[i].details) {
  493. gpr_slice details = call->status[i].details->slice;
  494. size_t len = GPR_SLICE_LENGTH(details);
  495. if (len + 1 > *out_details_capacity) {
  496. *out_details_capacity =
  497. GPR_MAX(len + 1, *out_details_capacity * 3 / 2);
  498. *out_details = gpr_realloc(*out_details, *out_details_capacity);
  499. }
  500. memcpy(*out_details, GPR_SLICE_START_PTR(details), len);
  501. (*out_details)[len] = 0;
  502. } else {
  503. goto no_details;
  504. }
  505. return;
  506. }
  507. }
  508. no_details:
  509. if (0 == *out_details_capacity) {
  510. *out_details_capacity = 8;
  511. *out_details = gpr_malloc(*out_details_capacity);
  512. }
  513. **out_details = 0;
  514. }
  515. static grpc_linked_mdelem *linked_from_md(grpc_metadata *md) {
  516. return (grpc_linked_mdelem *)&md->internal_data;
  517. }
  518. static grpc_metadata *get_md_elem(grpc_metadata *metadata,
  519. grpc_metadata *additional_metadata, int i,
  520. int count) {
  521. grpc_metadata *res =
  522. i < count ? &metadata[i] : &additional_metadata[i - count];
  523. GPR_ASSERT(res);
  524. return res;
  525. }
  526. static int prepare_application_metadata(grpc_call *call, int count,
  527. grpc_metadata *metadata,
  528. int is_trailing,
  529. int prepend_extra_metadata,
  530. grpc_metadata *additional_metadata,
  531. int additional_metadata_count) {
  532. int total_count = count + additional_metadata_count;
  533. int i;
  534. grpc_metadata_batch *batch =
  535. &call->metadata_batch[0 /* is_receiving */][is_trailing];
  536. for (i = 0; i < total_count; i++) {
  537. const grpc_metadata *md =
  538. get_md_elem(metadata, additional_metadata, i, count);
  539. grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
  540. GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
  541. l->md = grpc_mdelem_from_string_and_buffer(
  542. md->key, (const uint8_t *)md->value, md->value_length);
  543. if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key),
  544. GRPC_MDSTR_LENGTH(l->md->key))) {
  545. gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
  546. grpc_mdstr_as_c_string(l->md->key));
  547. break;
  548. } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key),
  549. GRPC_MDSTR_LENGTH(l->md->key)) &&
  550. !grpc_header_nonbin_value_is_legal(
  551. grpc_mdstr_as_c_string(l->md->value),
  552. GRPC_MDSTR_LENGTH(l->md->value))) {
  553. gpr_log(GPR_ERROR, "attempt to send invalid metadata value");
  554. break;
  555. }
  556. }
  557. if (i != total_count) {
  558. for (int j = 0; j <= i; j++) {
  559. const grpc_metadata *md =
  560. get_md_elem(metadata, additional_metadata, j, count);
  561. grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
  562. GRPC_MDELEM_UNREF(l->md);
  563. }
  564. return 0;
  565. }
  566. if (prepend_extra_metadata) {
  567. if (call->send_extra_metadata_count == 0) {
  568. prepend_extra_metadata = 0;
  569. } else {
  570. for (i = 0; i < call->send_extra_metadata_count; i++) {
  571. GRPC_MDELEM_REF(call->send_extra_metadata[i].md);
  572. }
  573. for (i = 1; i < call->send_extra_metadata_count; i++) {
  574. call->send_extra_metadata[i].prev = &call->send_extra_metadata[i - 1];
  575. }
  576. for (i = 0; i < call->send_extra_metadata_count - 1; i++) {
  577. call->send_extra_metadata[i].next = &call->send_extra_metadata[i + 1];
  578. }
  579. }
  580. }
  581. for (i = 1; i < total_count; i++) {
  582. grpc_metadata *md = get_md_elem(metadata, additional_metadata, i, count);
  583. grpc_metadata *prev_md =
  584. get_md_elem(metadata, additional_metadata, i - 1, count);
  585. linked_from_md(md)->prev = linked_from_md(prev_md);
  586. }
  587. for (i = 0; i < total_count - 1; i++) {
  588. grpc_metadata *md = get_md_elem(metadata, additional_metadata, i, count);
  589. grpc_metadata *next_md =
  590. get_md_elem(metadata, additional_metadata, i + 1, count);
  591. linked_from_md(md)->next = linked_from_md(next_md);
  592. }
  593. switch (prepend_extra_metadata * 2 + (total_count != 0)) {
  594. case 0:
  595. /* no prepend, no metadata => nothing to do */
  596. batch->list.head = batch->list.tail = NULL;
  597. break;
  598. case 1: {
  599. /* metadata, but no prepend */
  600. grpc_metadata *first_md =
  601. get_md_elem(metadata, additional_metadata, 0, count);
  602. grpc_metadata *last_md =
  603. get_md_elem(metadata, additional_metadata, total_count - 1, count);
  604. batch->list.head = linked_from_md(first_md);
  605. batch->list.tail = linked_from_md(last_md);
  606. batch->list.head->prev = NULL;
  607. batch->list.tail->next = NULL;
  608. break;
  609. }
  610. case 2:
  611. /* prepend, but no md */
  612. batch->list.head = &call->send_extra_metadata[0];
  613. batch->list.tail =
  614. &call->send_extra_metadata[call->send_extra_metadata_count - 1];
  615. batch->list.head->prev = NULL;
  616. batch->list.tail->next = NULL;
  617. break;
  618. case 3: {
  619. /* prepend AND md */
  620. grpc_metadata *first_md =
  621. get_md_elem(metadata, additional_metadata, 0, count);
  622. grpc_metadata *last_md =
  623. get_md_elem(metadata, additional_metadata, total_count - 1, count);
  624. batch->list.head = &call->send_extra_metadata[0];
  625. call->send_extra_metadata[call->send_extra_metadata_count - 1].next =
  626. linked_from_md(first_md);
  627. linked_from_md(first_md)->prev =
  628. &call->send_extra_metadata[call->send_extra_metadata_count - 1];
  629. batch->list.tail = linked_from_md(last_md);
  630. batch->list.head->prev = NULL;
  631. batch->list.tail->next = NULL;
  632. break;
  633. }
  634. default:
  635. GPR_UNREACHABLE_CODE(return 0);
  636. }
  637. return 1;
  638. }
  639. void grpc_call_destroy(grpc_call *c) {
  640. int cancel;
  641. grpc_call *parent = c->parent;
  642. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  643. GPR_TIMER_BEGIN("grpc_call_destroy", 0);
  644. GRPC_API_TRACE("grpc_call_destroy(c=%p)", 1, (c));
  645. if (parent) {
  646. gpr_mu_lock(&parent->mu);
  647. if (c == parent->first_child) {
  648. parent->first_child = c->sibling_next;
  649. if (c == parent->first_child) {
  650. parent->first_child = NULL;
  651. }
  652. c->sibling_prev->sibling_next = c->sibling_next;
  653. c->sibling_next->sibling_prev = c->sibling_prev;
  654. }
  655. gpr_mu_unlock(&parent->mu);
  656. GRPC_CALL_INTERNAL_UNREF(&exec_ctx, parent, "child");
  657. }
  658. gpr_mu_lock(&c->mu);
  659. GPR_ASSERT(!c->destroy_called);
  660. c->destroy_called = 1;
  661. cancel = !c->received_final_op;
  662. gpr_mu_unlock(&c->mu);
  663. if (cancel) grpc_call_cancel(c, NULL);
  664. GRPC_CALL_INTERNAL_UNREF(&exec_ctx, c, "destroy");
  665. grpc_exec_ctx_finish(&exec_ctx);
  666. GPR_TIMER_END("grpc_call_destroy", 0);
  667. }
  668. grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) {
  669. GRPC_API_TRACE("grpc_call_cancel(call=%p, reserved=%p)", 2, (call, reserved));
  670. GPR_ASSERT(!reserved);
  671. return grpc_call_cancel_with_status(call, GRPC_STATUS_CANCELLED, "Cancelled",
  672. NULL);
  673. }
  674. grpc_call_error grpc_call_cancel_with_status(grpc_call *c,
  675. grpc_status_code status,
  676. const char *description,
  677. void *reserved) {
  678. grpc_call_error r;
  679. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  680. GRPC_API_TRACE(
  681. "grpc_call_cancel_with_status("
  682. "c=%p, status=%d, description=%s, reserved=%p)",
  683. 4, (c, (int)status, description, reserved));
  684. GPR_ASSERT(reserved == NULL);
  685. gpr_mu_lock(&c->mu);
  686. r = cancel_with_status(&exec_ctx, c, status, description);
  687. gpr_mu_unlock(&c->mu);
  688. grpc_exec_ctx_finish(&exec_ctx);
  689. return r;
  690. }
  691. typedef struct termination_closure {
  692. grpc_closure closure;
  693. grpc_call *call;
  694. grpc_error *error;
  695. enum { TC_CANCEL, TC_CLOSE } type;
  696. grpc_transport_stream_op op;
  697. } termination_closure;
  698. static void done_termination(grpc_exec_ctx *exec_ctx, void *tcp,
  699. grpc_error *error) {
  700. termination_closure *tc = tcp;
  701. switch (tc->type) {
  702. case TC_CANCEL:
  703. GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "cancel");
  704. break;
  705. case TC_CLOSE:
  706. GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "close");
  707. break;
  708. }
  709. GRPC_ERROR_UNREF(tc->error);
  710. gpr_free(tc);
  711. }
  712. static void send_cancel(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
  713. termination_closure *tc = tcp;
  714. memset(&tc->op, 0, sizeof(tc->op));
  715. tc->op.cancel_error = tc->error;
  716. /* reuse closure to catch completion */
  717. grpc_closure_init(&tc->closure, done_termination, tc);
  718. tc->op.on_complete = &tc->closure;
  719. execute_op(exec_ctx, tc->call, &tc->op);
  720. }
  721. static void send_close(grpc_exec_ctx *exec_ctx, void *tcp, grpc_error *error) {
  722. termination_closure *tc = tcp;
  723. memset(&tc->op, 0, sizeof(tc->op));
  724. tc->op.close_error = tc->error;
  725. /* reuse closure to catch completion */
  726. grpc_closure_init(&tc->closure, done_termination, tc);
  727. tc->op.on_complete = &tc->closure;
  728. execute_op(exec_ctx, tc->call, &tc->op);
  729. }
  730. static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
  731. termination_closure *tc) {
  732. set_status_from_error(tc->call, STATUS_FROM_API_OVERRIDE, tc->error);
  733. if (tc->type == TC_CANCEL) {
  734. grpc_closure_init(&tc->closure, send_cancel, tc);
  735. GRPC_CALL_INTERNAL_REF(tc->call, "cancel");
  736. } else if (tc->type == TC_CLOSE) {
  737. grpc_closure_init(&tc->closure, send_close, tc);
  738. GRPC_CALL_INTERNAL_REF(tc->call, "close");
  739. }
  740. grpc_exec_ctx_sched(exec_ctx, &tc->closure, GRPC_ERROR_NONE, NULL);
  741. return GRPC_CALL_OK;
  742. }
  743. static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
  744. grpc_status_code status,
  745. const char *description) {
  746. GPR_ASSERT(status != GRPC_STATUS_OK);
  747. termination_closure *tc = gpr_malloc(sizeof(*tc));
  748. memset(tc, 0, sizeof(termination_closure));
  749. tc->type = TC_CANCEL;
  750. tc->call = c;
  751. tc->error = grpc_error_set_int(
  752. grpc_error_set_str(GRPC_ERROR_CREATE(description),
  753. GRPC_ERROR_STR_GRPC_MESSAGE, description),
  754. GRPC_ERROR_INT_GRPC_STATUS, status);
  755. return terminate_with_status(exec_ctx, tc);
  756. }
  757. static grpc_call_error close_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
  758. grpc_status_code status,
  759. const char *description) {
  760. GPR_ASSERT(status != GRPC_STATUS_OK);
  761. termination_closure *tc = gpr_malloc(sizeof(*tc));
  762. memset(tc, 0, sizeof(termination_closure));
  763. tc->type = TC_CLOSE;
  764. tc->call = c;
  765. tc->error = grpc_error_set_int(
  766. grpc_error_set_str(GRPC_ERROR_CREATE(description),
  767. GRPC_ERROR_STR_GRPC_MESSAGE, description),
  768. GRPC_ERROR_INT_GRPC_STATUS, status);
  769. return terminate_with_status(exec_ctx, tc);
  770. }
  771. static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
  772. grpc_transport_stream_op *op) {
  773. grpc_call_element *elem;
  774. GPR_TIMER_BEGIN("execute_op", 0);
  775. elem = CALL_ELEM_FROM_CALL(call, 0);
  776. op->context = call->context;
  777. elem->filter->start_transport_stream_op(exec_ctx, elem, op);
  778. GPR_TIMER_END("execute_op", 0);
  779. }
  780. char *grpc_call_get_peer(grpc_call *call) {
  781. grpc_call_element *elem = CALL_ELEM_FROM_CALL(call, 0);
  782. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  783. char *result;
  784. GRPC_API_TRACE("grpc_call_get_peer(%p)", 1, (call));
  785. result = elem->filter->get_peer(&exec_ctx, elem);
  786. if (result == NULL) {
  787. result = grpc_channel_get_target(call->channel);
  788. }
  789. if (result == NULL) {
  790. result = gpr_strdup("unknown");
  791. }
  792. grpc_exec_ctx_finish(&exec_ctx);
  793. return result;
  794. }
  795. grpc_call *grpc_call_from_top_element(grpc_call_element *elem) {
  796. return CALL_FROM_TOP_ELEM(elem);
  797. }
  798. /* we offset status by a small amount when storing it into transport metadata
  799. as metadata cannot store a 0 value (which is used as OK for grpc_status_codes
  800. */
  801. #define STATUS_OFFSET 1
  802. static void destroy_status(void *ignored) {}
  803. static uint32_t decode_status(grpc_mdelem *md) {
  804. uint32_t status;
  805. void *user_data;
  806. if (md == GRPC_MDELEM_GRPC_STATUS_0) return 0;
  807. if (md == GRPC_MDELEM_GRPC_STATUS_1) return 1;
  808. if (md == GRPC_MDELEM_GRPC_STATUS_2) return 2;
  809. user_data = grpc_mdelem_get_user_data(md, destroy_status);
  810. if (user_data != NULL) {
  811. status = ((uint32_t)(intptr_t)user_data) - STATUS_OFFSET;
  812. } else {
  813. if (!gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value),
  814. GPR_SLICE_LENGTH(md->value->slice),
  815. &status)) {
  816. status = GRPC_STATUS_UNKNOWN; /* could not parse status code */
  817. }
  818. grpc_mdelem_set_user_data(md, destroy_status,
  819. (void *)(intptr_t)(status + STATUS_OFFSET));
  820. }
  821. return status;
  822. }
  823. static grpc_compression_algorithm decode_compression(grpc_mdelem *md) {
  824. grpc_compression_algorithm algorithm =
  825. grpc_compression_algorithm_from_mdstr(md->value);
  826. if (algorithm == GRPC_COMPRESS_ALGORITHMS_COUNT) {
  827. const char *md_c_str = grpc_mdstr_as_c_string(md->value);
  828. gpr_log(GPR_ERROR,
  829. "Invalid incoming compression algorithm: '%s'. Interpreting "
  830. "incoming data as uncompressed.",
  831. md_c_str);
  832. return GRPC_COMPRESS_NONE;
  833. }
  834. return algorithm;
  835. }
  836. static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) {
  837. if (elem->key == GRPC_MDSTR_GRPC_STATUS) {
  838. GPR_TIMER_BEGIN("status", 0);
  839. set_status_code(call, STATUS_FROM_WIRE, decode_status(elem));
  840. GPR_TIMER_END("status", 0);
  841. return NULL;
  842. } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) {
  843. GPR_TIMER_BEGIN("status-details", 0);
  844. set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value));
  845. GPR_TIMER_END("status-details", 0);
  846. return NULL;
  847. }
  848. return elem;
  849. }
  850. static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem,
  851. int is_trailing) {
  852. grpc_metadata_array *dest;
  853. grpc_metadata *mdusr;
  854. GPR_TIMER_BEGIN("publish_app_metadata", 0);
  855. dest = call->buffered_metadata[is_trailing];
  856. if (dest->count == dest->capacity) {
  857. dest->capacity = GPR_MAX(dest->capacity + 8, dest->capacity * 2);
  858. dest->metadata =
  859. gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity);
  860. }
  861. mdusr = &dest->metadata[dest->count++];
  862. mdusr->key = grpc_mdstr_as_c_string(elem->key);
  863. mdusr->value = grpc_mdstr_as_c_string(elem->value);
  864. mdusr->value_length = GPR_SLICE_LENGTH(elem->value->slice);
  865. GPR_TIMER_END("publish_app_metadata", 0);
  866. return elem;
  867. }
  868. static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) {
  869. grpc_call *call = callp;
  870. elem = recv_common_filter(call, elem);
  871. if (elem == NULL) {
  872. return NULL;
  873. } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
  874. GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
  875. set_incoming_compression_algorithm(call, decode_compression(elem));
  876. GPR_TIMER_END("incoming_compression_algorithm", 0);
  877. return NULL;
  878. } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
  879. GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
  880. set_encodings_accepted_by_peer(call, elem);
  881. GPR_TIMER_END("encodings_accepted_by_peer", 0);
  882. return NULL;
  883. } else {
  884. return publish_app_metadata(call, elem, 0);
  885. }
  886. }
  887. static grpc_mdelem *recv_trailing_filter(void *callp, grpc_mdelem *elem) {
  888. grpc_call *call = callp;
  889. elem = recv_common_filter(call, elem);
  890. if (elem == NULL) {
  891. return NULL;
  892. } else {
  893. return publish_app_metadata(call, elem, 1);
  894. }
  895. }
  896. grpc_call_stack *grpc_call_get_call_stack(grpc_call *call) {
  897. return CALL_STACK_FROM_CALL(call);
  898. }
  899. /*
  900. * BATCH API IMPLEMENTATION
  901. */
  902. static void set_status_value_directly(grpc_status_code status, void *dest) {
  903. *(grpc_status_code *)dest = status;
  904. }
  905. static void set_cancelled_value(grpc_status_code status, void *dest) {
  906. *(int *)dest = (status != GRPC_STATUS_OK);
  907. }
  908. static bool are_write_flags_valid(uint32_t flags) {
  909. /* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */
  910. const uint32_t allowed_write_positions =
  911. (GRPC_WRITE_USED_MASK | GRPC_WRITE_INTERNAL_USED_MASK);
  912. const uint32_t invalid_positions = ~allowed_write_positions;
  913. return !(flags & invalid_positions);
  914. }
  915. static bool are_initial_metadata_flags_valid(uint32_t flags, bool is_client) {
  916. /* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */
  917. uint32_t invalid_positions = ~GRPC_INITIAL_METADATA_USED_MASK;
  918. if (!is_client) {
  919. invalid_positions |= GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
  920. }
  921. return !(flags & invalid_positions);
  922. }
  923. static batch_control *allocate_batch_control(grpc_call *call) {
  924. size_t i;
  925. for (i = 0; i < MAX_CONCURRENT_BATCHES; i++) {
  926. if ((call->used_batches & (1 << i)) == 0) {
  927. call->used_batches = (uint8_t)(call->used_batches | (uint8_t)(1 << i));
  928. return &call->active_batches[i];
  929. }
  930. }
  931. return NULL;
  932. }
  933. static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data,
  934. grpc_cq_completion *storage) {
  935. batch_control *bctl = user_data;
  936. grpc_call *call = bctl->call;
  937. gpr_mu_lock(&call->mu);
  938. call->used_batches = (uint8_t)(
  939. call->used_batches & ~(uint8_t)(1 << (bctl - call->active_batches)));
  940. gpr_mu_unlock(&call->mu);
  941. GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion");
  942. }
  943. static void post_batch_completion(grpc_exec_ctx *exec_ctx,
  944. batch_control *bctl) {
  945. grpc_call *call = bctl->call;
  946. grpc_error *error = bctl->error;
  947. if (bctl->recv_final_op) {
  948. GRPC_ERROR_UNREF(error);
  949. error = GRPC_ERROR_NONE;
  950. }
  951. if (bctl->is_notify_tag_closure) {
  952. /* unrefs bctl->error */
  953. grpc_closure_run(exec_ctx, bctl->notify_tag, error);
  954. gpr_mu_lock(&call->mu);
  955. bctl->call->used_batches =
  956. (uint8_t)(bctl->call->used_batches &
  957. ~(uint8_t)(1 << (bctl - bctl->call->active_batches)));
  958. gpr_mu_unlock(&call->mu);
  959. GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion");
  960. } else {
  961. /* unrefs bctl->error */
  962. grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, error,
  963. finish_batch_completion, bctl, &bctl->cq_completion);
  964. }
  965. }
  966. static void continue_receiving_slices(grpc_exec_ctx *exec_ctx,
  967. batch_control *bctl) {
  968. grpc_call *call = bctl->call;
  969. for (;;) {
  970. size_t remaining = call->receiving_stream->length -
  971. (*call->receiving_buffer)->data.raw.slice_buffer.length;
  972. if (remaining == 0) {
  973. call->receiving_message = 0;
  974. grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
  975. call->receiving_stream = NULL;
  976. if (gpr_unref(&bctl->steps_to_complete)) {
  977. post_batch_completion(exec_ctx, bctl);
  978. }
  979. return;
  980. }
  981. if (grpc_byte_stream_next(exec_ctx, call->receiving_stream,
  982. &call->receiving_slice, remaining,
  983. &call->receiving_slice_ready)) {
  984. gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer,
  985. call->receiving_slice);
  986. } else {
  987. return;
  988. }
  989. }
  990. }
  991. static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
  992. grpc_error *error) {
  993. batch_control *bctl = bctlp;
  994. grpc_call *call = bctl->call;
  995. if (error == GRPC_ERROR_NONE) {
  996. gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer,
  997. call->receiving_slice);
  998. continue_receiving_slices(exec_ctx, bctl);
  999. } else {
  1000. if (grpc_trace_operation_failures) {
  1001. GRPC_LOG_IF_ERROR("receiving_slice_ready", GRPC_ERROR_REF(error));
  1002. }
  1003. grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
  1004. call->receiving_stream = NULL;
  1005. grpc_byte_buffer_destroy(*call->receiving_buffer);
  1006. *call->receiving_buffer = NULL;
  1007. if (gpr_unref(&bctl->steps_to_complete)) {
  1008. post_batch_completion(exec_ctx, bctl);
  1009. }
  1010. }
  1011. }
  1012. static void process_data_after_md(grpc_exec_ctx *exec_ctx,
  1013. batch_control *bctl) {
  1014. grpc_call *call = bctl->call;
  1015. if (call->receiving_stream == NULL) {
  1016. *call->receiving_buffer = NULL;
  1017. call->receiving_message = 0;
  1018. if (gpr_unref(&bctl->steps_to_complete)) {
  1019. post_batch_completion(exec_ctx, bctl);
  1020. }
  1021. } else {
  1022. call->test_only_last_message_flags = call->receiving_stream->flags;
  1023. if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) &&
  1024. (call->incoming_compression_algorithm > GRPC_COMPRESS_NONE)) {
  1025. *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create(
  1026. NULL, 0, call->incoming_compression_algorithm);
  1027. } else {
  1028. *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0);
  1029. }
  1030. grpc_closure_init(&call->receiving_slice_ready, receiving_slice_ready,
  1031. bctl);
  1032. continue_receiving_slices(exec_ctx, bctl);
  1033. }
  1034. }
  1035. static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
  1036. grpc_error *error) {
  1037. batch_control *bctl = bctlp;
  1038. grpc_call *call = bctl->call;
  1039. if (error != GRPC_ERROR_NONE) {
  1040. grpc_status_code status;
  1041. const char *msg;
  1042. grpc_error_get_status(error, &status, &msg);
  1043. close_with_status(exec_ctx, call, status, msg);
  1044. }
  1045. gpr_mu_lock(&bctl->call->mu);
  1046. if (bctl->call->has_initial_md_been_received || error != GRPC_ERROR_NONE ||
  1047. call->receiving_stream == NULL) {
  1048. gpr_mu_unlock(&bctl->call->mu);
  1049. process_data_after_md(exec_ctx, bctlp);
  1050. } else {
  1051. call->saved_receiving_stream_ready_bctlp = bctlp;
  1052. gpr_mu_unlock(&bctl->call->mu);
  1053. }
  1054. }
  1055. static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
  1056. batch_control *bctl) {
  1057. grpc_call *call = bctl->call;
  1058. /* validate call->incoming_compression_algorithm */
  1059. if (call->incoming_compression_algorithm != GRPC_COMPRESS_NONE) {
  1060. const grpc_compression_algorithm algo =
  1061. call->incoming_compression_algorithm;
  1062. char *error_msg = NULL;
  1063. const grpc_compression_options compression_options =
  1064. grpc_channel_compression_options(call->channel);
  1065. /* check if algorithm is known */
  1066. if (algo >= GRPC_COMPRESS_ALGORITHMS_COUNT) {
  1067. gpr_asprintf(&error_msg, "Invalid compression algorithm value '%d'.",
  1068. algo);
  1069. gpr_log(GPR_ERROR, "%s", error_msg);
  1070. close_with_status(exec_ctx, call, GRPC_STATUS_UNIMPLEMENTED, error_msg);
  1071. } else if (grpc_compression_options_is_algorithm_enabled(
  1072. &compression_options, algo) == 0) {
  1073. /* check if algorithm is supported by current channel config */
  1074. char *algo_name = NULL;
  1075. grpc_compression_algorithm_name(algo, &algo_name);
  1076. gpr_asprintf(&error_msg, "Compression algorithm '%s' is disabled.",
  1077. algo_name);
  1078. gpr_log(GPR_ERROR, "%s", error_msg);
  1079. close_with_status(exec_ctx, call, GRPC_STATUS_UNIMPLEMENTED, error_msg);
  1080. } else {
  1081. call->incoming_compression_algorithm = algo;
  1082. }
  1083. gpr_free(error_msg);
  1084. }
  1085. /* make sure the received grpc-encoding is amongst the ones listed in
  1086. * grpc-accept-encoding */
  1087. GPR_ASSERT(call->encodings_accepted_by_peer != 0);
  1088. if (!GPR_BITGET(call->encodings_accepted_by_peer,
  1089. call->incoming_compression_algorithm)) {
  1090. extern int grpc_compression_trace;
  1091. if (grpc_compression_trace) {
  1092. char *algo_name = NULL;
  1093. grpc_compression_algorithm_name(call->incoming_compression_algorithm,
  1094. &algo_name);
  1095. gpr_log(GPR_ERROR,
  1096. "Compression algorithm (grpc-encoding = '%s') not present in "
  1097. "the bitset of accepted encodings (grpc-accept-encodings: "
  1098. "'0x%x')",
  1099. algo_name, call->encodings_accepted_by_peer);
  1100. }
  1101. }
  1102. }
  1103. static void add_batch_error(batch_control *bctl, grpc_error *error) {
  1104. if (error == GRPC_ERROR_NONE) return;
  1105. if (bctl->error == GRPC_ERROR_NONE) {
  1106. bctl->error = GRPC_ERROR_CREATE("Call batch operation failed");
  1107. }
  1108. bctl->error = grpc_error_add_child(bctl->error, error);
  1109. }
  1110. static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
  1111. void *bctlp, grpc_error *error) {
  1112. batch_control *bctl = bctlp;
  1113. grpc_call *call = bctl->call;
  1114. gpr_mu_lock(&call->mu);
  1115. add_batch_error(bctl, GRPC_ERROR_REF(error));
  1116. if (error == GRPC_ERROR_NONE) {
  1117. grpc_metadata_batch *md =
  1118. &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
  1119. grpc_metadata_batch_filter(md, recv_initial_filter, call);
  1120. GPR_TIMER_BEGIN("validate_filtered_metadata", 0);
  1121. validate_filtered_metadata(exec_ctx, bctl);
  1122. GPR_TIMER_END("validate_filtered_metadata", 0);
  1123. if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) !=
  1124. 0 &&
  1125. !call->is_client) {
  1126. call->send_deadline =
  1127. gpr_convert_clock_type(md->deadline, GPR_CLOCK_MONOTONIC);
  1128. }
  1129. }
  1130. call->has_initial_md_been_received = true;
  1131. if (call->saved_receiving_stream_ready_bctlp != NULL) {
  1132. grpc_closure *saved_rsr_closure = grpc_closure_create(
  1133. receiving_stream_ready, call->saved_receiving_stream_ready_bctlp);
  1134. call->saved_receiving_stream_ready_bctlp = NULL;
  1135. grpc_exec_ctx_sched(exec_ctx, saved_rsr_closure, error, NULL);
  1136. }
  1137. gpr_mu_unlock(&call->mu);
  1138. if (gpr_unref(&bctl->steps_to_complete)) {
  1139. post_batch_completion(exec_ctx, bctl);
  1140. }
  1141. }
  1142. static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp,
  1143. grpc_error *error) {
  1144. batch_control *bctl = bctlp;
  1145. grpc_call *call = bctl->call;
  1146. grpc_call *child_call;
  1147. grpc_call *next_child_call;
  1148. GRPC_ERROR_REF(error);
  1149. gpr_mu_lock(&call->mu);
  1150. // If the error has an associated status code, set the call's status.
  1151. intptr_t status;
  1152. if (error != GRPC_ERROR_NONE &&
  1153. grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) {
  1154. set_status_from_error(call, STATUS_FROM_CORE, error);
  1155. }
  1156. if (bctl->send_initial_metadata) {
  1157. if (error != GRPC_ERROR_NONE) {
  1158. set_status_from_error(call, STATUS_FROM_CORE, error);
  1159. }
  1160. grpc_metadata_batch_destroy(
  1161. &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]);
  1162. }
  1163. if (bctl->send_message) {
  1164. call->sending_message = 0;
  1165. }
  1166. if (bctl->send_final_op) {
  1167. grpc_metadata_batch_destroy(
  1168. &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]);
  1169. }
  1170. if (bctl->recv_final_op) {
  1171. grpc_metadata_batch *md =
  1172. &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
  1173. grpc_metadata_batch_filter(md, recv_trailing_filter, call);
  1174. call->received_final_op = true;
  1175. /* propagate cancellation to any interested children */
  1176. child_call = call->first_child;
  1177. if (child_call != NULL) {
  1178. do {
  1179. next_child_call = child_call->sibling_next;
  1180. if (child_call->cancellation_is_inherited) {
  1181. GRPC_CALL_INTERNAL_REF(child_call, "propagate_cancel");
  1182. grpc_call_cancel(child_call, NULL);
  1183. GRPC_CALL_INTERNAL_UNREF(exec_ctx, child_call, "propagate_cancel");
  1184. }
  1185. child_call = next_child_call;
  1186. } while (child_call != call->first_child);
  1187. }
  1188. if (call->is_client) {
  1189. get_final_status(call, set_status_value_directly,
  1190. call->final_op.client.status);
  1191. get_final_details(call, call->final_op.client.status_details,
  1192. call->final_op.client.status_details_capacity);
  1193. } else {
  1194. get_final_status(call, set_cancelled_value,
  1195. call->final_op.server.cancelled);
  1196. }
  1197. GRPC_ERROR_UNREF(error);
  1198. error = GRPC_ERROR_NONE;
  1199. }
  1200. add_batch_error(bctl, GRPC_ERROR_REF(error));
  1201. gpr_mu_unlock(&call->mu);
  1202. if (gpr_unref(&bctl->steps_to_complete)) {
  1203. post_batch_completion(exec_ctx, bctl);
  1204. }
  1205. GRPC_ERROR_UNREF(error);
  1206. }
  1207. static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
  1208. grpc_call *call, const grpc_op *ops,
  1209. size_t nops, void *notify_tag,
  1210. int is_notify_tag_closure) {
  1211. size_t i;
  1212. const grpc_op *op;
  1213. batch_control *bctl;
  1214. int num_completion_callbacks_needed = 1;
  1215. grpc_call_error error = GRPC_CALL_OK;
  1216. // sent_initial_metadata guards against variable reuse.
  1217. grpc_metadata compression_md;
  1218. GPR_TIMER_BEGIN("grpc_call_start_batch", 0);
  1219. GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, notify_tag);
  1220. /* TODO(ctiller): this feels like it could be made lock-free */
  1221. gpr_mu_lock(&call->mu);
  1222. bctl = allocate_batch_control(call);
  1223. memset(bctl, 0, sizeof(*bctl));
  1224. bctl->call = call;
  1225. bctl->notify_tag = notify_tag;
  1226. bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0);
  1227. grpc_transport_stream_op *stream_op = &bctl->op;
  1228. memset(stream_op, 0, sizeof(*stream_op));
  1229. stream_op->covered_by_poller = true;
  1230. if (nops == 0) {
  1231. GRPC_CALL_INTERNAL_REF(call, "completion");
  1232. bctl->error = GRPC_ERROR_NONE;
  1233. if (!is_notify_tag_closure) {
  1234. grpc_cq_begin_op(call->cq, notify_tag);
  1235. }
  1236. gpr_mu_unlock(&call->mu);
  1237. post_batch_completion(exec_ctx, bctl);
  1238. error = GRPC_CALL_OK;
  1239. goto done;
  1240. }
  1241. /* rewrite batch ops into a transport op */
  1242. for (i = 0; i < nops; i++) {
  1243. op = &ops[i];
  1244. if (op->reserved != NULL) {
  1245. error = GRPC_CALL_ERROR;
  1246. goto done_with_error;
  1247. }
  1248. switch (op->op) {
  1249. case GRPC_OP_SEND_INITIAL_METADATA:
  1250. /* Flag validation: currently allow no flags */
  1251. if (!are_initial_metadata_flags_valid(op->flags, call->is_client)) {
  1252. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1253. goto done_with_error;
  1254. }
  1255. if (call->sent_initial_metadata) {
  1256. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1257. goto done_with_error;
  1258. }
  1259. /* process compression level */
  1260. memset(&compression_md, 0, sizeof(compression_md));
  1261. size_t additional_metadata_count = 0;
  1262. grpc_compression_level effective_compression_level;
  1263. bool level_set = false;
  1264. if (op->data.send_initial_metadata.maybe_compression_level.is_set) {
  1265. effective_compression_level =
  1266. op->data.send_initial_metadata.maybe_compression_level.level;
  1267. level_set = true;
  1268. } else {
  1269. const grpc_compression_options copts =
  1270. grpc_channel_compression_options(call->channel);
  1271. level_set = copts.default_level.is_set;
  1272. if (level_set) {
  1273. effective_compression_level = copts.default_level.level;
  1274. }
  1275. }
  1276. if (level_set && !call->is_client) {
  1277. const grpc_compression_algorithm calgo =
  1278. compression_algorithm_for_level_locked(
  1279. call, effective_compression_level);
  1280. char *calgo_name = NULL;
  1281. grpc_compression_algorithm_name(calgo, &calgo_name);
  1282. // the following will be picked up by the compress filter and used as
  1283. // the call's compression algorithm.
  1284. compression_md.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
  1285. compression_md.value = calgo_name;
  1286. compression_md.value_length = strlen(calgo_name);
  1287. additional_metadata_count++;
  1288. }
  1289. if (op->data.send_initial_metadata.count + additional_metadata_count >
  1290. INT_MAX) {
  1291. error = GRPC_CALL_ERROR_INVALID_METADATA;
  1292. goto done_with_error;
  1293. }
  1294. bctl->send_initial_metadata = 1;
  1295. call->sent_initial_metadata = 1;
  1296. if (!prepare_application_metadata(
  1297. call, (int)op->data.send_initial_metadata.count,
  1298. op->data.send_initial_metadata.metadata, 0, call->is_client,
  1299. &compression_md, (int)additional_metadata_count)) {
  1300. error = GRPC_CALL_ERROR_INVALID_METADATA;
  1301. goto done_with_error;
  1302. }
  1303. /* TODO(ctiller): just make these the same variable? */
  1304. call->metadata_batch[0][0].deadline = call->send_deadline;
  1305. stream_op->send_initial_metadata =
  1306. &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */];
  1307. stream_op->send_initial_metadata_flags = op->flags;
  1308. break;
  1309. case GRPC_OP_SEND_MESSAGE:
  1310. if (!are_write_flags_valid(op->flags)) {
  1311. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1312. goto done_with_error;
  1313. }
  1314. if (op->data.send_message == NULL) {
  1315. error = GRPC_CALL_ERROR_INVALID_MESSAGE;
  1316. goto done_with_error;
  1317. }
  1318. if (call->sending_message) {
  1319. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1320. goto done_with_error;
  1321. }
  1322. bctl->send_message = 1;
  1323. call->sending_message = 1;
  1324. grpc_slice_buffer_stream_init(
  1325. &call->sending_stream,
  1326. &op->data.send_message->data.raw.slice_buffer, op->flags);
  1327. stream_op->send_message = &call->sending_stream.base;
  1328. break;
  1329. case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
  1330. /* Flag validation: currently allow no flags */
  1331. if (op->flags != 0) {
  1332. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1333. goto done_with_error;
  1334. }
  1335. if (!call->is_client) {
  1336. error = GRPC_CALL_ERROR_NOT_ON_SERVER;
  1337. goto done_with_error;
  1338. }
  1339. if (call->sent_final_op) {
  1340. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1341. goto done_with_error;
  1342. }
  1343. bctl->send_final_op = 1;
  1344. call->sent_final_op = 1;
  1345. stream_op->send_trailing_metadata =
  1346. &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
  1347. break;
  1348. case GRPC_OP_SEND_STATUS_FROM_SERVER:
  1349. /* Flag validation: currently allow no flags */
  1350. if (op->flags != 0) {
  1351. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1352. goto done_with_error;
  1353. }
  1354. if (call->is_client) {
  1355. error = GRPC_CALL_ERROR_NOT_ON_CLIENT;
  1356. goto done_with_error;
  1357. }
  1358. if (call->sent_final_op) {
  1359. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1360. goto done_with_error;
  1361. }
  1362. if (op->data.send_status_from_server.trailing_metadata_count >
  1363. INT_MAX) {
  1364. error = GRPC_CALL_ERROR_INVALID_METADATA;
  1365. goto done_with_error;
  1366. }
  1367. bctl->send_final_op = 1;
  1368. call->sent_final_op = 1;
  1369. call->send_extra_metadata_count = 1;
  1370. call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
  1371. call->channel, op->data.send_status_from_server.status);
  1372. if (op->data.send_status_from_server.status_details != NULL) {
  1373. call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings(
  1374. GRPC_MDSTR_GRPC_MESSAGE,
  1375. grpc_mdstr_from_string(
  1376. op->data.send_status_from_server.status_details));
  1377. call->send_extra_metadata_count++;
  1378. set_status_details(
  1379. call, STATUS_FROM_API_OVERRIDE,
  1380. GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value));
  1381. }
  1382. if (op->data.send_status_from_server.status != GRPC_STATUS_OK) {
  1383. set_status_code(call, STATUS_FROM_API_OVERRIDE,
  1384. (uint32_t)op->data.send_status_from_server.status);
  1385. }
  1386. if (!prepare_application_metadata(
  1387. call,
  1388. (int)op->data.send_status_from_server.trailing_metadata_count,
  1389. op->data.send_status_from_server.trailing_metadata, 1, 1, NULL,
  1390. 0)) {
  1391. error = GRPC_CALL_ERROR_INVALID_METADATA;
  1392. goto done_with_error;
  1393. }
  1394. stream_op->send_trailing_metadata =
  1395. &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
  1396. break;
  1397. case GRPC_OP_RECV_INITIAL_METADATA:
  1398. /* Flag validation: currently allow no flags */
  1399. if (op->flags != 0) {
  1400. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1401. goto done_with_error;
  1402. }
  1403. if (call->received_initial_metadata) {
  1404. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1405. goto done_with_error;
  1406. }
  1407. call->received_initial_metadata = 1;
  1408. call->buffered_metadata[0] = op->data.recv_initial_metadata;
  1409. grpc_closure_init(&call->receiving_initial_metadata_ready,
  1410. receiving_initial_metadata_ready, bctl);
  1411. bctl->recv_initial_metadata = 1;
  1412. stream_op->recv_initial_metadata =
  1413. &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
  1414. stream_op->recv_initial_metadata_ready =
  1415. &call->receiving_initial_metadata_ready;
  1416. num_completion_callbacks_needed++;
  1417. break;
  1418. case GRPC_OP_RECV_MESSAGE:
  1419. /* Flag validation: currently allow no flags */
  1420. if (op->flags != 0) {
  1421. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1422. goto done_with_error;
  1423. }
  1424. if (call->receiving_message) {
  1425. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1426. goto done_with_error;
  1427. }
  1428. call->receiving_message = 1;
  1429. bctl->recv_message = 1;
  1430. call->receiving_buffer = op->data.recv_message;
  1431. stream_op->recv_message = &call->receiving_stream;
  1432. grpc_closure_init(&call->receiving_stream_ready, receiving_stream_ready,
  1433. bctl);
  1434. stream_op->recv_message_ready = &call->receiving_stream_ready;
  1435. num_completion_callbacks_needed++;
  1436. break;
  1437. case GRPC_OP_RECV_STATUS_ON_CLIENT:
  1438. /* Flag validation: currently allow no flags */
  1439. if (op->flags != 0) {
  1440. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1441. goto done_with_error;
  1442. }
  1443. if (!call->is_client) {
  1444. error = GRPC_CALL_ERROR_NOT_ON_SERVER;
  1445. goto done_with_error;
  1446. }
  1447. if (call->requested_final_op) {
  1448. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1449. goto done_with_error;
  1450. }
  1451. call->requested_final_op = 1;
  1452. call->buffered_metadata[1] =
  1453. op->data.recv_status_on_client.trailing_metadata;
  1454. call->final_op.client.status = op->data.recv_status_on_client.status;
  1455. call->final_op.client.status_details =
  1456. op->data.recv_status_on_client.status_details;
  1457. call->final_op.client.status_details_capacity =
  1458. op->data.recv_status_on_client.status_details_capacity;
  1459. bctl->recv_final_op = 1;
  1460. stream_op->recv_trailing_metadata =
  1461. &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
  1462. stream_op->collect_stats =
  1463. &call->final_info.stats.transport_stream_stats;
  1464. break;
  1465. case GRPC_OP_RECV_CLOSE_ON_SERVER:
  1466. /* Flag validation: currently allow no flags */
  1467. if (op->flags != 0) {
  1468. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1469. goto done_with_error;
  1470. }
  1471. if (call->is_client) {
  1472. error = GRPC_CALL_ERROR_NOT_ON_CLIENT;
  1473. goto done_with_error;
  1474. }
  1475. if (call->requested_final_op) {
  1476. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1477. goto done_with_error;
  1478. }
  1479. call->requested_final_op = 1;
  1480. call->final_op.server.cancelled =
  1481. op->data.recv_close_on_server.cancelled;
  1482. bctl->recv_final_op = 1;
  1483. stream_op->recv_trailing_metadata =
  1484. &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
  1485. stream_op->collect_stats =
  1486. &call->final_info.stats.transport_stream_stats;
  1487. break;
  1488. }
  1489. }
  1490. GRPC_CALL_INTERNAL_REF(call, "completion");
  1491. if (!is_notify_tag_closure) {
  1492. grpc_cq_begin_op(call->cq, notify_tag);
  1493. }
  1494. gpr_ref_init(&bctl->steps_to_complete, num_completion_callbacks_needed);
  1495. stream_op->context = call->context;
  1496. grpc_closure_init(&bctl->finish_batch, finish_batch, bctl);
  1497. stream_op->on_complete = &bctl->finish_batch;
  1498. gpr_mu_unlock(&call->mu);
  1499. execute_op(exec_ctx, call, stream_op);
  1500. done:
  1501. GPR_TIMER_END("grpc_call_start_batch", 0);
  1502. return error;
  1503. done_with_error:
  1504. /* reverse any mutations that occured */
  1505. if (bctl->send_initial_metadata) {
  1506. call->sent_initial_metadata = 0;
  1507. grpc_metadata_batch_clear(&call->metadata_batch[0][0]);
  1508. }
  1509. if (bctl->send_message) {
  1510. call->sending_message = 0;
  1511. grpc_byte_stream_destroy(exec_ctx, &call->sending_stream.base);
  1512. }
  1513. if (bctl->send_final_op) {
  1514. call->sent_final_op = 0;
  1515. grpc_metadata_batch_clear(&call->metadata_batch[0][1]);
  1516. }
  1517. if (bctl->recv_initial_metadata) {
  1518. call->received_initial_metadata = 0;
  1519. }
  1520. if (bctl->recv_message) {
  1521. call->receiving_message = 0;
  1522. }
  1523. if (bctl->recv_final_op) {
  1524. call->requested_final_op = 0;
  1525. }
  1526. gpr_mu_unlock(&call->mu);
  1527. goto done;
  1528. }
  1529. grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
  1530. size_t nops, void *tag, void *reserved) {
  1531. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  1532. grpc_call_error err;
  1533. GRPC_API_TRACE(
  1534. "grpc_call_start_batch(call=%p, ops=%p, nops=%lu, tag=%p, "
  1535. "reserved=%p)",
  1536. 5, (call, ops, (unsigned long)nops, tag, reserved));
  1537. if (reserved != NULL) {
  1538. err = GRPC_CALL_ERROR;
  1539. } else {
  1540. err = call_start_batch(&exec_ctx, call, ops, nops, tag, 0);
  1541. }
  1542. grpc_exec_ctx_finish(&exec_ctx);
  1543. return err;
  1544. }
  1545. grpc_call_error grpc_call_start_batch_and_execute(grpc_exec_ctx *exec_ctx,
  1546. grpc_call *call,
  1547. const grpc_op *ops,
  1548. size_t nops,
  1549. grpc_closure *closure) {
  1550. return call_start_batch(exec_ctx, call, ops, nops, closure, 1);
  1551. }
  1552. void grpc_call_context_set(grpc_call *call, grpc_context_index elem,
  1553. void *value, void (*destroy)(void *value)) {
  1554. if (call->context[elem].destroy) {
  1555. call->context[elem].destroy(call->context[elem].value);
  1556. }
  1557. call->context[elem].value = value;
  1558. call->context[elem].destroy = destroy;
  1559. }
  1560. void *grpc_call_context_get(grpc_call *call, grpc_context_index elem) {
  1561. return call->context[elem].value;
  1562. }
  1563. uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; }
  1564. grpc_compression_algorithm grpc_call_compression_for_level(
  1565. grpc_call *call, grpc_compression_level level) {
  1566. gpr_mu_lock(&call->mu);
  1567. grpc_compression_algorithm algo =
  1568. compression_algorithm_for_level_locked(call, level);
  1569. gpr_mu_unlock(&call->mu);
  1570. return algo;
  1571. }
  1572. const char *grpc_call_error_to_string(grpc_call_error error) {
  1573. switch (error) {
  1574. case GRPC_CALL_ERROR:
  1575. return "GRPC_CALL_ERROR";
  1576. case GRPC_CALL_ERROR_ALREADY_ACCEPTED:
  1577. return "GRPC_CALL_ERROR_ALREADY_ACCEPTED";
  1578. case GRPC_CALL_ERROR_ALREADY_FINISHED:
  1579. return "GRPC_CALL_ERROR_ALREADY_FINISHED";
  1580. case GRPC_CALL_ERROR_ALREADY_INVOKED:
  1581. return "GRPC_CALL_ERROR_ALREADY_INVOKED";
  1582. case GRPC_CALL_ERROR_BATCH_TOO_BIG:
  1583. return "GRPC_CALL_ERROR_BATCH_TOO_BIG";
  1584. case GRPC_CALL_ERROR_INVALID_FLAGS:
  1585. return "GRPC_CALL_ERROR_INVALID_FLAGS";
  1586. case GRPC_CALL_ERROR_INVALID_MESSAGE:
  1587. return "GRPC_CALL_ERROR_INVALID_MESSAGE";
  1588. case GRPC_CALL_ERROR_INVALID_METADATA:
  1589. return "GRPC_CALL_ERROR_INVALID_METADATA";
  1590. case GRPC_CALL_ERROR_NOT_INVOKED:
  1591. return "GRPC_CALL_ERROR_NOT_INVOKED";
  1592. case GRPC_CALL_ERROR_NOT_ON_CLIENT:
  1593. return "GRPC_CALL_ERROR_NOT_ON_CLIENT";
  1594. case GRPC_CALL_ERROR_NOT_ON_SERVER:
  1595. return "GRPC_CALL_ERROR_NOT_ON_SERVER";
  1596. case GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE:
  1597. return "GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE";
  1598. case GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH:
  1599. return "GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH";
  1600. case GRPC_CALL_ERROR_TOO_MANY_OPERATIONS:
  1601. return "GRPC_CALL_ERROR_TOO_MANY_OPERATIONS";
  1602. case GRPC_CALL_OK:
  1603. return "GRPC_CALL_OK";
  1604. }
  1605. GPR_UNREACHABLE_CODE(return "GRPC_CALL_ERROR_UNKNOW");
  1606. }