completion_queue.cc 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226
  1. /*
  2. *
  3. * Copyright 2015-2016 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <grpc/support/port_platform.h>
  19. #include "src/core/lib/surface/completion_queue.h"
  20. #include <inttypes.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <grpc/support/alloc.h>
  24. #include <grpc/support/atm.h>
  25. #include <grpc/support/log.h>
  26. #include <grpc/support/string_util.h>
  27. #include <grpc/support/time.h>
  28. #include "src/core/lib/debug/stats.h"
  29. #include "src/core/lib/iomgr/pollset.h"
  30. #include "src/core/lib/iomgr/timer.h"
  31. #include "src/core/lib/profiling/timers.h"
  32. #include "src/core/lib/support/spinlock.h"
  33. #include "src/core/lib/support/string.h"
  34. #include "src/core/lib/surface/api_trace.h"
  35. #include "src/core/lib/surface/call.h"
  36. #include "src/core/lib/surface/event_string.h"
  37. grpc_tracer_flag grpc_trace_operation_failures =
  38. GRPC_TRACER_INITIALIZER(false, "op_failure");
  39. #ifndef NDEBUG
  40. grpc_tracer_flag grpc_trace_pending_tags =
  41. GRPC_TRACER_INITIALIZER(false, "pending_tags");
  42. grpc_tracer_flag grpc_trace_cq_refcount =
  43. GRPC_TRACER_INITIALIZER(false, "cq_refcount");
  44. #endif
  45. typedef struct {
  46. grpc_pollset_worker **worker;
  47. void *tag;
  48. } plucker;
  49. typedef struct {
  50. bool can_get_pollset;
  51. bool can_listen;
  52. size_t (*size)(void);
  53. void (*init)(grpc_pollset *pollset, gpr_mu **mu);
  54. grpc_error *(*kick)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
  55. grpc_pollset_worker *specific_worker);
  56. grpc_error *(*work)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
  57. grpc_pollset_worker **worker, grpc_millis deadline);
  58. void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
  59. grpc_closure *closure);
  60. void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset);
  61. } cq_poller_vtable;
  62. typedef struct non_polling_worker {
  63. gpr_cv cv;
  64. bool kicked;
  65. struct non_polling_worker *next;
  66. struct non_polling_worker *prev;
  67. } non_polling_worker;
  68. typedef struct {
  69. gpr_mu mu;
  70. non_polling_worker *root;
  71. grpc_closure *shutdown;
  72. } non_polling_poller;
  73. static size_t non_polling_poller_size(void) {
  74. return sizeof(non_polling_poller);
  75. }
  76. static void non_polling_poller_init(grpc_pollset *pollset, gpr_mu **mu) {
  77. non_polling_poller *npp = (non_polling_poller *)pollset;
  78. gpr_mu_init(&npp->mu);
  79. *mu = &npp->mu;
  80. }
  81. static void non_polling_poller_destroy(grpc_exec_ctx *exec_ctx,
  82. grpc_pollset *pollset) {
  83. non_polling_poller *npp = (non_polling_poller *)pollset;
  84. gpr_mu_destroy(&npp->mu);
  85. }
  86. static grpc_error *non_polling_poller_work(grpc_exec_ctx *exec_ctx,
  87. grpc_pollset *pollset,
  88. grpc_pollset_worker **worker,
  89. grpc_millis deadline) {
  90. non_polling_poller *npp = (non_polling_poller *)pollset;
  91. if (npp->shutdown) return GRPC_ERROR_NONE;
  92. non_polling_worker w;
  93. gpr_cv_init(&w.cv);
  94. if (worker != NULL) *worker = (grpc_pollset_worker *)&w;
  95. if (npp->root == NULL) {
  96. npp->root = w.next = w.prev = &w;
  97. } else {
  98. w.next = npp->root;
  99. w.prev = w.next->prev;
  100. w.next->prev = w.prev->next = &w;
  101. }
  102. w.kicked = false;
  103. gpr_timespec deadline_ts =
  104. grpc_millis_to_timespec(deadline, GPR_CLOCK_REALTIME);
  105. while (!npp->shutdown && !w.kicked &&
  106. !gpr_cv_wait(&w.cv, &npp->mu, deadline_ts))
  107. ;
  108. if (&w == npp->root) {
  109. npp->root = w.next;
  110. if (&w == npp->root) {
  111. if (npp->shutdown) {
  112. GRPC_CLOSURE_SCHED(exec_ctx, npp->shutdown, GRPC_ERROR_NONE);
  113. }
  114. npp->root = NULL;
  115. }
  116. }
  117. w.next->prev = w.prev;
  118. w.prev->next = w.next;
  119. gpr_cv_destroy(&w.cv);
  120. if (worker != NULL) *worker = NULL;
  121. return GRPC_ERROR_NONE;
  122. }
  123. static grpc_error *non_polling_poller_kick(
  124. grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
  125. grpc_pollset_worker *specific_worker) {
  126. non_polling_poller *p = (non_polling_poller *)pollset;
  127. if (specific_worker == NULL) specific_worker = (grpc_pollset_worker *)p->root;
  128. if (specific_worker != NULL) {
  129. non_polling_worker *w = (non_polling_worker *)specific_worker;
  130. if (!w->kicked) {
  131. w->kicked = true;
  132. gpr_cv_signal(&w->cv);
  133. }
  134. }
  135. return GRPC_ERROR_NONE;
  136. }
  137. static void non_polling_poller_shutdown(grpc_exec_ctx *exec_ctx,
  138. grpc_pollset *pollset,
  139. grpc_closure *closure) {
  140. non_polling_poller *p = (non_polling_poller *)pollset;
  141. GPR_ASSERT(closure != NULL);
  142. p->shutdown = closure;
  143. if (p->root == NULL) {
  144. GRPC_CLOSURE_SCHED(exec_ctx, closure, GRPC_ERROR_NONE);
  145. } else {
  146. non_polling_worker *w = p->root;
  147. do {
  148. gpr_cv_signal(&w->cv);
  149. w = w->next;
  150. } while (w != p->root);
  151. }
  152. }
  153. static const cq_poller_vtable g_poller_vtable_by_poller_type[] = {
  154. /* GRPC_CQ_DEFAULT_POLLING */
  155. {true, true, grpc_pollset_size, grpc_pollset_init, grpc_pollset_kick,
  156. grpc_pollset_work, grpc_pollset_shutdown, grpc_pollset_destroy},
  157. /* GRPC_CQ_NON_LISTENING */
  158. {true, false, grpc_pollset_size, grpc_pollset_init, grpc_pollset_kick,
  159. grpc_pollset_work, grpc_pollset_shutdown, grpc_pollset_destroy},
  160. /* GRPC_CQ_NON_POLLING */
  161. {false, false, non_polling_poller_size, non_polling_poller_init,
  162. non_polling_poller_kick, non_polling_poller_work,
  163. non_polling_poller_shutdown, non_polling_poller_destroy},
  164. };
  165. typedef struct cq_vtable {
  166. grpc_cq_completion_type cq_completion_type;
  167. size_t data_size;
  168. void (*init)(void *data);
  169. void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cq);
  170. void (*destroy)(void *data);
  171. bool (*begin_op)(grpc_completion_queue *cq, void *tag);
  172. void (*end_op)(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cq, void *tag,
  173. grpc_error *error,
  174. void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg,
  175. grpc_cq_completion *storage),
  176. void *done_arg, grpc_cq_completion *storage);
  177. grpc_event (*next)(grpc_completion_queue *cq, gpr_timespec deadline,
  178. void *reserved);
  179. grpc_event (*pluck)(grpc_completion_queue *cq, void *tag,
  180. gpr_timespec deadline, void *reserved);
  181. } cq_vtable;
  182. /* Queue that holds the cq_completion_events. Internally uses gpr_mpscq queue
  183. * (a lockfree multiproducer single consumer queue). It uses a queue_lock
  184. * to support multiple consumers.
  185. * Only used in completion queues whose completion_type is GRPC_CQ_NEXT */
  186. typedef struct grpc_cq_event_queue {
  187. /* Spinlock to serialize consumers i.e pop() operations */
  188. gpr_spinlock queue_lock;
  189. gpr_mpscq queue;
  190. /* A lazy counter of number of items in the queue. This is NOT atomically
  191. incremented/decremented along with push/pop operations and hence is only
  192. eventually consistent */
  193. gpr_atm num_queue_items;
  194. } grpc_cq_event_queue;
  195. typedef struct cq_next_data {
  196. /** Completed events for completion-queues of type GRPC_CQ_NEXT */
  197. grpc_cq_event_queue queue;
  198. /** Counter of how many things have ever been queued on this completion queue
  199. useful for avoiding locks to check the queue */
  200. gpr_atm things_queued_ever;
  201. /* Number of outstanding events (+1 if not shut down) */
  202. gpr_atm pending_events;
  203. /** 0 initially. 1 once we initiated shutdown */
  204. bool shutdown_called;
  205. } cq_next_data;
  206. typedef struct cq_pluck_data {
  207. /** Completed events for completion-queues of type GRPC_CQ_PLUCK */
  208. grpc_cq_completion completed_head;
  209. grpc_cq_completion *completed_tail;
  210. /** Number of pending events (+1 if we're not shutdown) */
  211. gpr_atm pending_events;
  212. /** Counter of how many things have ever been queued on this completion queue
  213. useful for avoiding locks to check the queue */
  214. gpr_atm things_queued_ever;
  215. /** 0 initially. 1 once we completed shutting */
  216. /* TODO: (sreek) This is not needed since (shutdown == 1) if and only if
  217. * (pending_events == 0). So consider removing this in future and use
  218. * pending_events */
  219. gpr_atm shutdown;
  220. /** 0 initially. 1 once we initiated shutdown */
  221. bool shutdown_called;
  222. int num_pluckers;
  223. plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
  224. } cq_pluck_data;
  225. /* Completion queue structure */
  226. struct grpc_completion_queue {
  227. /** Once owning_refs drops to zero, we will destroy the cq */
  228. gpr_refcount owning_refs;
  229. gpr_mu *mu;
  230. const cq_vtable *vtable;
  231. const cq_poller_vtable *poller_vtable;
  232. #ifndef NDEBUG
  233. void **outstanding_tags;
  234. size_t outstanding_tag_count;
  235. size_t outstanding_tag_capacity;
  236. #endif
  237. grpc_closure pollset_shutdown_done;
  238. int num_polls;
  239. };
  240. /* Forward declarations */
  241. static void cq_finish_shutdown_next(grpc_exec_ctx *exec_ctx,
  242. grpc_completion_queue *cq);
  243. static void cq_finish_shutdown_pluck(grpc_exec_ctx *exec_ctx,
  244. grpc_completion_queue *cq);
  245. static void cq_shutdown_next(grpc_exec_ctx *exec_ctx,
  246. grpc_completion_queue *cq);
  247. static void cq_shutdown_pluck(grpc_exec_ctx *exec_ctx,
  248. grpc_completion_queue *cq);
  249. static bool cq_begin_op_for_next(grpc_completion_queue *cq, void *tag);
  250. static bool cq_begin_op_for_pluck(grpc_completion_queue *cq, void *tag);
  251. static void cq_end_op_for_next(grpc_exec_ctx *exec_ctx,
  252. grpc_completion_queue *cq, void *tag,
  253. grpc_error *error,
  254. void (*done)(grpc_exec_ctx *exec_ctx,
  255. void *done_arg,
  256. grpc_cq_completion *storage),
  257. void *done_arg, grpc_cq_completion *storage);
  258. static void cq_end_op_for_pluck(grpc_exec_ctx *exec_ctx,
  259. grpc_completion_queue *cq, void *tag,
  260. grpc_error *error,
  261. void (*done)(grpc_exec_ctx *exec_ctx,
  262. void *done_arg,
  263. grpc_cq_completion *storage),
  264. void *done_arg, grpc_cq_completion *storage);
  265. static grpc_event cq_next(grpc_completion_queue *cq, gpr_timespec deadline,
  266. void *reserved);
  267. static grpc_event cq_pluck(grpc_completion_queue *cq, void *tag,
  268. gpr_timespec deadline, void *reserved);
  269. static void cq_init_next(void *data);
  270. static void cq_init_pluck(void *data);
  271. static void cq_destroy_next(void *data);
  272. static void cq_destroy_pluck(void *data);
  273. /* Completion queue vtables based on the completion-type */
  274. static const cq_vtable g_cq_vtable[] = {
  275. /* GRPC_CQ_NEXT */
  276. {GRPC_CQ_NEXT, sizeof(cq_next_data), cq_init_next, cq_shutdown_next,
  277. cq_destroy_next, cq_begin_op_for_next, cq_end_op_for_next, cq_next, NULL},
  278. /* GRPC_CQ_PLUCK */
  279. {GRPC_CQ_PLUCK, sizeof(cq_pluck_data), cq_init_pluck, cq_shutdown_pluck,
  280. cq_destroy_pluck, cq_begin_op_for_pluck, cq_end_op_for_pluck, NULL,
  281. cq_pluck},
  282. };
  283. #define DATA_FROM_CQ(cq) ((void *)(cq + 1))
  284. #define POLLSET_FROM_CQ(cq) \
  285. ((grpc_pollset *)(cq->vtable->data_size + (char *)DATA_FROM_CQ(cq)))
  286. grpc_tracer_flag grpc_cq_pluck_trace =
  287. GRPC_TRACER_INITIALIZER(true, "queue_pluck");
  288. grpc_tracer_flag grpc_cq_event_timeout_trace =
  289. GRPC_TRACER_INITIALIZER(true, "queue_timeout");
  290. #define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \
  291. if (GRPC_TRACER_ON(grpc_api_trace) && \
  292. (GRPC_TRACER_ON(grpc_cq_pluck_trace) || \
  293. (event)->type != GRPC_QUEUE_TIMEOUT)) { \
  294. char *_ev = grpc_event_string(event); \
  295. gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \
  296. gpr_free(_ev); \
  297. }
  298. static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *cq,
  299. grpc_error *error);
  300. static void cq_event_queue_init(grpc_cq_event_queue *q) {
  301. gpr_mpscq_init(&q->queue);
  302. q->queue_lock = GPR_SPINLOCK_INITIALIZER;
  303. gpr_atm_no_barrier_store(&q->num_queue_items, 0);
  304. }
  305. static void cq_event_queue_destroy(grpc_cq_event_queue *q) {
  306. gpr_mpscq_destroy(&q->queue);
  307. }
  308. static bool cq_event_queue_push(grpc_cq_event_queue *q, grpc_cq_completion *c) {
  309. gpr_mpscq_push(&q->queue, (gpr_mpscq_node *)c);
  310. return gpr_atm_no_barrier_fetch_add(&q->num_queue_items, 1) == 0;
  311. }
  312. static grpc_cq_completion *cq_event_queue_pop(grpc_cq_event_queue *q) {
  313. grpc_cq_completion *c = NULL;
  314. if (gpr_spinlock_trylock(&q->queue_lock)) {
  315. c = (grpc_cq_completion *)gpr_mpscq_pop(&q->queue);
  316. gpr_spinlock_unlock(&q->queue_lock);
  317. }
  318. if (c) {
  319. gpr_atm_no_barrier_fetch_add(&q->num_queue_items, -1);
  320. }
  321. return c;
  322. }
  323. /* Note: The counter is not incremented/decremented atomically with push/pop.
  324. * The count is only eventually consistent */
  325. static long cq_event_queue_num_items(grpc_cq_event_queue *q) {
  326. return (long)gpr_atm_no_barrier_load(&q->num_queue_items);
  327. }
  328. grpc_completion_queue *grpc_completion_queue_create_internal(
  329. grpc_cq_completion_type completion_type,
  330. grpc_cq_polling_type polling_type) {
  331. grpc_completion_queue *cq;
  332. GPR_TIMER_BEGIN("grpc_completion_queue_create_internal", 0);
  333. GRPC_API_TRACE(
  334. "grpc_completion_queue_create_internal(completion_type=%d, "
  335. "polling_type=%d)",
  336. 2, (completion_type, polling_type));
  337. const cq_vtable *vtable = &g_cq_vtable[completion_type];
  338. const cq_poller_vtable *poller_vtable =
  339. &g_poller_vtable_by_poller_type[polling_type];
  340. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  341. GRPC_STATS_INC_CQS_CREATED(&exec_ctx);
  342. grpc_exec_ctx_finish(&exec_ctx);
  343. cq = (grpc_completion_queue *)gpr_zalloc(sizeof(grpc_completion_queue) +
  344. vtable->data_size +
  345. poller_vtable->size());
  346. cq->vtable = vtable;
  347. cq->poller_vtable = poller_vtable;
  348. /* One for destroy(), one for pollset_shutdown */
  349. gpr_ref_init(&cq->owning_refs, 2);
  350. poller_vtable->init(POLLSET_FROM_CQ(cq), &cq->mu);
  351. vtable->init(DATA_FROM_CQ(cq));
  352. GRPC_CLOSURE_INIT(&cq->pollset_shutdown_done, on_pollset_shutdown_done, cq,
  353. grpc_schedule_on_exec_ctx);
  354. GPR_TIMER_END("grpc_completion_queue_create_internal", 0);
  355. return cq;
  356. }
  357. static void cq_init_next(void *ptr) {
  358. cq_next_data *cqd = (cq_next_data *)ptr;
  359. /* Initial count is dropped by grpc_completion_queue_shutdown */
  360. gpr_atm_no_barrier_store(&cqd->pending_events, 1);
  361. cqd->shutdown_called = false;
  362. gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0);
  363. cq_event_queue_init(&cqd->queue);
  364. }
  365. static void cq_destroy_next(void *ptr) {
  366. cq_next_data *cqd = (cq_next_data *)ptr;
  367. GPR_ASSERT(cq_event_queue_num_items(&cqd->queue) == 0);
  368. cq_event_queue_destroy(&cqd->queue);
  369. }
  370. static void cq_init_pluck(void *ptr) {
  371. cq_pluck_data *cqd = (cq_pluck_data *)ptr;
  372. /* Initial count is dropped by grpc_completion_queue_shutdown */
  373. gpr_atm_no_barrier_store(&cqd->pending_events, 1);
  374. cqd->completed_tail = &cqd->completed_head;
  375. cqd->completed_head.next = (uintptr_t)cqd->completed_tail;
  376. gpr_atm_no_barrier_store(&cqd->shutdown, 0);
  377. cqd->shutdown_called = false;
  378. cqd->num_pluckers = 0;
  379. gpr_atm_no_barrier_store(&cqd->things_queued_ever, 0);
  380. }
  381. static void cq_destroy_pluck(void *ptr) {
  382. cq_pluck_data *cqd = (cq_pluck_data *)ptr;
  383. GPR_ASSERT(cqd->completed_head.next == (uintptr_t)&cqd->completed_head);
  384. }
  385. grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue *cq) {
  386. return cq->vtable->cq_completion_type;
  387. }
  388. int grpc_get_cq_poll_num(grpc_completion_queue *cq) {
  389. int cur_num_polls;
  390. gpr_mu_lock(cq->mu);
  391. cur_num_polls = cq->num_polls;
  392. gpr_mu_unlock(cq->mu);
  393. return cur_num_polls;
  394. }
  395. #ifndef NDEBUG
  396. void grpc_cq_internal_ref(grpc_completion_queue *cq, const char *reason,
  397. const char *file, int line) {
  398. if (GRPC_TRACER_ON(grpc_trace_cq_refcount)) {
  399. gpr_atm val = gpr_atm_no_barrier_load(&cq->owning_refs.count);
  400. gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
  401. "CQ:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", cq, val, val + 1,
  402. reason);
  403. }
  404. #else
  405. void grpc_cq_internal_ref(grpc_completion_queue *cq) {
  406. #endif
  407. gpr_ref(&cq->owning_refs);
  408. }
  409. static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *arg,
  410. grpc_error *error) {
  411. grpc_completion_queue *cq = (grpc_completion_queue *)arg;
  412. GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "pollset_destroy");
  413. }
  414. #ifndef NDEBUG
  415. void grpc_cq_internal_unref(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cq,
  416. const char *reason, const char *file, int line) {
  417. if (GRPC_TRACER_ON(grpc_trace_cq_refcount)) {
  418. gpr_atm val = gpr_atm_no_barrier_load(&cq->owning_refs.count);
  419. gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
  420. "CQ:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", cq, val, val - 1,
  421. reason);
  422. }
  423. #else
  424. void grpc_cq_internal_unref(grpc_exec_ctx *exec_ctx,
  425. grpc_completion_queue *cq) {
  426. #endif
  427. if (gpr_unref(&cq->owning_refs)) {
  428. cq->vtable->destroy(DATA_FROM_CQ(cq));
  429. cq->poller_vtable->destroy(exec_ctx, POLLSET_FROM_CQ(cq));
  430. #ifndef NDEBUG
  431. gpr_free(cq->outstanding_tags);
  432. #endif
  433. gpr_free(cq);
  434. }
  435. }
  436. #ifndef NDEBUG
  437. static void cq_check_tag(grpc_completion_queue *cq, void *tag, bool lock_cq) {
  438. int found = 0;
  439. if (lock_cq) {
  440. gpr_mu_lock(cq->mu);
  441. }
  442. for (int i = 0; i < (int)cq->outstanding_tag_count; i++) {
  443. if (cq->outstanding_tags[i] == tag) {
  444. cq->outstanding_tag_count--;
  445. GPR_SWAP(void *, cq->outstanding_tags[i],
  446. cq->outstanding_tags[cq->outstanding_tag_count]);
  447. found = 1;
  448. break;
  449. }
  450. }
  451. if (lock_cq) {
  452. gpr_mu_unlock(cq->mu);
  453. }
  454. GPR_ASSERT(found);
  455. }
  456. #else
  457. static void cq_check_tag(grpc_completion_queue *cq, void *tag, bool lock_cq) {}
  458. #endif
  459. /* Atomically increments a counter only if the counter is not zero. Returns
  460. * true if the increment was successful; false if the counter is zero */
  461. static bool atm_inc_if_nonzero(gpr_atm *counter) {
  462. while (true) {
  463. gpr_atm count = gpr_atm_acq_load(counter);
  464. /* If zero, we are done. If not, we must to a CAS (instead of an atomic
  465. * increment) to maintain the contract: do not increment the counter if it
  466. * is zero. */
  467. if (count == 0) {
  468. return false;
  469. } else if (gpr_atm_full_cas(counter, count, count + 1)) {
  470. break;
  471. }
  472. }
  473. return true;
  474. }
  475. static bool cq_begin_op_for_next(grpc_completion_queue *cq, void *tag) {
  476. cq_next_data *cqd = (cq_next_data *)DATA_FROM_CQ(cq);
  477. return atm_inc_if_nonzero(&cqd->pending_events);
  478. }
  479. static bool cq_begin_op_for_pluck(grpc_completion_queue *cq, void *tag) {
  480. cq_pluck_data *cqd = (cq_pluck_data *)DATA_FROM_CQ(cq);
  481. return atm_inc_if_nonzero(&cqd->pending_events);
  482. }
  483. bool grpc_cq_begin_op(grpc_completion_queue *cq, void *tag) {
  484. #ifndef NDEBUG
  485. gpr_mu_lock(cq->mu);
  486. if (cq->outstanding_tag_count == cq->outstanding_tag_capacity) {
  487. cq->outstanding_tag_capacity = GPR_MAX(4, 2 * cq->outstanding_tag_capacity);
  488. cq->outstanding_tags = (void **)gpr_realloc(
  489. cq->outstanding_tags,
  490. sizeof(*cq->outstanding_tags) * cq->outstanding_tag_capacity);
  491. }
  492. cq->outstanding_tags[cq->outstanding_tag_count++] = tag;
  493. gpr_mu_unlock(cq->mu);
  494. #endif
  495. return cq->vtable->begin_op(cq, tag);
  496. }
  497. /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a
  498. * completion
  499. * type of GRPC_CQ_NEXT) */
  500. static void cq_end_op_for_next(grpc_exec_ctx *exec_ctx,
  501. grpc_completion_queue *cq, void *tag,
  502. grpc_error *error,
  503. void (*done)(grpc_exec_ctx *exec_ctx,
  504. void *done_arg,
  505. grpc_cq_completion *storage),
  506. void *done_arg, grpc_cq_completion *storage) {
  507. GPR_TIMER_BEGIN("cq_end_op_for_next", 0);
  508. if (GRPC_TRACER_ON(grpc_api_trace) ||
  509. (GRPC_TRACER_ON(grpc_trace_operation_failures) &&
  510. error != GRPC_ERROR_NONE)) {
  511. const char *errmsg = grpc_error_string(error);
  512. GRPC_API_TRACE(
  513. "cq_end_op_for_next(exec_ctx=%p, cq=%p, tag=%p, error=%s, "
  514. "done=%p, done_arg=%p, storage=%p)",
  515. 7, (exec_ctx, cq, tag, errmsg, done, done_arg, storage));
  516. if (GRPC_TRACER_ON(grpc_trace_operation_failures) &&
  517. error != GRPC_ERROR_NONE) {
  518. gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg);
  519. }
  520. }
  521. cq_next_data *cqd = (cq_next_data *)DATA_FROM_CQ(cq);
  522. int is_success = (error == GRPC_ERROR_NONE);
  523. storage->tag = tag;
  524. storage->done = done;
  525. storage->done_arg = done_arg;
  526. storage->next = (uintptr_t)(is_success);
  527. cq_check_tag(cq, tag, true); /* Used in debug builds only */
  528. /* Add the completion to the queue */
  529. bool is_first = cq_event_queue_push(&cqd->queue, storage);
  530. gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1);
  531. /* Since we do not hold the cq lock here, it is important to do an 'acquire'
  532. load here (instead of a 'no_barrier' load) to match with the release store
  533. (done via gpr_atm_full_fetch_add(pending_events, -1)) in cq_shutdown_next
  534. */
  535. bool will_definitely_shutdown = gpr_atm_acq_load(&cqd->pending_events) == 1;
  536. if (!will_definitely_shutdown) {
  537. /* Only kick if this is the first item queued */
  538. if (is_first) {
  539. gpr_mu_lock(cq->mu);
  540. grpc_error *kick_error =
  541. cq->poller_vtable->kick(exec_ctx, POLLSET_FROM_CQ(cq), NULL);
  542. gpr_mu_unlock(cq->mu);
  543. if (kick_error != GRPC_ERROR_NONE) {
  544. const char *msg = grpc_error_string(kick_error);
  545. gpr_log(GPR_ERROR, "Kick failed: %s", msg);
  546. GRPC_ERROR_UNREF(kick_error);
  547. }
  548. }
  549. if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) {
  550. GRPC_CQ_INTERNAL_REF(cq, "shutting_down");
  551. gpr_mu_lock(cq->mu);
  552. cq_finish_shutdown_next(exec_ctx, cq);
  553. gpr_mu_unlock(cq->mu);
  554. GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "shutting_down");
  555. }
  556. } else {
  557. GRPC_CQ_INTERNAL_REF(cq, "shutting_down");
  558. gpr_atm_rel_store(&cqd->pending_events, 0);
  559. gpr_mu_lock(cq->mu);
  560. cq_finish_shutdown_next(exec_ctx, cq);
  561. gpr_mu_unlock(cq->mu);
  562. GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "shutting_down");
  563. }
  564. GPR_TIMER_END("cq_end_op_for_next", 0);
  565. GRPC_ERROR_UNREF(error);
  566. }
  567. /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a
  568. * completion
  569. * type of GRPC_CQ_PLUCK) */
  570. static void cq_end_op_for_pluck(grpc_exec_ctx *exec_ctx,
  571. grpc_completion_queue *cq, void *tag,
  572. grpc_error *error,
  573. void (*done)(grpc_exec_ctx *exec_ctx,
  574. void *done_arg,
  575. grpc_cq_completion *storage),
  576. void *done_arg, grpc_cq_completion *storage) {
  577. cq_pluck_data *cqd = (cq_pluck_data *)DATA_FROM_CQ(cq);
  578. int is_success = (error == GRPC_ERROR_NONE);
  579. GPR_TIMER_BEGIN("cq_end_op_for_pluck", 0);
  580. if (GRPC_TRACER_ON(grpc_api_trace) ||
  581. (GRPC_TRACER_ON(grpc_trace_operation_failures) &&
  582. error != GRPC_ERROR_NONE)) {
  583. const char *errmsg = grpc_error_string(error);
  584. GRPC_API_TRACE(
  585. "cq_end_op_for_pluck(exec_ctx=%p, cq=%p, tag=%p, error=%s, "
  586. "done=%p, done_arg=%p, storage=%p)",
  587. 7, (exec_ctx, cq, tag, errmsg, done, done_arg, storage));
  588. if (GRPC_TRACER_ON(grpc_trace_operation_failures) &&
  589. error != GRPC_ERROR_NONE) {
  590. gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg);
  591. }
  592. }
  593. storage->tag = tag;
  594. storage->done = done;
  595. storage->done_arg = done_arg;
  596. storage->next = ((uintptr_t)&cqd->completed_head) | ((uintptr_t)(is_success));
  597. gpr_mu_lock(cq->mu);
  598. cq_check_tag(cq, tag, false); /* Used in debug builds only */
  599. /* Add to the list of completions */
  600. gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1);
  601. cqd->completed_tail->next =
  602. ((uintptr_t)storage) | (1u & (uintptr_t)cqd->completed_tail->next);
  603. cqd->completed_tail = storage;
  604. if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) {
  605. cq_finish_shutdown_pluck(exec_ctx, cq);
  606. gpr_mu_unlock(cq->mu);
  607. } else {
  608. grpc_pollset_worker *pluck_worker = NULL;
  609. for (int i = 0; i < cqd->num_pluckers; i++) {
  610. if (cqd->pluckers[i].tag == tag) {
  611. pluck_worker = *cqd->pluckers[i].worker;
  612. break;
  613. }
  614. }
  615. grpc_error *kick_error =
  616. cq->poller_vtable->kick(exec_ctx, POLLSET_FROM_CQ(cq), pluck_worker);
  617. gpr_mu_unlock(cq->mu);
  618. if (kick_error != GRPC_ERROR_NONE) {
  619. const char *msg = grpc_error_string(kick_error);
  620. gpr_log(GPR_ERROR, "Kick failed: %s", msg);
  621. GRPC_ERROR_UNREF(kick_error);
  622. }
  623. }
  624. GPR_TIMER_END("cq_end_op_for_pluck", 0);
  625. GRPC_ERROR_UNREF(error);
  626. }
  627. void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cq,
  628. void *tag, grpc_error *error,
  629. void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg,
  630. grpc_cq_completion *storage),
  631. void *done_arg, grpc_cq_completion *storage) {
  632. cq->vtable->end_op(exec_ctx, cq, tag, error, done, done_arg, storage);
  633. }
  634. typedef struct {
  635. gpr_atm last_seen_things_queued_ever;
  636. grpc_completion_queue *cq;
  637. grpc_millis deadline;
  638. grpc_cq_completion *stolen_completion;
  639. void *tag; /* for pluck */
  640. bool first_loop;
  641. } cq_is_finished_arg;
  642. static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) {
  643. cq_is_finished_arg *a = (cq_is_finished_arg *)arg;
  644. grpc_completion_queue *cq = a->cq;
  645. cq_next_data *cqd = (cq_next_data *)DATA_FROM_CQ(cq);
  646. GPR_ASSERT(a->stolen_completion == NULL);
  647. gpr_atm current_last_seen_things_queued_ever =
  648. gpr_atm_no_barrier_load(&cqd->things_queued_ever);
  649. if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) {
  650. a->last_seen_things_queued_ever =
  651. gpr_atm_no_barrier_load(&cqd->things_queued_ever);
  652. /* Pop a cq_completion from the queue. Returns NULL if the queue is empty
  653. * might return NULL in some cases even if the queue is not empty; but
  654. * that
  655. * is ok and doesn't affect correctness. Might effect the tail latencies a
  656. * bit) */
  657. a->stolen_completion = cq_event_queue_pop(&cqd->queue);
  658. if (a->stolen_completion != NULL) {
  659. return true;
  660. }
  661. }
  662. return !a->first_loop && a->deadline < grpc_exec_ctx_now(exec_ctx);
  663. }
  664. #ifndef NDEBUG
  665. static void dump_pending_tags(grpc_completion_queue *cq) {
  666. if (!GRPC_TRACER_ON(grpc_trace_pending_tags)) return;
  667. gpr_strvec v;
  668. gpr_strvec_init(&v);
  669. gpr_strvec_add(&v, gpr_strdup("PENDING TAGS:"));
  670. gpr_mu_lock(cq->mu);
  671. for (size_t i = 0; i < cq->outstanding_tag_count; i++) {
  672. char *s;
  673. gpr_asprintf(&s, " %p", cq->outstanding_tags[i]);
  674. gpr_strvec_add(&v, s);
  675. }
  676. gpr_mu_unlock(cq->mu);
  677. char *out = gpr_strvec_flatten(&v, NULL);
  678. gpr_strvec_destroy(&v);
  679. gpr_log(GPR_DEBUG, "%s", out);
  680. gpr_free(out);
  681. }
  682. #else
  683. static void dump_pending_tags(grpc_completion_queue *cq) {}
  684. #endif
  685. static grpc_event cq_next(grpc_completion_queue *cq, gpr_timespec deadline,
  686. void *reserved) {
  687. grpc_event ret;
  688. cq_next_data *cqd = (cq_next_data *)DATA_FROM_CQ(cq);
  689. GPR_TIMER_BEGIN("grpc_completion_queue_next", 0);
  690. GRPC_API_TRACE(
  691. "grpc_completion_queue_next("
  692. "cq=%p, "
  693. "deadline=gpr_timespec { tv_sec: %" PRId64
  694. ", tv_nsec: %d, clock_type: %d }, "
  695. "reserved=%p)",
  696. 5, (cq, deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type,
  697. reserved));
  698. GPR_ASSERT(!reserved);
  699. dump_pending_tags(cq);
  700. GRPC_CQ_INTERNAL_REF(cq, "next");
  701. grpc_millis deadline_millis = grpc_timespec_to_millis_round_up(deadline);
  702. cq_is_finished_arg is_finished_arg = {
  703. gpr_atm_no_barrier_load(&cqd->things_queued_ever),
  704. cq,
  705. deadline_millis,
  706. NULL,
  707. NULL,
  708. true};
  709. grpc_exec_ctx exec_ctx =
  710. GRPC_EXEC_CTX_INITIALIZER(0, cq_is_next_finished, &is_finished_arg);
  711. for (;;) {
  712. grpc_millis iteration_deadline = deadline_millis;
  713. if (is_finished_arg.stolen_completion != NULL) {
  714. grpc_cq_completion *c = is_finished_arg.stolen_completion;
  715. is_finished_arg.stolen_completion = NULL;
  716. ret.type = GRPC_OP_COMPLETE;
  717. ret.success = c->next & 1u;
  718. ret.tag = c->tag;
  719. c->done(&exec_ctx, c->done_arg, c);
  720. break;
  721. }
  722. grpc_cq_completion *c = cq_event_queue_pop(&cqd->queue);
  723. if (c != NULL) {
  724. ret.type = GRPC_OP_COMPLETE;
  725. ret.success = c->next & 1u;
  726. ret.tag = c->tag;
  727. c->done(&exec_ctx, c->done_arg, c);
  728. break;
  729. } else {
  730. /* If c == NULL it means either the queue is empty OR in an transient
  731. inconsistent state. If it is the latter, we shold do a 0-timeout poll
  732. so that the thread comes back quickly from poll to make a second
  733. attempt at popping. Not doing this can potentially deadlock this
  734. thread forever (if the deadline is infinity) */
  735. if (cq_event_queue_num_items(&cqd->queue) > 0) {
  736. iteration_deadline = 0;
  737. }
  738. }
  739. if (gpr_atm_acq_load(&cqd->pending_events) == 0) {
  740. /* Before returning, check if the queue has any items left over (since
  741. gpr_mpscq_pop() can sometimes return NULL even if the queue is not
  742. empty. If so, keep retrying but do not return GRPC_QUEUE_SHUTDOWN */
  743. if (cq_event_queue_num_items(&cqd->queue) > 0) {
  744. /* Go to the beginning of the loop. No point doing a poll because
  745. (cq->shutdown == true) is only possible when there is no pending
  746. work (i.e cq->pending_events == 0) and any outstanding completion
  747. events should have already been queued on this cq */
  748. continue;
  749. }
  750. memset(&ret, 0, sizeof(ret));
  751. ret.type = GRPC_QUEUE_SHUTDOWN;
  752. break;
  753. }
  754. if (!is_finished_arg.first_loop &&
  755. grpc_exec_ctx_now(&exec_ctx) >= deadline_millis) {
  756. memset(&ret, 0, sizeof(ret));
  757. ret.type = GRPC_QUEUE_TIMEOUT;
  758. dump_pending_tags(cq);
  759. break;
  760. }
  761. /* The main polling work happens in grpc_pollset_work */
  762. gpr_mu_lock(cq->mu);
  763. cq->num_polls++;
  764. grpc_error *err = cq->poller_vtable->work(&exec_ctx, POLLSET_FROM_CQ(cq),
  765. NULL, iteration_deadline);
  766. gpr_mu_unlock(cq->mu);
  767. if (err != GRPC_ERROR_NONE) {
  768. const char *msg = grpc_error_string(err);
  769. gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg);
  770. GRPC_ERROR_UNREF(err);
  771. memset(&ret, 0, sizeof(ret));
  772. ret.type = GRPC_QUEUE_TIMEOUT;
  773. dump_pending_tags(cq);
  774. break;
  775. }
  776. is_finished_arg.first_loop = false;
  777. }
  778. if (cq_event_queue_num_items(&cqd->queue) > 0 &&
  779. gpr_atm_acq_load(&cqd->pending_events) > 0) {
  780. gpr_mu_lock(cq->mu);
  781. cq->poller_vtable->kick(&exec_ctx, POLLSET_FROM_CQ(cq), NULL);
  782. gpr_mu_unlock(cq->mu);
  783. }
  784. GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, &ret);
  785. GRPC_CQ_INTERNAL_UNREF(&exec_ctx, cq, "next");
  786. grpc_exec_ctx_finish(&exec_ctx);
  787. GPR_ASSERT(is_finished_arg.stolen_completion == NULL);
  788. GPR_TIMER_END("grpc_completion_queue_next", 0);
  789. return ret;
  790. }
  791. /* Finishes the completion queue shutdown. This means that there are no more
  792. completion events / tags expected from the completion queue
  793. - Must be called under completion queue lock
  794. - Must be called only once in completion queue's lifetime
  795. - grpc_completion_queue_shutdown() MUST have been called before calling
  796. this function */
  797. static void cq_finish_shutdown_next(grpc_exec_ctx *exec_ctx,
  798. grpc_completion_queue *cq) {
  799. cq_next_data *cqd = (cq_next_data *)DATA_FROM_CQ(cq);
  800. GPR_ASSERT(cqd->shutdown_called);
  801. GPR_ASSERT(gpr_atm_no_barrier_load(&cqd->pending_events) == 0);
  802. cq->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cq),
  803. &cq->pollset_shutdown_done);
  804. }
  805. static void cq_shutdown_next(grpc_exec_ctx *exec_ctx,
  806. grpc_completion_queue *cq) {
  807. cq_next_data *cqd = (cq_next_data *)DATA_FROM_CQ(cq);
  808. /* Need an extra ref for cq here because:
  809. * We call cq_finish_shutdown_next() below, that would call pollset shutdown.
  810. * Pollset shutdown decrements the cq ref count which can potentially destroy
  811. * the cq (if that happens to be the last ref).
  812. * Creating an extra ref here prevents the cq from getting destroyed while
  813. * this function is still active */
  814. GRPC_CQ_INTERNAL_REF(cq, "shutting_down");
  815. gpr_mu_lock(cq->mu);
  816. if (cqd->shutdown_called) {
  817. gpr_mu_unlock(cq->mu);
  818. GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "shutting_down");
  819. return;
  820. }
  821. cqd->shutdown_called = true;
  822. /* Doing a full_fetch_add (i.e acq/release) here to match with
  823. * cq_begin_op_for_next and and cq_end_op_for_next functions which read/write
  824. * on this counter without necessarily holding a lock on cq */
  825. if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) {
  826. cq_finish_shutdown_next(exec_ctx, cq);
  827. }
  828. gpr_mu_unlock(cq->mu);
  829. GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "shutting_down");
  830. }
  831. grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
  832. gpr_timespec deadline, void *reserved) {
  833. return cq->vtable->next(cq, deadline, reserved);
  834. }
  835. static int add_plucker(grpc_completion_queue *cq, void *tag,
  836. grpc_pollset_worker **worker) {
  837. cq_pluck_data *cqd = (cq_pluck_data *)DATA_FROM_CQ(cq);
  838. if (cqd->num_pluckers == GRPC_MAX_COMPLETION_QUEUE_PLUCKERS) {
  839. return 0;
  840. }
  841. cqd->pluckers[cqd->num_pluckers].tag = tag;
  842. cqd->pluckers[cqd->num_pluckers].worker = worker;
  843. cqd->num_pluckers++;
  844. return 1;
  845. }
  846. static void del_plucker(grpc_completion_queue *cq, void *tag,
  847. grpc_pollset_worker **worker) {
  848. cq_pluck_data *cqd = (cq_pluck_data *)DATA_FROM_CQ(cq);
  849. for (int i = 0; i < cqd->num_pluckers; i++) {
  850. if (cqd->pluckers[i].tag == tag && cqd->pluckers[i].worker == worker) {
  851. cqd->num_pluckers--;
  852. GPR_SWAP(plucker, cqd->pluckers[i], cqd->pluckers[cqd->num_pluckers]);
  853. return;
  854. }
  855. }
  856. GPR_UNREACHABLE_CODE(return );
  857. }
  858. static bool cq_is_pluck_finished(grpc_exec_ctx *exec_ctx, void *arg) {
  859. cq_is_finished_arg *a = (cq_is_finished_arg *)arg;
  860. grpc_completion_queue *cq = a->cq;
  861. cq_pluck_data *cqd = (cq_pluck_data *)DATA_FROM_CQ(cq);
  862. GPR_ASSERT(a->stolen_completion == NULL);
  863. gpr_atm current_last_seen_things_queued_ever =
  864. gpr_atm_no_barrier_load(&cqd->things_queued_ever);
  865. if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) {
  866. gpr_mu_lock(cq->mu);
  867. a->last_seen_things_queued_ever =
  868. gpr_atm_no_barrier_load(&cqd->things_queued_ever);
  869. grpc_cq_completion *c;
  870. grpc_cq_completion *prev = &cqd->completed_head;
  871. while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) !=
  872. &cqd->completed_head) {
  873. if (c->tag == a->tag) {
  874. prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1);
  875. if (c == cqd->completed_tail) {
  876. cqd->completed_tail = prev;
  877. }
  878. gpr_mu_unlock(cq->mu);
  879. a->stolen_completion = c;
  880. return true;
  881. }
  882. prev = c;
  883. }
  884. gpr_mu_unlock(cq->mu);
  885. }
  886. return !a->first_loop && a->deadline < grpc_exec_ctx_now(exec_ctx);
  887. }
  888. static grpc_event cq_pluck(grpc_completion_queue *cq, void *tag,
  889. gpr_timespec deadline, void *reserved) {
  890. grpc_event ret;
  891. grpc_cq_completion *c;
  892. grpc_cq_completion *prev;
  893. grpc_pollset_worker *worker = NULL;
  894. cq_pluck_data *cqd = (cq_pluck_data *)DATA_FROM_CQ(cq);
  895. GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0);
  896. if (GRPC_TRACER_ON(grpc_cq_pluck_trace)) {
  897. GRPC_API_TRACE(
  898. "grpc_completion_queue_pluck("
  899. "cq=%p, tag=%p, "
  900. "deadline=gpr_timespec { tv_sec: %" PRId64
  901. ", tv_nsec: %d, clock_type: %d }, "
  902. "reserved=%p)",
  903. 6, (cq, tag, deadline.tv_sec, deadline.tv_nsec,
  904. (int)deadline.clock_type, reserved));
  905. }
  906. GPR_ASSERT(!reserved);
  907. dump_pending_tags(cq);
  908. GRPC_CQ_INTERNAL_REF(cq, "pluck");
  909. gpr_mu_lock(cq->mu);
  910. grpc_millis deadline_millis = grpc_timespec_to_millis_round_up(deadline);
  911. cq_is_finished_arg is_finished_arg = {
  912. gpr_atm_no_barrier_load(&cqd->things_queued_ever),
  913. cq,
  914. deadline_millis,
  915. NULL,
  916. tag,
  917. true};
  918. grpc_exec_ctx exec_ctx =
  919. GRPC_EXEC_CTX_INITIALIZER(0, cq_is_pluck_finished, &is_finished_arg);
  920. for (;;) {
  921. if (is_finished_arg.stolen_completion != NULL) {
  922. gpr_mu_unlock(cq->mu);
  923. c = is_finished_arg.stolen_completion;
  924. is_finished_arg.stolen_completion = NULL;
  925. ret.type = GRPC_OP_COMPLETE;
  926. ret.success = c->next & 1u;
  927. ret.tag = c->tag;
  928. c->done(&exec_ctx, c->done_arg, c);
  929. break;
  930. }
  931. prev = &cqd->completed_head;
  932. while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) !=
  933. &cqd->completed_head) {
  934. if (c->tag == tag) {
  935. prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1);
  936. if (c == cqd->completed_tail) {
  937. cqd->completed_tail = prev;
  938. }
  939. gpr_mu_unlock(cq->mu);
  940. ret.type = GRPC_OP_COMPLETE;
  941. ret.success = c->next & 1u;
  942. ret.tag = c->tag;
  943. c->done(&exec_ctx, c->done_arg, c);
  944. goto done;
  945. }
  946. prev = c;
  947. }
  948. if (gpr_atm_no_barrier_load(&cqd->shutdown)) {
  949. gpr_mu_unlock(cq->mu);
  950. memset(&ret, 0, sizeof(ret));
  951. ret.type = GRPC_QUEUE_SHUTDOWN;
  952. break;
  953. }
  954. if (!add_plucker(cq, tag, &worker)) {
  955. gpr_log(GPR_DEBUG,
  956. "Too many outstanding grpc_completion_queue_pluck calls: maximum "
  957. "is %d",
  958. GRPC_MAX_COMPLETION_QUEUE_PLUCKERS);
  959. gpr_mu_unlock(cq->mu);
  960. memset(&ret, 0, sizeof(ret));
  961. /* TODO(ctiller): should we use a different result here */
  962. ret.type = GRPC_QUEUE_TIMEOUT;
  963. dump_pending_tags(cq);
  964. break;
  965. }
  966. if (!is_finished_arg.first_loop &&
  967. grpc_exec_ctx_now(&exec_ctx) >= deadline_millis) {
  968. del_plucker(cq, tag, &worker);
  969. gpr_mu_unlock(cq->mu);
  970. memset(&ret, 0, sizeof(ret));
  971. ret.type = GRPC_QUEUE_TIMEOUT;
  972. dump_pending_tags(cq);
  973. break;
  974. }
  975. cq->num_polls++;
  976. grpc_error *err = cq->poller_vtable->work(&exec_ctx, POLLSET_FROM_CQ(cq),
  977. &worker, deadline_millis);
  978. if (err != GRPC_ERROR_NONE) {
  979. del_plucker(cq, tag, &worker);
  980. gpr_mu_unlock(cq->mu);
  981. const char *msg = grpc_error_string(err);
  982. gpr_log(GPR_ERROR, "Completion queue pluck failed: %s", msg);
  983. GRPC_ERROR_UNREF(err);
  984. memset(&ret, 0, sizeof(ret));
  985. ret.type = GRPC_QUEUE_TIMEOUT;
  986. dump_pending_tags(cq);
  987. break;
  988. }
  989. is_finished_arg.first_loop = false;
  990. del_plucker(cq, tag, &worker);
  991. }
  992. done:
  993. GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, &ret);
  994. GRPC_CQ_INTERNAL_UNREF(&exec_ctx, cq, "pluck");
  995. grpc_exec_ctx_finish(&exec_ctx);
  996. GPR_ASSERT(is_finished_arg.stolen_completion == NULL);
  997. GPR_TIMER_END("grpc_completion_queue_pluck", 0);
  998. return ret;
  999. }
  1000. grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
  1001. gpr_timespec deadline, void *reserved) {
  1002. return cq->vtable->pluck(cq, tag, deadline, reserved);
  1003. }
  1004. static void cq_finish_shutdown_pluck(grpc_exec_ctx *exec_ctx,
  1005. grpc_completion_queue *cq) {
  1006. cq_pluck_data *cqd = (cq_pluck_data *)DATA_FROM_CQ(cq);
  1007. GPR_ASSERT(cqd->shutdown_called);
  1008. GPR_ASSERT(!gpr_atm_no_barrier_load(&cqd->shutdown));
  1009. gpr_atm_no_barrier_store(&cqd->shutdown, 1);
  1010. cq->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cq),
  1011. &cq->pollset_shutdown_done);
  1012. }
  1013. /* NOTE: This function is almost exactly identical to cq_shutdown_next() but
  1014. * merging them is a bit tricky and probably not worth it */
  1015. static void cq_shutdown_pluck(grpc_exec_ctx *exec_ctx,
  1016. grpc_completion_queue *cq) {
  1017. cq_pluck_data *cqd = (cq_pluck_data *)DATA_FROM_CQ(cq);
  1018. /* Need an extra ref for cq here because:
  1019. * We call cq_finish_shutdown_pluck() below, that would call pollset shutdown.
  1020. * Pollset shutdown decrements the cq ref count which can potentially destroy
  1021. * the cq (if that happens to be the last ref).
  1022. * Creating an extra ref here prevents the cq from getting destroyed while
  1023. * this function is still active */
  1024. GRPC_CQ_INTERNAL_REF(cq, "shutting_down (pluck cq)");
  1025. gpr_mu_lock(cq->mu);
  1026. if (cqd->shutdown_called) {
  1027. gpr_mu_unlock(cq->mu);
  1028. GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "shutting_down (pluck cq)");
  1029. return;
  1030. }
  1031. cqd->shutdown_called = true;
  1032. if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) {
  1033. cq_finish_shutdown_pluck(exec_ctx, cq);
  1034. }
  1035. gpr_mu_unlock(cq->mu);
  1036. GRPC_CQ_INTERNAL_UNREF(exec_ctx, cq, "shutting_down (pluck cq)");
  1037. }
  1038. /* Shutdown simply drops a ref that we reserved at creation time; if we drop
  1039. to zero here, then enter shutdown mode and wake up any waiters */
  1040. void grpc_completion_queue_shutdown(grpc_completion_queue *cq) {
  1041. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  1042. GPR_TIMER_BEGIN("grpc_completion_queue_shutdown", 0);
  1043. GRPC_API_TRACE("grpc_completion_queue_shutdown(cq=%p)", 1, (cq));
  1044. cq->vtable->shutdown(&exec_ctx, cq);
  1045. grpc_exec_ctx_finish(&exec_ctx);
  1046. GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
  1047. }
  1048. void grpc_completion_queue_destroy(grpc_completion_queue *cq) {
  1049. GRPC_API_TRACE("grpc_completion_queue_destroy(cq=%p)", 1, (cq));
  1050. GPR_TIMER_BEGIN("grpc_completion_queue_destroy", 0);
  1051. grpc_completion_queue_shutdown(cq);
  1052. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  1053. GRPC_CQ_INTERNAL_UNREF(&exec_ctx, cq, "destroy");
  1054. grpc_exec_ctx_finish(&exec_ctx);
  1055. GPR_TIMER_END("grpc_completion_queue_destroy", 0);
  1056. }
  1057. grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cq) {
  1058. return cq->poller_vtable->can_get_pollset ? POLLSET_FROM_CQ(cq) : NULL;
  1059. }
  1060. bool grpc_cq_can_listen(grpc_completion_queue *cq) {
  1061. return cq->poller_vtable->can_listen;
  1062. }