call.c 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597
  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. typedef struct {
  68. grpc_ioreq_completion_func on_complete;
  69. void *user_data;
  70. int success;
  71. } completed_request;
  72. #define MAX_SEND_EXTRA_METADATA_COUNT 3
  73. /* Status data for a request can come from several sources; this
  74. enumerates them all, and acts as a priority sorting for which
  75. status to return to the application - earlier entries override
  76. later ones */
  77. typedef enum {
  78. /* Status came from the application layer overriding whatever
  79. the wire says */
  80. STATUS_FROM_API_OVERRIDE = 0,
  81. /* Status came from 'the wire' - or somewhere below the surface
  82. layer */
  83. STATUS_FROM_WIRE,
  84. /* Status was created by some internal channel stack operation */
  85. STATUS_FROM_CORE,
  86. /* Status came from the server sending status */
  87. STATUS_FROM_SERVER_STATUS,
  88. STATUS_SOURCE_COUNT
  89. } status_source;
  90. typedef struct {
  91. uint8_t is_set;
  92. grpc_status_code code;
  93. grpc_mdstr *details;
  94. } received_status;
  95. /* How far through the GRPC stream have we read? */
  96. typedef enum {
  97. /* We are still waiting for initial metadata to complete */
  98. READ_STATE_INITIAL = 0,
  99. /* We have gotten initial metadata, and are reading either
  100. messages or trailing metadata */
  101. READ_STATE_GOT_INITIAL_METADATA,
  102. /* The stream is closed for reading */
  103. READ_STATE_READ_CLOSED,
  104. /* The stream is closed for reading & writing */
  105. READ_STATE_STREAM_CLOSED
  106. } read_state;
  107. typedef enum {
  108. WRITE_STATE_INITIAL = 0,
  109. WRITE_STATE_STARTED,
  110. WRITE_STATE_WRITE_CLOSED
  111. } write_state;
  112. typedef struct batch_control {
  113. grpc_call *call;
  114. grpc_cq_completion cq_completion;
  115. grpc_closure finish_batch;
  116. void *notify_tag;
  117. gpr_refcount steps_to_complete;
  118. uint8_t send_initial_metadata;
  119. uint8_t send_message;
  120. uint8_t send_final_op;
  121. uint8_t recv_initial_metadata;
  122. uint8_t recv_message;
  123. uint8_t recv_final_op;
  124. uint8_t is_notify_tag_closure;
  125. uint8_t success;
  126. } batch_control;
  127. struct grpc_call {
  128. grpc_completion_queue *cq;
  129. grpc_channel *channel;
  130. grpc_call *parent;
  131. grpc_call *first_child;
  132. /* TODO(ctiller): share with cq if possible? */
  133. gpr_mu mu;
  134. /* client or server call */
  135. uint8_t is_client;
  136. /* is the alarm set */
  137. uint8_t have_alarm;
  138. /** has grpc_call_destroy been called */
  139. uint8_t destroy_called;
  140. /** flag indicating that cancellation is inherited */
  141. uint8_t cancellation_is_inherited;
  142. /** bitmask of live batches */
  143. uint8_t used_batches;
  144. /** which ops are in-flight */
  145. uint8_t sent_initial_metadata;
  146. uint8_t sending_message;
  147. uint8_t sent_final_op;
  148. uint8_t received_initial_metadata;
  149. uint8_t receiving_message;
  150. uint8_t received_final_op;
  151. /* have we received initial metadata */
  152. bool has_initial_md_been_received;
  153. batch_control active_batches[MAX_CONCURRENT_BATCHES];
  154. /* first idx: is_receiving, second idx: is_trailing */
  155. grpc_metadata_batch metadata_batch[2][2];
  156. /* Buffered read metadata waiting to be returned to the application.
  157. Element 0 is initial metadata, element 1 is trailing metadata. */
  158. grpc_metadata_array *buffered_metadata[2];
  159. /* Received call statuses from various sources */
  160. received_status status[STATUS_SOURCE_COUNT];
  161. /* Call stats: only valid after trailing metadata received */
  162. grpc_transport_stream_stats stats;
  163. /* Compression algorithm for the call */
  164. grpc_compression_algorithm compression_algorithm;
  165. /* Supported encodings (compression algorithms), a bitset */
  166. uint32_t encodings_accepted_by_peer;
  167. /* Contexts for various subsystems (security, tracing, ...). */
  168. grpc_call_context_element context[GRPC_CONTEXT_COUNT];
  169. /* Deadline alarm - if have_alarm is non-zero */
  170. grpc_timer alarm;
  171. /* for the client, extra metadata is initial metadata; for the
  172. server, it's trailing metadata */
  173. grpc_linked_mdelem send_extra_metadata[MAX_SEND_EXTRA_METADATA_COUNT];
  174. int send_extra_metadata_count;
  175. gpr_timespec send_deadline;
  176. /** siblings: children of the same parent form a list, and this list is
  177. protected under
  178. parent->mu */
  179. grpc_call *sibling_next;
  180. grpc_call *sibling_prev;
  181. grpc_slice_buffer_stream sending_stream;
  182. grpc_byte_stream *receiving_stream;
  183. grpc_byte_buffer **receiving_buffer;
  184. gpr_slice receiving_slice;
  185. grpc_closure receiving_slice_ready;
  186. grpc_closure receiving_stream_ready;
  187. grpc_closure receiving_initial_metadata_ready;
  188. uint32_t test_only_last_message_flags;
  189. union {
  190. struct {
  191. grpc_status_code *status;
  192. char **status_details;
  193. size_t *status_details_capacity;
  194. } client;
  195. struct {
  196. int *cancelled;
  197. } server;
  198. } final_op;
  199. struct {
  200. void *bctlp;
  201. bool success;
  202. } saved_receiving_stream_ready_ctx;
  203. };
  204. #define CALL_STACK_FROM_CALL(call) ((grpc_call_stack *)((call) + 1))
  205. #define CALL_FROM_CALL_STACK(call_stack) (((grpc_call *)(call_stack)) - 1)
  206. #define CALL_ELEM_FROM_CALL(call, idx) \
  207. grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx)
  208. #define CALL_FROM_TOP_ELEM(top_elem) \
  209. CALL_FROM_CALL_STACK(grpc_call_stack_from_top_element(top_elem))
  210. static void set_deadline_alarm(grpc_exec_ctx *exec_ctx, grpc_call *call,
  211. gpr_timespec deadline);
  212. static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
  213. grpc_transport_stream_op *op);
  214. static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
  215. grpc_status_code status,
  216. const char *description);
  217. static grpc_call_error close_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
  218. grpc_status_code status,
  219. const char *description);
  220. static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack,
  221. bool success);
  222. static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
  223. bool success);
  224. grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
  225. uint32_t propagation_mask,
  226. grpc_completion_queue *cq,
  227. const void *server_transport_data,
  228. grpc_mdelem **add_initial_metadata,
  229. size_t add_initial_metadata_count,
  230. gpr_timespec send_deadline) {
  231. size_t i, j;
  232. grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
  233. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  234. grpc_call *call;
  235. GPR_TIMER_BEGIN("grpc_call_create", 0);
  236. call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size);
  237. memset(call, 0, sizeof(grpc_call));
  238. gpr_mu_init(&call->mu);
  239. call->channel = channel;
  240. call->cq = cq;
  241. call->parent = parent_call;
  242. call->is_client = server_transport_data == NULL;
  243. if (call->is_client) {
  244. GPR_ASSERT(add_initial_metadata_count < MAX_SEND_EXTRA_METADATA_COUNT);
  245. for (i = 0; i < add_initial_metadata_count; i++) {
  246. call->send_extra_metadata[i].md = add_initial_metadata[i];
  247. }
  248. call->send_extra_metadata_count = (int)add_initial_metadata_count;
  249. } else {
  250. GPR_ASSERT(add_initial_metadata_count == 0);
  251. call->send_extra_metadata_count = 0;
  252. }
  253. for (i = 0; i < 2; i++) {
  254. for (j = 0; j < 2; j++) {
  255. call->metadata_batch[i][j].deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
  256. }
  257. }
  258. call->send_deadline = send_deadline;
  259. GRPC_CHANNEL_INTERNAL_REF(channel, "call");
  260. /* initial refcount dropped by grpc_call_destroy */
  261. grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call,
  262. call->context, server_transport_data,
  263. CALL_STACK_FROM_CALL(call));
  264. if (cq != NULL) {
  265. GRPC_CQ_INTERNAL_REF(cq, "bind");
  266. grpc_call_stack_set_pollset(&exec_ctx, CALL_STACK_FROM_CALL(call),
  267. grpc_cq_pollset(cq));
  268. }
  269. if (parent_call != NULL) {
  270. GRPC_CALL_INTERNAL_REF(parent_call, "child");
  271. GPR_ASSERT(call->is_client);
  272. GPR_ASSERT(!parent_call->is_client);
  273. gpr_mu_lock(&parent_call->mu);
  274. if (propagation_mask & GRPC_PROPAGATE_DEADLINE) {
  275. send_deadline = gpr_time_min(
  276. gpr_convert_clock_type(send_deadline,
  277. parent_call->send_deadline.clock_type),
  278. parent_call->send_deadline);
  279. }
  280. /* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with
  281. * GRPC_PROPAGATE_STATS_CONTEXT */
  282. /* TODO(ctiller): This should change to use the appropriate census start_op
  283. * call. */
  284. if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
  285. GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT);
  286. grpc_call_context_set(call, GRPC_CONTEXT_TRACING,
  287. parent_call->context[GRPC_CONTEXT_TRACING].value,
  288. NULL);
  289. } else {
  290. GPR_ASSERT(propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT);
  291. }
  292. if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
  293. call->cancellation_is_inherited = 1;
  294. }
  295. if (parent_call->first_child == NULL) {
  296. parent_call->first_child = call;
  297. call->sibling_next = call->sibling_prev = call;
  298. } else {
  299. call->sibling_next = parent_call->first_child;
  300. call->sibling_prev = parent_call->first_child->sibling_prev;
  301. call->sibling_next->sibling_prev = call->sibling_prev->sibling_next =
  302. call;
  303. }
  304. gpr_mu_unlock(&parent_call->mu);
  305. }
  306. if (gpr_time_cmp(send_deadline, gpr_inf_future(send_deadline.clock_type)) !=
  307. 0) {
  308. set_deadline_alarm(&exec_ctx, call, send_deadline);
  309. }
  310. grpc_exec_ctx_finish(&exec_ctx);
  311. GPR_TIMER_END("grpc_call_create", 0);
  312. return call;
  313. }
  314. void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call,
  315. grpc_completion_queue *cq) {
  316. GPR_ASSERT(cq);
  317. call->cq = cq;
  318. GRPC_CQ_INTERNAL_REF(cq, "bind");
  319. grpc_call_stack_set_pollset(exec_ctx, CALL_STACK_FROM_CALL(call),
  320. grpc_cq_pollset(cq));
  321. }
  322. #ifdef GRPC_STREAM_REFCOUNT_DEBUG
  323. #define REF_REASON reason
  324. #define REF_ARG , const char *reason
  325. #else
  326. #define REF_REASON ""
  327. #define REF_ARG
  328. #endif
  329. void grpc_call_internal_ref(grpc_call *c REF_ARG) {
  330. GRPC_CALL_STACK_REF(CALL_STACK_FROM_CALL(c), REF_REASON);
  331. }
  332. void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) {
  333. GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON);
  334. }
  335. static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, bool success) {
  336. size_t i;
  337. int ii;
  338. grpc_call *c = call;
  339. GPR_TIMER_BEGIN("destroy_call", 0);
  340. for (i = 0; i < 2; i++) {
  341. grpc_metadata_batch_destroy(
  342. &c->metadata_batch[1 /* is_receiving */][i /* is_initial */]);
  343. }
  344. if (c->receiving_stream != NULL) {
  345. grpc_byte_stream_destroy(exec_ctx, c->receiving_stream);
  346. }
  347. grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c));
  348. GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, c->channel, "call");
  349. gpr_mu_destroy(&c->mu);
  350. for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
  351. if (c->status[i].details) {
  352. GRPC_MDSTR_UNREF(c->status[i].details);
  353. }
  354. }
  355. for (ii = 0; ii < c->send_extra_metadata_count; ii++) {
  356. GRPC_MDELEM_UNREF(c->send_extra_metadata[ii].md);
  357. }
  358. for (i = 0; i < GRPC_CONTEXT_COUNT; i++) {
  359. if (c->context[i].destroy) {
  360. c->context[i].destroy(c->context[i].value);
  361. }
  362. }
  363. if (c->cq) {
  364. GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
  365. }
  366. gpr_free(c);
  367. GPR_TIMER_END("destroy_call", 0);
  368. }
  369. static void set_status_code(grpc_call *call, status_source source,
  370. uint32_t status) {
  371. if (call->status[source].is_set) return;
  372. call->status[source].is_set = 1;
  373. call->status[source].code = (grpc_status_code)status;
  374. /* TODO(ctiller): what to do about the flush that was previously here */
  375. }
  376. static void set_compression_algorithm(grpc_call *call,
  377. grpc_compression_algorithm algo) {
  378. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  379. char *error_msg = NULL;
  380. const grpc_compression_options compression_options =
  381. grpc_channel_get_compression_options(call->channel);
  382. /* check if algorithm is known */
  383. if (algo >= GRPC_COMPRESS_ALGORITHMS_COUNT) {
  384. gpr_asprintf(&error_msg, "Invalid compression algorithm value '%d'.", algo);
  385. gpr_log(GPR_ERROR, error_msg);
  386. close_with_status(&exec_ctx, call, GRPC_STATUS_INTERNAL, error_msg);
  387. } else if (grpc_compression_options_is_algorithm_enabled(&compression_options,
  388. algo) == 0) {
  389. /* check if algorithm is supported by current channel config */
  390. char *algo_name;
  391. grpc_compression_algorithm_name(algo, &algo_name);
  392. gpr_asprintf(&error_msg, "Compression algorithm '%s' is disabled.",
  393. algo_name);
  394. gpr_log(GPR_ERROR, error_msg);
  395. close_with_status(&exec_ctx, call, GRPC_STATUS_INTERNAL, error_msg);
  396. } else {
  397. call->compression_algorithm = algo;
  398. }
  399. gpr_free(error_msg);
  400. grpc_exec_ctx_finish(&exec_ctx);
  401. }
  402. grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
  403. grpc_call *call) {
  404. grpc_compression_algorithm algorithm;
  405. gpr_mu_lock(&call->mu);
  406. algorithm = call->compression_algorithm;
  407. gpr_mu_unlock(&call->mu);
  408. return algorithm;
  409. }
  410. uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
  411. uint32_t flags;
  412. gpr_mu_lock(&call->mu);
  413. flags = call->test_only_last_message_flags;
  414. gpr_mu_unlock(&call->mu);
  415. return flags;
  416. }
  417. static void destroy_encodings_accepted_by_peer(void *p) { return; }
  418. static void set_encodings_accepted_by_peer(grpc_call *call, grpc_mdelem *mdel) {
  419. size_t i;
  420. grpc_compression_algorithm algorithm;
  421. gpr_slice_buffer accept_encoding_parts;
  422. gpr_slice accept_encoding_slice;
  423. void *accepted_user_data;
  424. accepted_user_data =
  425. grpc_mdelem_get_user_data(mdel, destroy_encodings_accepted_by_peer);
  426. if (accepted_user_data != NULL) {
  427. call->encodings_accepted_by_peer =
  428. (uint32_t)(((uintptr_t)accepted_user_data) - 1);
  429. return;
  430. }
  431. accept_encoding_slice = mdel->value->slice;
  432. gpr_slice_buffer_init(&accept_encoding_parts);
  433. gpr_slice_split(accept_encoding_slice, ",", &accept_encoding_parts);
  434. /* No need to zero call->encodings_accepted_by_peer: grpc_call_create already
  435. * zeroes the whole grpc_call */
  436. /* Always support no compression */
  437. GPR_BITSET(&call->encodings_accepted_by_peer, GRPC_COMPRESS_NONE);
  438. for (i = 0; i < accept_encoding_parts.count; i++) {
  439. const gpr_slice *accept_encoding_entry_slice =
  440. &accept_encoding_parts.slices[i];
  441. if (grpc_compression_algorithm_parse(
  442. (const char *)GPR_SLICE_START_PTR(*accept_encoding_entry_slice),
  443. GPR_SLICE_LENGTH(*accept_encoding_entry_slice), &algorithm)) {
  444. GPR_BITSET(&call->encodings_accepted_by_peer, algorithm);
  445. } else {
  446. char *accept_encoding_entry_str =
  447. gpr_dump_slice(*accept_encoding_entry_slice, GPR_DUMP_ASCII);
  448. gpr_log(GPR_ERROR,
  449. "Invalid entry in accept encoding metadata: '%s'. Ignoring.",
  450. accept_encoding_entry_str);
  451. gpr_free(accept_encoding_entry_str);
  452. }
  453. }
  454. gpr_slice_buffer_destroy(&accept_encoding_parts);
  455. grpc_mdelem_set_user_data(
  456. mdel, destroy_encodings_accepted_by_peer,
  457. (void *)(((uintptr_t)call->encodings_accepted_by_peer) + 1));
  458. }
  459. uint32_t grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
  460. uint32_t encodings_accepted_by_peer;
  461. gpr_mu_lock(&call->mu);
  462. encodings_accepted_by_peer = call->encodings_accepted_by_peer;
  463. gpr_mu_unlock(&call->mu);
  464. return encodings_accepted_by_peer;
  465. }
  466. static void set_status_details(grpc_call *call, status_source source,
  467. grpc_mdstr *status) {
  468. if (call->status[source].details != NULL) {
  469. GRPC_MDSTR_UNREF(call->status[source].details);
  470. }
  471. call->status[source].details = status;
  472. }
  473. static void get_final_status(grpc_call *call,
  474. void (*set_value)(grpc_status_code code,
  475. void *user_data),
  476. void *set_value_user_data) {
  477. int i;
  478. for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
  479. if (call->status[i].is_set) {
  480. set_value(call->status[i].code, set_value_user_data);
  481. return;
  482. }
  483. }
  484. if (call->is_client) {
  485. set_value(GRPC_STATUS_UNKNOWN, set_value_user_data);
  486. } else {
  487. set_value(GRPC_STATUS_OK, set_value_user_data);
  488. }
  489. }
  490. static void get_final_details(grpc_call *call, char **out_details,
  491. size_t *out_details_capacity) {
  492. int i;
  493. for (i = 0; i < STATUS_SOURCE_COUNT; i++) {
  494. if (call->status[i].is_set) {
  495. if (call->status[i].details) {
  496. gpr_slice details = call->status[i].details->slice;
  497. size_t len = GPR_SLICE_LENGTH(details);
  498. if (len + 1 > *out_details_capacity) {
  499. *out_details_capacity =
  500. GPR_MAX(len + 1, *out_details_capacity * 3 / 2);
  501. *out_details = gpr_realloc(*out_details, *out_details_capacity);
  502. }
  503. memcpy(*out_details, GPR_SLICE_START_PTR(details), len);
  504. (*out_details)[len] = 0;
  505. } else {
  506. goto no_details;
  507. }
  508. return;
  509. }
  510. }
  511. no_details:
  512. if (0 == *out_details_capacity) {
  513. *out_details_capacity = 8;
  514. *out_details = gpr_malloc(*out_details_capacity);
  515. }
  516. **out_details = 0;
  517. }
  518. static grpc_linked_mdelem *linked_from_md(grpc_metadata *md) {
  519. return (grpc_linked_mdelem *)&md->internal_data;
  520. }
  521. static int prepare_application_metadata(grpc_call *call, int count,
  522. grpc_metadata *metadata,
  523. int is_trailing,
  524. int prepend_extra_metadata) {
  525. int i;
  526. grpc_metadata_batch *batch =
  527. &call->metadata_batch[0 /* is_receiving */][is_trailing];
  528. if (prepend_extra_metadata) {
  529. if (call->send_extra_metadata_count == 0) {
  530. prepend_extra_metadata = 0;
  531. } else {
  532. for (i = 0; i < call->send_extra_metadata_count; i++) {
  533. GRPC_MDELEM_REF(call->send_extra_metadata[i].md);
  534. }
  535. for (i = 1; i < call->send_extra_metadata_count; i++) {
  536. call->send_extra_metadata[i].prev = &call->send_extra_metadata[i - 1];
  537. }
  538. for (i = 0; i < call->send_extra_metadata_count - 1; i++) {
  539. call->send_extra_metadata[i].next = &call->send_extra_metadata[i + 1];
  540. }
  541. }
  542. }
  543. for (i = 0; i < count; i++) {
  544. grpc_metadata *md = &metadata[i];
  545. grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
  546. GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
  547. l->md = grpc_mdelem_from_string_and_buffer(
  548. md->key, (const uint8_t *)md->value, md->value_length);
  549. if (!grpc_header_key_is_legal(grpc_mdstr_as_c_string(l->md->key),
  550. GRPC_MDSTR_LENGTH(l->md->key))) {
  551. gpr_log(GPR_ERROR, "attempt to send invalid metadata key: %s",
  552. grpc_mdstr_as_c_string(l->md->key));
  553. return 0;
  554. } else if (!grpc_is_binary_header(grpc_mdstr_as_c_string(l->md->key),
  555. GRPC_MDSTR_LENGTH(l->md->key)) &&
  556. !grpc_header_nonbin_value_is_legal(
  557. grpc_mdstr_as_c_string(l->md->value),
  558. GRPC_MDSTR_LENGTH(l->md->value))) {
  559. gpr_log(GPR_ERROR, "attempt to send invalid metadata value");
  560. return 0;
  561. }
  562. }
  563. for (i = 1; i < count; i++) {
  564. linked_from_md(&metadata[i])->prev = linked_from_md(&metadata[i - 1]);
  565. }
  566. for (i = 0; i < count - 1; i++) {
  567. linked_from_md(&metadata[i])->next = linked_from_md(&metadata[i + 1]);
  568. }
  569. switch (prepend_extra_metadata * 2 + (count != 0)) {
  570. case 0:
  571. /* no prepend, no metadata => nothing to do */
  572. batch->list.head = batch->list.tail = NULL;
  573. break;
  574. case 1:
  575. /* metadata, but no prepend */
  576. batch->list.head = linked_from_md(&metadata[0]);
  577. batch->list.tail = linked_from_md(&metadata[count - 1]);
  578. batch->list.head->prev = NULL;
  579. batch->list.tail->next = NULL;
  580. break;
  581. case 2:
  582. /* prepend, but no md */
  583. batch->list.head = &call->send_extra_metadata[0];
  584. batch->list.tail =
  585. &call->send_extra_metadata[call->send_extra_metadata_count - 1];
  586. batch->list.head->prev = NULL;
  587. batch->list.tail->next = NULL;
  588. break;
  589. case 3:
  590. /* prepend AND md */
  591. batch->list.head = &call->send_extra_metadata[0];
  592. call->send_extra_metadata[call->send_extra_metadata_count - 1].next =
  593. linked_from_md(&metadata[0]);
  594. linked_from_md(&metadata[0])->prev =
  595. &call->send_extra_metadata[call->send_extra_metadata_count - 1];
  596. batch->list.tail = linked_from_md(&metadata[count - 1]);
  597. batch->list.head->prev = NULL;
  598. batch->list.tail->next = NULL;
  599. break;
  600. default:
  601. GPR_UNREACHABLE_CODE(return 0);
  602. }
  603. return 1;
  604. }
  605. void grpc_call_destroy(grpc_call *c) {
  606. int cancel;
  607. grpc_call *parent = c->parent;
  608. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  609. GPR_TIMER_BEGIN("grpc_call_destroy", 0);
  610. GRPC_API_TRACE("grpc_call_destroy(c=%p)", 1, (c));
  611. if (parent) {
  612. gpr_mu_lock(&parent->mu);
  613. if (c == parent->first_child) {
  614. parent->first_child = c->sibling_next;
  615. if (c == parent->first_child) {
  616. parent->first_child = NULL;
  617. }
  618. c->sibling_prev->sibling_next = c->sibling_next;
  619. c->sibling_next->sibling_prev = c->sibling_prev;
  620. }
  621. gpr_mu_unlock(&parent->mu);
  622. GRPC_CALL_INTERNAL_UNREF(&exec_ctx, parent, "child");
  623. }
  624. gpr_mu_lock(&c->mu);
  625. GPR_ASSERT(!c->destroy_called);
  626. c->destroy_called = 1;
  627. if (c->have_alarm) {
  628. grpc_timer_cancel(&exec_ctx, &c->alarm);
  629. }
  630. cancel = !c->received_final_op;
  631. gpr_mu_unlock(&c->mu);
  632. if (cancel) grpc_call_cancel(c, NULL);
  633. GRPC_CALL_INTERNAL_UNREF(&exec_ctx, c, "destroy");
  634. grpc_exec_ctx_finish(&exec_ctx);
  635. GPR_TIMER_END("grpc_call_destroy", 0);
  636. }
  637. grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) {
  638. GRPC_API_TRACE("grpc_call_cancel(call=%p, reserved=%p)", 2, (call, reserved));
  639. GPR_ASSERT(!reserved);
  640. return grpc_call_cancel_with_status(call, GRPC_STATUS_CANCELLED, "Cancelled",
  641. NULL);
  642. }
  643. grpc_call_error grpc_call_cancel_with_status(grpc_call *c,
  644. grpc_status_code status,
  645. const char *description,
  646. void *reserved) {
  647. grpc_call_error r;
  648. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  649. GRPC_API_TRACE(
  650. "grpc_call_cancel_with_status("
  651. "c=%p, status=%d, description=%s, reserved=%p)",
  652. 4, (c, (int)status, description, reserved));
  653. GPR_ASSERT(reserved == NULL);
  654. gpr_mu_lock(&c->mu);
  655. r = cancel_with_status(&exec_ctx, c, status, description);
  656. gpr_mu_unlock(&c->mu);
  657. grpc_exec_ctx_finish(&exec_ctx);
  658. return r;
  659. }
  660. typedef struct termination_closure {
  661. grpc_closure closure;
  662. grpc_call *call;
  663. grpc_status_code status;
  664. gpr_slice optional_message;
  665. grpc_closure *op_closure;
  666. enum { TC_CANCEL, TC_CLOSE } type;
  667. } termination_closure;
  668. static void done_termination(grpc_exec_ctx *exec_ctx, void *tcp, bool success) {
  669. termination_closure *tc = tcp;
  670. if (tc->type == TC_CANCEL) {
  671. GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "cancel");
  672. }
  673. if (tc->type == TC_CLOSE) {
  674. GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "close");
  675. }
  676. gpr_slice_unref(tc->optional_message);
  677. if (tc->op_closure != NULL) {
  678. grpc_exec_ctx_enqueue(exec_ctx, tc->op_closure, false, NULL);
  679. }
  680. gpr_free(tc);
  681. }
  682. static void send_cancel(grpc_exec_ctx *exec_ctx, void *tcp, bool success) {
  683. grpc_transport_stream_op op;
  684. termination_closure *tc = tcp;
  685. memset(&op, 0, sizeof(op));
  686. op.cancel_with_status = tc->status;
  687. /* reuse closure to catch completion */
  688. grpc_closure_init(&tc->closure, done_termination, tc);
  689. op.on_complete = &tc->closure;
  690. execute_op(exec_ctx, tc->call, &op);
  691. }
  692. static void send_close(grpc_exec_ctx *exec_ctx, void *tcp, bool success) {
  693. grpc_transport_stream_op op;
  694. termination_closure *tc = tcp;
  695. memset(&op, 0, sizeof(op));
  696. tc->optional_message = gpr_slice_ref(tc->optional_message);
  697. grpc_transport_stream_op_add_close(&op, tc->status, &tc->optional_message);
  698. /* reuse closure to catch completion */
  699. grpc_closure_init(&tc->closure, done_termination, tc);
  700. tc->op_closure = op.on_complete;
  701. op.on_complete = &tc->closure;
  702. execute_op(exec_ctx, tc->call, &op);
  703. }
  704. static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
  705. termination_closure *tc) {
  706. grpc_mdstr *details = NULL;
  707. if (GPR_SLICE_LENGTH(tc->optional_message) > 0) {
  708. tc->optional_message = gpr_slice_ref(tc->optional_message);
  709. details = grpc_mdstr_from_slice(tc->optional_message);
  710. }
  711. set_status_code(tc->call, STATUS_FROM_API_OVERRIDE, (uint32_t)tc->status);
  712. set_status_details(tc->call, STATUS_FROM_API_OVERRIDE, details);
  713. if (tc->type == TC_CANCEL) {
  714. grpc_closure_init(&tc->closure, send_cancel, tc);
  715. GRPC_CALL_INTERNAL_REF(tc->call, "cancel");
  716. } else if (tc->type == TC_CLOSE) {
  717. grpc_closure_init(&tc->closure, send_close, tc);
  718. GRPC_CALL_INTERNAL_REF(tc->call, "close");
  719. }
  720. grpc_exec_ctx_enqueue(exec_ctx, &tc->closure, true, NULL);
  721. return GRPC_CALL_OK;
  722. }
  723. static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
  724. grpc_status_code status,
  725. const char *description) {
  726. termination_closure *tc = gpr_malloc(sizeof(*tc));
  727. memset(tc, 0, sizeof(termination_closure));
  728. tc->type = TC_CANCEL;
  729. tc->call = c;
  730. tc->optional_message = gpr_slice_from_copied_string(description);
  731. GPR_ASSERT(status != GRPC_STATUS_OK);
  732. tc->status = status;
  733. return terminate_with_status(exec_ctx, tc);
  734. }
  735. static grpc_call_error close_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
  736. grpc_status_code status,
  737. const char *description) {
  738. termination_closure *tc = gpr_malloc(sizeof(*tc));
  739. memset(tc, 0, sizeof(termination_closure));
  740. tc->type = TC_CLOSE;
  741. tc->call = c;
  742. tc->optional_message = gpr_slice_from_copied_string(description);
  743. GPR_ASSERT(status != GRPC_STATUS_OK);
  744. tc->status = status;
  745. return terminate_with_status(exec_ctx, tc);
  746. }
  747. static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
  748. grpc_transport_stream_op *op) {
  749. grpc_call_element *elem;
  750. GPR_TIMER_BEGIN("execute_op", 0);
  751. elem = CALL_ELEM_FROM_CALL(call, 0);
  752. op->context = call->context;
  753. elem->filter->start_transport_stream_op(exec_ctx, elem, op);
  754. GPR_TIMER_END("execute_op", 0);
  755. }
  756. char *grpc_call_get_peer(grpc_call *call) {
  757. grpc_call_element *elem = CALL_ELEM_FROM_CALL(call, 0);
  758. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  759. char *result;
  760. GRPC_API_TRACE("grpc_call_get_peer(%p)", 1, (call));
  761. result = elem->filter->get_peer(&exec_ctx, elem);
  762. if (result == NULL) {
  763. result = grpc_channel_get_target(call->channel);
  764. }
  765. if (result == NULL) {
  766. result = gpr_strdup("unknown");
  767. }
  768. grpc_exec_ctx_finish(&exec_ctx);
  769. return result;
  770. }
  771. grpc_call *grpc_call_from_top_element(grpc_call_element *elem) {
  772. return CALL_FROM_TOP_ELEM(elem);
  773. }
  774. static void call_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
  775. grpc_call *call = arg;
  776. gpr_mu_lock(&call->mu);
  777. call->have_alarm = 0;
  778. if (success) {
  779. cancel_with_status(exec_ctx, call, GRPC_STATUS_DEADLINE_EXCEEDED,
  780. "Deadline Exceeded");
  781. }
  782. gpr_mu_unlock(&call->mu);
  783. GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "alarm");
  784. }
  785. static void set_deadline_alarm(grpc_exec_ctx *exec_ctx, grpc_call *call,
  786. gpr_timespec deadline) {
  787. if (call->have_alarm) {
  788. gpr_log(GPR_ERROR, "Attempt to set deadline alarm twice");
  789. assert(0);
  790. return;
  791. }
  792. GRPC_CALL_INTERNAL_REF(call, "alarm");
  793. call->have_alarm = 1;
  794. call->send_deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
  795. grpc_timer_init(exec_ctx, &call->alarm, call->send_deadline, call_alarm, call,
  796. gpr_now(GPR_CLOCK_MONOTONIC));
  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 uint32_t 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, "Invalid compression algorithm: '%s'", md_c_str);
  829. }
  830. return algorithm;
  831. }
  832. static grpc_mdelem *recv_common_filter(grpc_call *call, grpc_mdelem *elem) {
  833. if (elem->key == GRPC_MDSTR_GRPC_STATUS) {
  834. GPR_TIMER_BEGIN("status", 0);
  835. set_status_code(call, STATUS_FROM_WIRE, decode_status(elem));
  836. GPR_TIMER_END("status", 0);
  837. return NULL;
  838. } else if (elem->key == GRPC_MDSTR_GRPC_MESSAGE) {
  839. GPR_TIMER_BEGIN("status-details", 0);
  840. set_status_details(call, STATUS_FROM_WIRE, GRPC_MDSTR_REF(elem->value));
  841. GPR_TIMER_END("status-details", 0);
  842. return NULL;
  843. }
  844. return elem;
  845. }
  846. static grpc_mdelem *publish_app_metadata(grpc_call *call, grpc_mdelem *elem,
  847. int is_trailing) {
  848. grpc_metadata_array *dest;
  849. grpc_metadata *mdusr;
  850. GPR_TIMER_BEGIN("publish_app_metadata", 0);
  851. dest = call->buffered_metadata[is_trailing];
  852. if (dest->count == dest->capacity) {
  853. dest->capacity = GPR_MAX(dest->capacity + 8, dest->capacity * 2);
  854. dest->metadata =
  855. gpr_realloc(dest->metadata, sizeof(grpc_metadata) * dest->capacity);
  856. }
  857. mdusr = &dest->metadata[dest->count++];
  858. mdusr->key = grpc_mdstr_as_c_string(elem->key);
  859. mdusr->value = grpc_mdstr_as_c_string(elem->value);
  860. mdusr->value_length = GPR_SLICE_LENGTH(elem->value->slice);
  861. GPR_TIMER_END("publish_app_metadata", 0);
  862. return elem;
  863. }
  864. static grpc_mdelem *recv_initial_filter(void *callp, grpc_mdelem *elem) {
  865. grpc_call *call = callp;
  866. elem = recv_common_filter(call, elem);
  867. if (elem == NULL) {
  868. return NULL;
  869. } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
  870. GPR_TIMER_BEGIN("compression_algorithm", 0);
  871. set_compression_algorithm(call, decode_compression(elem));
  872. GPR_TIMER_END("compression_algorithm", 0);
  873. return NULL;
  874. } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
  875. GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
  876. set_encodings_accepted_by_peer(call, elem);
  877. GPR_TIMER_END("encodings_accepted_by_peer", 0);
  878. return NULL;
  879. } else {
  880. return publish_app_metadata(call, elem, 0);
  881. }
  882. }
  883. static grpc_mdelem *recv_trailing_filter(void *callp, grpc_mdelem *elem) {
  884. grpc_call *call = callp;
  885. elem = recv_common_filter(call, elem);
  886. if (elem == NULL) {
  887. return NULL;
  888. } else {
  889. return publish_app_metadata(call, elem, 1);
  890. }
  891. }
  892. grpc_call_stack *grpc_call_get_call_stack(grpc_call *call) {
  893. return CALL_STACK_FROM_CALL(call);
  894. }
  895. /*
  896. * BATCH API IMPLEMENTATION
  897. */
  898. static void set_status_value_directly(grpc_status_code status, void *dest) {
  899. *(grpc_status_code *)dest = status;
  900. }
  901. static void set_cancelled_value(grpc_status_code status, void *dest) {
  902. *(int *)dest = (status != GRPC_STATUS_OK);
  903. }
  904. static bool are_write_flags_valid(uint32_t flags) {
  905. /* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */
  906. const uint32_t allowed_write_positions =
  907. (GRPC_WRITE_USED_MASK | GRPC_WRITE_INTERNAL_USED_MASK);
  908. const uint32_t invalid_positions = ~allowed_write_positions;
  909. return !(flags & invalid_positions);
  910. }
  911. static bool are_initial_metadata_flags_valid(uint32_t flags, bool is_client) {
  912. /* check that only bits in GRPC_WRITE_(INTERNAL?)_USED_MASK are set */
  913. uint32_t invalid_positions = ~GRPC_INITIAL_METADATA_USED_MASK;
  914. if (!is_client) {
  915. invalid_positions |= GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST;
  916. }
  917. return !(flags & invalid_positions);
  918. }
  919. static batch_control *allocate_batch_control(grpc_call *call) {
  920. size_t i;
  921. for (i = 0; i < MAX_CONCURRENT_BATCHES; i++) {
  922. if ((call->used_batches & (1 << i)) == 0) {
  923. call->used_batches = (uint8_t)(call->used_batches | (uint8_t)(1 << i));
  924. return &call->active_batches[i];
  925. }
  926. }
  927. return NULL;
  928. }
  929. static void finish_batch_completion(grpc_exec_ctx *exec_ctx, void *user_data,
  930. grpc_cq_completion *storage) {
  931. batch_control *bctl = user_data;
  932. grpc_call *call = bctl->call;
  933. gpr_mu_lock(&call->mu);
  934. call->used_batches = (uint8_t)(
  935. call->used_batches & ~(uint8_t)(1 << (bctl - call->active_batches)));
  936. gpr_mu_unlock(&call->mu);
  937. GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion");
  938. }
  939. static void post_batch_completion(grpc_exec_ctx *exec_ctx,
  940. batch_control *bctl) {
  941. grpc_call *call = bctl->call;
  942. if (bctl->is_notify_tag_closure) {
  943. grpc_exec_ctx_enqueue(exec_ctx, bctl->notify_tag, bctl->success, NULL);
  944. gpr_mu_lock(&call->mu);
  945. bctl->call->used_batches =
  946. (uint8_t)(bctl->call->used_batches &
  947. ~(uint8_t)(1 << (bctl - bctl->call->active_batches)));
  948. gpr_mu_unlock(&call->mu);
  949. GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "completion");
  950. } else {
  951. grpc_cq_end_op(exec_ctx, bctl->call->cq, bctl->notify_tag, bctl->success,
  952. finish_batch_completion, bctl, &bctl->cq_completion);
  953. }
  954. }
  955. static void continue_receiving_slices(grpc_exec_ctx *exec_ctx,
  956. batch_control *bctl) {
  957. grpc_call *call = bctl->call;
  958. for (;;) {
  959. size_t remaining = call->receiving_stream->length -
  960. (*call->receiving_buffer)->data.raw.slice_buffer.length;
  961. if (remaining == 0) {
  962. call->receiving_message = 0;
  963. grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
  964. call->receiving_stream = NULL;
  965. if (gpr_unref(&bctl->steps_to_complete)) {
  966. post_batch_completion(exec_ctx, bctl);
  967. }
  968. return;
  969. }
  970. if (grpc_byte_stream_next(exec_ctx, call->receiving_stream,
  971. &call->receiving_slice, remaining,
  972. &call->receiving_slice_ready)) {
  973. gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer,
  974. call->receiving_slice);
  975. } else {
  976. return;
  977. }
  978. }
  979. }
  980. static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
  981. bool success) {
  982. batch_control *bctl = bctlp;
  983. grpc_call *call = bctl->call;
  984. if (success) {
  985. gpr_slice_buffer_add(&(*call->receiving_buffer)->data.raw.slice_buffer,
  986. call->receiving_slice);
  987. continue_receiving_slices(exec_ctx, bctl);
  988. } else {
  989. grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
  990. call->receiving_stream = NULL;
  991. grpc_byte_buffer_destroy(*call->receiving_buffer);
  992. *call->receiving_buffer = NULL;
  993. if (gpr_unref(&bctl->steps_to_complete)) {
  994. post_batch_completion(exec_ctx, bctl);
  995. }
  996. }
  997. }
  998. static void process_data_after_md(grpc_exec_ctx *exec_ctx, batch_control *bctl,
  999. bool success) {
  1000. grpc_call *call = bctl->call;
  1001. if (call->receiving_stream == NULL) {
  1002. *call->receiving_buffer = NULL;
  1003. call->receiving_message = 0;
  1004. if (gpr_unref(&bctl->steps_to_complete)) {
  1005. post_batch_completion(exec_ctx, bctl);
  1006. }
  1007. } else if (call->receiving_stream->length >
  1008. grpc_channel_get_max_message_length(call->channel)) {
  1009. cancel_with_status(exec_ctx, call, GRPC_STATUS_INTERNAL,
  1010. "Max message size exceeded");
  1011. grpc_byte_stream_destroy(exec_ctx, call->receiving_stream);
  1012. call->receiving_stream = NULL;
  1013. *call->receiving_buffer = NULL;
  1014. call->receiving_message = 0;
  1015. if (gpr_unref(&bctl->steps_to_complete)) {
  1016. post_batch_completion(exec_ctx, bctl);
  1017. }
  1018. } else {
  1019. call->test_only_last_message_flags = call->receiving_stream->flags;
  1020. if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) &&
  1021. (call->compression_algorithm > GRPC_COMPRESS_NONE)) {
  1022. *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create(
  1023. NULL, 0, call->compression_algorithm);
  1024. } else {
  1025. *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0);
  1026. }
  1027. grpc_closure_init(&call->receiving_slice_ready, receiving_slice_ready,
  1028. bctl);
  1029. continue_receiving_slices(exec_ctx, bctl);
  1030. /* early out */
  1031. return;
  1032. }
  1033. }
  1034. static void receiving_stream_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
  1035. bool success) {
  1036. batch_control *bctl = bctlp;
  1037. grpc_call *call = bctl->call;
  1038. gpr_mu_lock(&bctl->call->mu);
  1039. if (bctl->call->has_initial_md_been_received) {
  1040. gpr_mu_unlock(&bctl->call->mu);
  1041. process_data_after_md(exec_ctx, bctlp, success);
  1042. } else {
  1043. call->saved_receiving_stream_ready_ctx.bctlp = bctlp;
  1044. call->saved_receiving_stream_ready_ctx.success = success;
  1045. gpr_mu_unlock(&bctl->call->mu);
  1046. }
  1047. }
  1048. static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
  1049. void *bctlp, bool success) {
  1050. batch_control *bctl = bctlp;
  1051. grpc_call *call = bctl->call;
  1052. gpr_mu_lock(&call->mu);
  1053. if (!success) {
  1054. bctl->success = false;
  1055. } else {
  1056. grpc_metadata_batch *md =
  1057. &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
  1058. grpc_metadata_batch_filter(md, recv_initial_filter, call);
  1059. if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) !=
  1060. 0 &&
  1061. !call->is_client) {
  1062. GPR_TIMER_BEGIN("set_deadline_alarm", 0);
  1063. set_deadline_alarm(exec_ctx, call, md->deadline);
  1064. GPR_TIMER_END("set_deadline_alarm", 0);
  1065. }
  1066. }
  1067. call->has_initial_md_been_received = true;
  1068. if (call->saved_receiving_stream_ready_ctx.bctlp != NULL) {
  1069. grpc_closure *saved_rsr_closure = grpc_closure_create(
  1070. receiving_stream_ready, call->saved_receiving_stream_ready_ctx.bctlp);
  1071. grpc_exec_ctx_enqueue(
  1072. exec_ctx, saved_rsr_closure,
  1073. call->saved_receiving_stream_ready_ctx.success && success, NULL);
  1074. call->saved_receiving_stream_ready_ctx.bctlp = NULL;
  1075. }
  1076. gpr_mu_unlock(&call->mu);
  1077. if (gpr_unref(&bctl->steps_to_complete)) {
  1078. post_batch_completion(exec_ctx, bctl);
  1079. }
  1080. }
  1081. static void finish_batch(grpc_exec_ctx *exec_ctx, void *bctlp, bool success) {
  1082. batch_control *bctl = bctlp;
  1083. grpc_call *call = bctl->call;
  1084. grpc_call *child_call;
  1085. grpc_call *next_child_call;
  1086. gpr_mu_lock(&call->mu);
  1087. if (bctl->send_initial_metadata) {
  1088. if (!success) {
  1089. set_status_code(call, STATUS_FROM_CORE, GRPC_STATUS_UNAVAILABLE);
  1090. }
  1091. grpc_metadata_batch_destroy(
  1092. &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */]);
  1093. }
  1094. if (bctl->send_message) {
  1095. call->sending_message = 0;
  1096. }
  1097. if (bctl->send_final_op) {
  1098. grpc_metadata_batch_destroy(
  1099. &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */]);
  1100. }
  1101. if (bctl->recv_final_op) {
  1102. grpc_metadata_batch *md =
  1103. &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
  1104. grpc_metadata_batch_filter(md, recv_trailing_filter, call);
  1105. if (call->have_alarm) {
  1106. grpc_timer_cancel(exec_ctx, &call->alarm);
  1107. }
  1108. /* propagate cancellation to any interested children */
  1109. child_call = call->first_child;
  1110. if (child_call != NULL) {
  1111. do {
  1112. next_child_call = child_call->sibling_next;
  1113. if (child_call->cancellation_is_inherited) {
  1114. GRPC_CALL_INTERNAL_REF(child_call, "propagate_cancel");
  1115. grpc_call_cancel(child_call, NULL);
  1116. GRPC_CALL_INTERNAL_UNREF(exec_ctx, child_call, "propagate_cancel");
  1117. }
  1118. child_call = next_child_call;
  1119. } while (child_call != call->first_child);
  1120. }
  1121. if (call->is_client) {
  1122. get_final_status(call, set_status_value_directly,
  1123. call->final_op.client.status);
  1124. get_final_details(call, call->final_op.client.status_details,
  1125. call->final_op.client.status_details_capacity);
  1126. } else {
  1127. get_final_status(call, set_cancelled_value,
  1128. call->final_op.server.cancelled);
  1129. }
  1130. success = 1;
  1131. }
  1132. bctl->success = success != 0;
  1133. gpr_mu_unlock(&call->mu);
  1134. if (gpr_unref(&bctl->steps_to_complete)) {
  1135. post_batch_completion(exec_ctx, bctl);
  1136. }
  1137. }
  1138. static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
  1139. grpc_call *call, const grpc_op *ops,
  1140. size_t nops, void *notify_tag,
  1141. int is_notify_tag_closure) {
  1142. grpc_transport_stream_op stream_op;
  1143. size_t i;
  1144. const grpc_op *op;
  1145. batch_control *bctl;
  1146. int num_completion_callbacks_needed = 1;
  1147. grpc_call_error error = GRPC_CALL_OK;
  1148. GPR_TIMER_BEGIN("grpc_call_start_batch", 0);
  1149. GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, notify_tag);
  1150. memset(&stream_op, 0, sizeof(stream_op));
  1151. /* TODO(ctiller): this feels like it could be made lock-free */
  1152. gpr_mu_lock(&call->mu);
  1153. bctl = allocate_batch_control(call);
  1154. memset(bctl, 0, sizeof(*bctl));
  1155. bctl->call = call;
  1156. bctl->notify_tag = notify_tag;
  1157. bctl->is_notify_tag_closure = (uint8_t)(is_notify_tag_closure != 0);
  1158. if (nops == 0) {
  1159. GRPC_CALL_INTERNAL_REF(call, "completion");
  1160. bctl->success = 1;
  1161. if (!is_notify_tag_closure) {
  1162. grpc_cq_begin_op(call->cq, notify_tag);
  1163. }
  1164. gpr_mu_unlock(&call->mu);
  1165. post_batch_completion(exec_ctx, bctl);
  1166. error = GRPC_CALL_OK;
  1167. goto done;
  1168. }
  1169. /* rewrite batch ops into a transport op */
  1170. for (i = 0; i < nops; i++) {
  1171. op = &ops[i];
  1172. if (op->reserved != NULL) {
  1173. error = GRPC_CALL_ERROR;
  1174. goto done_with_error;
  1175. }
  1176. switch (op->op) {
  1177. case GRPC_OP_SEND_INITIAL_METADATA:
  1178. /* Flag validation: currently allow no flags */
  1179. if (!are_initial_metadata_flags_valid(op->flags, call->is_client)) {
  1180. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1181. goto done_with_error;
  1182. }
  1183. if (call->sent_initial_metadata) {
  1184. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1185. goto done_with_error;
  1186. }
  1187. if (op->data.send_initial_metadata.count > INT_MAX) {
  1188. error = GRPC_CALL_ERROR_INVALID_METADATA;
  1189. goto done_with_error;
  1190. }
  1191. bctl->send_initial_metadata = 1;
  1192. call->sent_initial_metadata = 1;
  1193. if (!prepare_application_metadata(
  1194. call, (int)op->data.send_initial_metadata.count,
  1195. op->data.send_initial_metadata.metadata, 0, call->is_client)) {
  1196. error = GRPC_CALL_ERROR_INVALID_METADATA;
  1197. goto done_with_error;
  1198. }
  1199. /* TODO(ctiller): just make these the same variable? */
  1200. call->metadata_batch[0][0].deadline = call->send_deadline;
  1201. stream_op.send_initial_metadata =
  1202. &call->metadata_batch[0 /* is_receiving */][0 /* is_trailing */];
  1203. stream_op.send_initial_metadata_flags = op->flags;
  1204. break;
  1205. case GRPC_OP_SEND_MESSAGE:
  1206. if (!are_write_flags_valid(op->flags)) {
  1207. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1208. goto done_with_error;
  1209. }
  1210. if (op->data.send_message == NULL) {
  1211. error = GRPC_CALL_ERROR_INVALID_MESSAGE;
  1212. goto done_with_error;
  1213. }
  1214. if (call->sending_message) {
  1215. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1216. goto done_with_error;
  1217. }
  1218. bctl->send_message = 1;
  1219. call->sending_message = 1;
  1220. grpc_slice_buffer_stream_init(
  1221. &call->sending_stream,
  1222. &op->data.send_message->data.raw.slice_buffer, op->flags);
  1223. stream_op.send_message = &call->sending_stream.base;
  1224. break;
  1225. case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
  1226. /* Flag validation: currently allow no flags */
  1227. if (op->flags != 0) {
  1228. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1229. goto done_with_error;
  1230. }
  1231. if (!call->is_client) {
  1232. error = GRPC_CALL_ERROR_NOT_ON_SERVER;
  1233. goto done_with_error;
  1234. }
  1235. if (call->sent_final_op) {
  1236. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1237. goto done_with_error;
  1238. }
  1239. bctl->send_final_op = 1;
  1240. call->sent_final_op = 1;
  1241. stream_op.send_trailing_metadata =
  1242. &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
  1243. break;
  1244. case GRPC_OP_SEND_STATUS_FROM_SERVER:
  1245. /* Flag validation: currently allow no flags */
  1246. if (op->flags != 0) {
  1247. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1248. goto done_with_error;
  1249. }
  1250. if (call->is_client) {
  1251. error = GRPC_CALL_ERROR_NOT_ON_CLIENT;
  1252. goto done_with_error;
  1253. }
  1254. if (call->sent_final_op) {
  1255. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1256. goto done_with_error;
  1257. }
  1258. if (op->data.send_status_from_server.trailing_metadata_count >
  1259. INT_MAX) {
  1260. error = GRPC_CALL_ERROR_INVALID_METADATA;
  1261. goto done_with_error;
  1262. }
  1263. bctl->send_final_op = 1;
  1264. call->sent_final_op = 1;
  1265. call->send_extra_metadata_count = 1;
  1266. call->send_extra_metadata[0].md = grpc_channel_get_reffed_status_elem(
  1267. call->channel, op->data.send_status_from_server.status);
  1268. if (op->data.send_status_from_server.status_details != NULL) {
  1269. call->send_extra_metadata[1].md = grpc_mdelem_from_metadata_strings(
  1270. GRPC_MDSTR_GRPC_MESSAGE,
  1271. grpc_mdstr_from_string(
  1272. op->data.send_status_from_server.status_details));
  1273. call->send_extra_metadata_count++;
  1274. set_status_details(
  1275. call, STATUS_FROM_API_OVERRIDE,
  1276. GRPC_MDSTR_REF(call->send_extra_metadata[1].md->value));
  1277. }
  1278. set_status_code(call, STATUS_FROM_API_OVERRIDE,
  1279. (uint32_t)op->data.send_status_from_server.status);
  1280. if (!prepare_application_metadata(
  1281. call,
  1282. (int)op->data.send_status_from_server.trailing_metadata_count,
  1283. op->data.send_status_from_server.trailing_metadata, 1, 1)) {
  1284. error = GRPC_CALL_ERROR_INVALID_METADATA;
  1285. goto done_with_error;
  1286. }
  1287. stream_op.send_trailing_metadata =
  1288. &call->metadata_batch[0 /* is_receiving */][1 /* is_trailing */];
  1289. break;
  1290. case GRPC_OP_RECV_INITIAL_METADATA:
  1291. /* Flag validation: currently allow no flags */
  1292. if (op->flags != 0) {
  1293. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1294. goto done_with_error;
  1295. }
  1296. if (call->received_initial_metadata) {
  1297. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1298. goto done_with_error;
  1299. }
  1300. call->received_initial_metadata = 1;
  1301. call->buffered_metadata[0] = op->data.recv_initial_metadata;
  1302. grpc_closure_init(&call->receiving_initial_metadata_ready,
  1303. receiving_initial_metadata_ready, bctl);
  1304. bctl->recv_initial_metadata = 1;
  1305. stream_op.recv_initial_metadata =
  1306. &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
  1307. stream_op.recv_initial_metadata_ready =
  1308. &call->receiving_initial_metadata_ready;
  1309. num_completion_callbacks_needed++;
  1310. break;
  1311. case GRPC_OP_RECV_MESSAGE:
  1312. /* Flag validation: currently allow no flags */
  1313. if (op->flags != 0) {
  1314. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1315. goto done_with_error;
  1316. }
  1317. if (call->receiving_message) {
  1318. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1319. goto done_with_error;
  1320. }
  1321. call->receiving_message = 1;
  1322. bctl->recv_message = 1;
  1323. call->receiving_buffer = op->data.recv_message;
  1324. stream_op.recv_message = &call->receiving_stream;
  1325. grpc_closure_init(&call->receiving_stream_ready, receiving_stream_ready,
  1326. bctl);
  1327. stream_op.recv_message_ready = &call->receiving_stream_ready;
  1328. num_completion_callbacks_needed++;
  1329. break;
  1330. case GRPC_OP_RECV_STATUS_ON_CLIENT:
  1331. /* Flag validation: currently allow no flags */
  1332. if (op->flags != 0) {
  1333. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1334. goto done_with_error;
  1335. }
  1336. if (!call->is_client) {
  1337. error = GRPC_CALL_ERROR_NOT_ON_SERVER;
  1338. goto done_with_error;
  1339. }
  1340. if (call->received_final_op) {
  1341. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1342. goto done_with_error;
  1343. }
  1344. call->received_final_op = 1;
  1345. call->buffered_metadata[1] =
  1346. op->data.recv_status_on_client.trailing_metadata;
  1347. call->final_op.client.status = op->data.recv_status_on_client.status;
  1348. call->final_op.client.status_details =
  1349. op->data.recv_status_on_client.status_details;
  1350. call->final_op.client.status_details_capacity =
  1351. op->data.recv_status_on_client.status_details_capacity;
  1352. bctl->recv_final_op = 1;
  1353. stream_op.recv_trailing_metadata =
  1354. &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
  1355. stream_op.collect_stats = &call->stats;
  1356. break;
  1357. case GRPC_OP_RECV_CLOSE_ON_SERVER:
  1358. /* Flag validation: currently allow no flags */
  1359. if (op->flags != 0) {
  1360. error = GRPC_CALL_ERROR_INVALID_FLAGS;
  1361. goto done_with_error;
  1362. }
  1363. if (call->is_client) {
  1364. error = GRPC_CALL_ERROR_NOT_ON_CLIENT;
  1365. goto done_with_error;
  1366. }
  1367. if (call->received_final_op) {
  1368. error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
  1369. goto done_with_error;
  1370. }
  1371. call->received_final_op = 1;
  1372. call->final_op.server.cancelled =
  1373. op->data.recv_close_on_server.cancelled;
  1374. bctl->recv_final_op = 1;
  1375. stream_op.recv_trailing_metadata =
  1376. &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
  1377. stream_op.collect_stats = &call->stats;
  1378. break;
  1379. }
  1380. }
  1381. GRPC_CALL_INTERNAL_REF(call, "completion");
  1382. if (!is_notify_tag_closure) {
  1383. grpc_cq_begin_op(call->cq, notify_tag);
  1384. }
  1385. gpr_ref_init(&bctl->steps_to_complete, num_completion_callbacks_needed);
  1386. stream_op.context = call->context;
  1387. grpc_closure_init(&bctl->finish_batch, finish_batch, bctl);
  1388. stream_op.on_complete = &bctl->finish_batch;
  1389. gpr_mu_unlock(&call->mu);
  1390. execute_op(exec_ctx, call, &stream_op);
  1391. done:
  1392. GPR_TIMER_END("grpc_call_start_batch", 0);
  1393. return error;
  1394. done_with_error:
  1395. /* reverse any mutations that occured */
  1396. if (bctl->send_initial_metadata) {
  1397. call->sent_initial_metadata = 0;
  1398. grpc_metadata_batch_clear(&call->metadata_batch[0][0]);
  1399. }
  1400. if (bctl->send_message) {
  1401. call->sending_message = 0;
  1402. grpc_byte_stream_destroy(exec_ctx, &call->sending_stream.base);
  1403. }
  1404. if (bctl->send_final_op) {
  1405. call->sent_final_op = 0;
  1406. grpc_metadata_batch_clear(&call->metadata_batch[0][1]);
  1407. }
  1408. if (bctl->recv_initial_metadata) {
  1409. call->received_initial_metadata = 0;
  1410. }
  1411. if (bctl->recv_message) {
  1412. call->receiving_message = 0;
  1413. }
  1414. if (bctl->recv_final_op) {
  1415. call->received_final_op = 0;
  1416. }
  1417. gpr_mu_unlock(&call->mu);
  1418. goto done;
  1419. }
  1420. grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
  1421. size_t nops, void *tag, void *reserved) {
  1422. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  1423. grpc_call_error err;
  1424. GRPC_API_TRACE(
  1425. "grpc_call_start_batch(call=%p, ops=%p, nops=%lu, tag=%p, reserved=%p)",
  1426. 5, (call, ops, (unsigned long)nops, tag, reserved));
  1427. if (reserved != NULL) {
  1428. err = GRPC_CALL_ERROR;
  1429. } else {
  1430. err = call_start_batch(&exec_ctx, call, ops, nops, tag, 0);
  1431. }
  1432. grpc_exec_ctx_finish(&exec_ctx);
  1433. return err;
  1434. }
  1435. grpc_call_error grpc_call_start_batch_and_execute(grpc_exec_ctx *exec_ctx,
  1436. grpc_call *call,
  1437. const grpc_op *ops,
  1438. size_t nops,
  1439. grpc_closure *closure) {
  1440. return call_start_batch(exec_ctx, call, ops, nops, closure, 1);
  1441. }
  1442. void grpc_call_context_set(grpc_call *call, grpc_context_index elem,
  1443. void *value, void (*destroy)(void *value)) {
  1444. if (call->context[elem].destroy) {
  1445. call->context[elem].destroy(call->context[elem].value);
  1446. }
  1447. call->context[elem].value = value;
  1448. call->context[elem].destroy = destroy;
  1449. }
  1450. void *grpc_call_context_get(grpc_call *call, grpc_context_index elem) {
  1451. return call->context[elem].value;
  1452. }
  1453. uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; }
  1454. grpc_compression_algorithm grpc_call_compression_for_level(
  1455. grpc_call *call, grpc_compression_level level) {
  1456. gpr_mu_lock(&call->mu);
  1457. const uint32_t accepted_encodings = call->encodings_accepted_by_peer;
  1458. gpr_mu_unlock(&call->mu);
  1459. return grpc_compression_algorithm_for_level(level, accepted_encodings);
  1460. }