completion_queue.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. /*
  2. *
  3. * Copyright 2015-2016, 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 "src/core/lib/surface/completion_queue.h"
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <grpc/support/alloc.h>
  37. #include <grpc/support/atm.h>
  38. #include <grpc/support/log.h>
  39. #include <grpc/support/string_util.h>
  40. #include <grpc/support/time.h>
  41. #include "src/core/lib/iomgr/pollset.h"
  42. #include "src/core/lib/iomgr/timer.h"
  43. #include "src/core/lib/profiling/timers.h"
  44. #include "src/core/lib/support/spinlock.h"
  45. #include "src/core/lib/support/string.h"
  46. #include "src/core/lib/surface/api_trace.h"
  47. #include "src/core/lib/surface/call.h"
  48. #include "src/core/lib/surface/event_string.h"
  49. int grpc_trace_operation_failures;
  50. #ifndef NDEBUG
  51. int grpc_trace_pending_tags;
  52. #endif
  53. typedef struct {
  54. grpc_pollset_worker **worker;
  55. void *tag;
  56. } plucker;
  57. typedef struct {
  58. bool can_get_pollset;
  59. bool can_listen;
  60. size_t (*size)(void);
  61. void (*init)(grpc_pollset *pollset, gpr_mu **mu);
  62. grpc_error *(*kick)(grpc_pollset *pollset,
  63. grpc_pollset_worker *specific_worker);
  64. grpc_error *(*work)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
  65. grpc_pollset_worker **worker, gpr_timespec now,
  66. gpr_timespec deadline);
  67. void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
  68. grpc_closure *closure);
  69. void (*destroy)(grpc_pollset *pollset);
  70. } cq_poller_vtable;
  71. typedef struct non_polling_worker {
  72. gpr_cv cv;
  73. bool kicked;
  74. struct non_polling_worker *next;
  75. struct non_polling_worker *prev;
  76. } non_polling_worker;
  77. typedef struct {
  78. gpr_mu mu;
  79. non_polling_worker *root;
  80. grpc_closure *shutdown;
  81. } non_polling_poller;
  82. static size_t non_polling_poller_size(void) {
  83. return sizeof(non_polling_poller);
  84. }
  85. static void non_polling_poller_init(grpc_pollset *pollset, gpr_mu **mu) {
  86. non_polling_poller *npp = (non_polling_poller *)pollset;
  87. gpr_mu_init(&npp->mu);
  88. *mu = &npp->mu;
  89. }
  90. static void non_polling_poller_destroy(grpc_pollset *pollset) {
  91. non_polling_poller *npp = (non_polling_poller *)pollset;
  92. gpr_mu_destroy(&npp->mu);
  93. }
  94. static grpc_error *non_polling_poller_work(grpc_exec_ctx *exec_ctx,
  95. grpc_pollset *pollset,
  96. grpc_pollset_worker **worker,
  97. gpr_timespec now,
  98. gpr_timespec deadline) {
  99. non_polling_poller *npp = (non_polling_poller *)pollset;
  100. if (npp->shutdown) return GRPC_ERROR_NONE;
  101. non_polling_worker w;
  102. gpr_cv_init(&w.cv);
  103. if (worker != NULL) *worker = (grpc_pollset_worker *)&w;
  104. if (npp->root == NULL) {
  105. npp->root = w.next = w.prev = &w;
  106. } else {
  107. w.next = npp->root;
  108. w.prev = w.next->prev;
  109. w.next->prev = w.prev->next = &w;
  110. }
  111. w.kicked = false;
  112. while (!npp->shutdown && !w.kicked && !gpr_cv_wait(&w.cv, &npp->mu, deadline))
  113. ;
  114. if (&w == npp->root) {
  115. npp->root = w.next;
  116. if (&w == npp->root) {
  117. if (npp->shutdown) {
  118. grpc_closure_sched(exec_ctx, npp->shutdown, GRPC_ERROR_NONE);
  119. }
  120. npp->root = NULL;
  121. }
  122. }
  123. w.next->prev = w.prev;
  124. w.prev->next = w.next;
  125. gpr_cv_destroy(&w.cv);
  126. if (worker != NULL) *worker = NULL;
  127. return GRPC_ERROR_NONE;
  128. }
  129. static grpc_error *non_polling_poller_kick(
  130. grpc_pollset *pollset, grpc_pollset_worker *specific_worker) {
  131. non_polling_poller *p = (non_polling_poller *)pollset;
  132. if (specific_worker == NULL) specific_worker = (grpc_pollset_worker *)p->root;
  133. if (specific_worker != NULL) {
  134. non_polling_worker *w = (non_polling_worker *)specific_worker;
  135. if (!w->kicked) {
  136. w->kicked = true;
  137. gpr_cv_signal(&w->cv);
  138. }
  139. }
  140. return GRPC_ERROR_NONE;
  141. }
  142. static void non_polling_poller_shutdown(grpc_exec_ctx *exec_ctx,
  143. grpc_pollset *pollset,
  144. grpc_closure *closure) {
  145. non_polling_poller *p = (non_polling_poller *)pollset;
  146. GPR_ASSERT(closure != NULL);
  147. p->shutdown = closure;
  148. if (p->root == NULL) {
  149. grpc_closure_sched(exec_ctx, closure, GRPC_ERROR_NONE);
  150. } else {
  151. non_polling_worker *w = p->root;
  152. do {
  153. gpr_cv_signal(&w->cv);
  154. w = w->next;
  155. } while (w != p->root);
  156. }
  157. }
  158. static const cq_poller_vtable g_poller_vtable_by_poller_type[] = {
  159. /* GRPC_CQ_DEFAULT_POLLING */
  160. {.can_get_pollset = true,
  161. .can_listen = true,
  162. .size = grpc_pollset_size,
  163. .init = grpc_pollset_init,
  164. .kick = grpc_pollset_kick,
  165. .work = grpc_pollset_work,
  166. .shutdown = grpc_pollset_shutdown,
  167. .destroy = grpc_pollset_destroy},
  168. /* GRPC_CQ_NON_LISTENING */
  169. {.can_get_pollset = true,
  170. .can_listen = false,
  171. .size = grpc_pollset_size,
  172. .init = grpc_pollset_init,
  173. .kick = grpc_pollset_kick,
  174. .work = grpc_pollset_work,
  175. .shutdown = grpc_pollset_shutdown,
  176. .destroy = grpc_pollset_destroy},
  177. /* GRPC_CQ_NON_POLLING */
  178. {.can_get_pollset = false,
  179. .can_listen = false,
  180. .size = non_polling_poller_size,
  181. .init = non_polling_poller_init,
  182. .kick = non_polling_poller_kick,
  183. .work = non_polling_poller_work,
  184. .shutdown = non_polling_poller_shutdown,
  185. .destroy = non_polling_poller_destroy},
  186. };
  187. /* Queue that holds the cq_completion_events. This internally uses gpr_mpscq
  188. * queue (a lockfree multiproducer single consumer queue). However this queue
  189. * supports multiple consumers too. As such, it uses the queue_mu to serialize
  190. * consumer access (but no locks for producer access).
  191. *
  192. * Currently this is only used in completion queues whose completion_type is
  193. * GRPC_CQ_NEXT */
  194. typedef struct grpc_cq_event_queue {
  195. /* spinlock to serialize consumers i.e pop() operations */
  196. gpr_spinlock queue_lock;
  197. gpr_mpscq queue;
  198. /* A lazy counter indicating the number of items in the queue. This is NOT
  199. atomically incremented/decrements along with push/pop operations and hence
  200. only eventually consistent */
  201. gpr_atm num_queue_items;
  202. } grpc_cq_event_queue;
  203. /* Completion queue structure */
  204. struct grpc_completion_queue {
  205. /** Owned by pollset */
  206. gpr_mu *mu;
  207. grpc_cq_completion_type completion_type;
  208. const cq_poller_vtable *poller_vtable;
  209. /** completed events */
  210. grpc_cq_completion completed_head;
  211. grpc_cq_completion *completed_tail;
  212. /** Completed events for completion-queues of type GRPC_CQ_NEXT are stored in
  213. * this queue */
  214. grpc_cq_event_queue queue;
  215. /** Number of pending events (+1 if we're not shutdown) */
  216. gpr_refcount pending_events;
  217. /** Once owning_refs drops to zero, we will destroy the cq */
  218. gpr_refcount owning_refs;
  219. /** Counter of how many things have ever been queued on this completion queue
  220. useful for avoiding locks to check the queue */
  221. gpr_atm things_queued_ever;
  222. /** 0 initially, 1 once we've begun shutting down */
  223. gpr_atm shutdown;
  224. int shutdown_called;
  225. int is_server_cq;
  226. /** Can the server cq accept incoming channels */
  227. /* TODO: sreek - This will no longer be needed. Use polling_type set */
  228. int is_non_listening_server_cq;
  229. int num_pluckers;
  230. plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
  231. grpc_closure pollset_shutdown_done;
  232. #ifndef NDEBUG
  233. void **outstanding_tags;
  234. size_t outstanding_tag_count;
  235. size_t outstanding_tag_capacity;
  236. #endif
  237. grpc_completion_queue *next_free;
  238. };
  239. #define POLLSET_FROM_CQ(cq) ((grpc_pollset *)(cq + 1))
  240. #define CQ_FROM_POLLSET(ps) (((grpc_completion_queue *)ps) - 1)
  241. int grpc_cq_pluck_trace;
  242. int grpc_cq_event_timeout_trace;
  243. #define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \
  244. if (grpc_api_trace && \
  245. (grpc_cq_pluck_trace || (event)->type != GRPC_QUEUE_TIMEOUT)) { \
  246. char *_ev = grpc_event_string(event); \
  247. gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \
  248. gpr_free(_ev); \
  249. }
  250. static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *cc,
  251. grpc_error *error);
  252. static void cq_event_queue_init(grpc_cq_event_queue *q) {
  253. gpr_mpscq_init(&q->queue);
  254. q->queue_lock = GPR_SPINLOCK_INITIALIZER;
  255. gpr_atm_no_barrier_store(&q->num_queue_items, 0);
  256. }
  257. static void cq_event_queue_destroy(grpc_cq_event_queue *q) {
  258. gpr_mpscq_destroy(&q->queue);
  259. }
  260. static void cq_event_queue_push(grpc_cq_event_queue *q, grpc_cq_completion *c) {
  261. gpr_mpscq_push(&q->queue, (gpr_mpscq_node *)c);
  262. gpr_atm_no_barrier_fetch_add(&q->num_queue_items, 1);
  263. }
  264. static grpc_cq_completion *cq_event_queue_pop(grpc_cq_event_queue *q) {
  265. grpc_cq_completion *c = NULL;
  266. if (gpr_spinlock_trylock(&q->queue_lock)) {
  267. c = (grpc_cq_completion *)gpr_mpscq_pop(&q->queue);
  268. gpr_spinlock_unlock(&q->queue_lock);
  269. }
  270. if (c) {
  271. gpr_atm_no_barrier_fetch_add(&q->num_queue_items, -1);
  272. }
  273. return c;
  274. }
  275. /* Note: The counter is not incremented/decremented atomically with push/pop.
  276. * The count is only eventually consistent */
  277. static long cq_event_queue_num_items(grpc_cq_event_queue *q) {
  278. return (long)gpr_atm_no_barrier_load(&q->num_queue_items);
  279. }
  280. grpc_completion_queue *grpc_completion_queue_create_internal(
  281. grpc_cq_completion_type completion_type,
  282. grpc_cq_polling_type polling_type) {
  283. grpc_completion_queue *cc;
  284. GPR_TIMER_BEGIN("grpc_completion_queue_create_internal", 0);
  285. GRPC_API_TRACE(
  286. "grpc_completion_queue_create_internal(completion_type=%d, "
  287. "polling_type=%d)",
  288. 2, (completion_type, polling_type));
  289. const cq_poller_vtable *poller_vtable =
  290. &g_poller_vtable_by_poller_type[polling_type];
  291. cc = gpr_zalloc(sizeof(grpc_completion_queue) + poller_vtable->size());
  292. poller_vtable->init(POLLSET_FROM_CQ(cc), &cc->mu);
  293. #ifndef NDEBUG
  294. cc->outstanding_tags = NULL;
  295. cc->outstanding_tag_capacity = 0;
  296. #endif
  297. cc->completion_type = completion_type;
  298. cc->poller_vtable = poller_vtable;
  299. /* Initial ref is dropped by grpc_completion_queue_shutdown */
  300. gpr_ref_init(&cc->pending_events, 1);
  301. /* One for destroy(), one for pollset_shutdown */
  302. gpr_ref_init(&cc->owning_refs, 2);
  303. cc->completed_tail = &cc->completed_head;
  304. cc->completed_head.next = (uintptr_t)cc->completed_tail;
  305. gpr_atm_no_barrier_store(&cc->shutdown, 0);
  306. cc->shutdown_called = 0;
  307. cc->is_server_cq = 0;
  308. cc->is_non_listening_server_cq = 0;
  309. cc->num_pluckers = 0;
  310. gpr_atm_no_barrier_store(&cc->things_queued_ever, 0);
  311. #ifndef NDEBUG
  312. cc->outstanding_tag_count = 0;
  313. #endif
  314. cq_event_queue_init(&cc->queue);
  315. grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc,
  316. grpc_schedule_on_exec_ctx);
  317. GPR_TIMER_END("grpc_completion_queue_create_internal", 0);
  318. return cc;
  319. }
  320. grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue *cc) {
  321. return cc->completion_type;
  322. }
  323. #ifdef GRPC_CQ_REF_COUNT_DEBUG
  324. void grpc_cq_internal_ref(grpc_completion_queue *cc, const char *reason,
  325. const char *file, int line) {
  326. gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p ref %d -> %d %s", cc,
  327. (int)cc->owning_refs.count, (int)cc->owning_refs.count + 1, reason);
  328. #else
  329. void grpc_cq_internal_ref(grpc_completion_queue *cc) {
  330. #endif
  331. gpr_ref(&cc->owning_refs);
  332. }
  333. static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *arg,
  334. grpc_error *error) {
  335. grpc_completion_queue *cc = arg;
  336. GRPC_CQ_INTERNAL_UNREF(cc, "pollset_destroy");
  337. }
  338. #ifdef GRPC_CQ_REF_COUNT_DEBUG
  339. void grpc_cq_internal_unref(grpc_completion_queue *cc, const char *reason,
  340. const char *file, int line) {
  341. gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p unref %d -> %d %s", cc,
  342. (int)cc->owning_refs.count, (int)cc->owning_refs.count - 1, reason);
  343. #else
  344. void grpc_cq_internal_unref(grpc_completion_queue *cc) {
  345. #endif
  346. if (gpr_unref(&cc->owning_refs)) {
  347. GPR_ASSERT(cc->completed_head.next == (uintptr_t)&cc->completed_head);
  348. cc->poller_vtable->destroy(POLLSET_FROM_CQ(cc));
  349. cq_event_queue_destroy(&cc->queue);
  350. #ifndef NDEBUG
  351. gpr_free(cc->outstanding_tags);
  352. #endif
  353. gpr_free(cc);
  354. }
  355. }
  356. void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag) {
  357. #ifndef NDEBUG
  358. gpr_mu_lock(cc->mu);
  359. GPR_ASSERT(!cc->shutdown_called);
  360. if (cc->outstanding_tag_count == cc->outstanding_tag_capacity) {
  361. cc->outstanding_tag_capacity = GPR_MAX(4, 2 * cc->outstanding_tag_capacity);
  362. cc->outstanding_tags =
  363. gpr_realloc(cc->outstanding_tags, sizeof(*cc->outstanding_tags) *
  364. cc->outstanding_tag_capacity);
  365. }
  366. cc->outstanding_tags[cc->outstanding_tag_count++] = tag;
  367. gpr_mu_unlock(cc->mu);
  368. #endif
  369. gpr_ref(&cc->pending_events);
  370. }
  371. #ifndef NDEBUG
  372. void check_tag_in_cq(grpc_completion_queue *cc, void *tag, bool lock_cq) {
  373. int found = 0;
  374. if (lock_cq) {
  375. gpr_mu_lock(cc->mu);
  376. }
  377. for (int i = 0; i < (int)cc->outstanding_tag_count; i++) {
  378. if (cc->outstanding_tags[i] == tag) {
  379. cc->outstanding_tag_count--;
  380. GPR_SWAP(void *, cc->outstanding_tags[i],
  381. cc->outstanding_tags[cc->outstanding_tag_count]);
  382. found = 1;
  383. break;
  384. }
  385. }
  386. if (lock_cq) {
  387. gpr_mu_unlock(cc->mu);
  388. }
  389. GPR_ASSERT(found);
  390. }
  391. #else
  392. void check_tag_in_cq(grpc_completion_queue *cc, void *tag, bool lock_cq) {}
  393. #endif
  394. /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a completion
  395. * type of GRPC_CQ_NEXT) */
  396. void grpc_cq_end_op_for_next(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
  397. void *tag, int is_success,
  398. void (*done)(grpc_exec_ctx *exec_ctx,
  399. void *done_arg,
  400. grpc_cq_completion *storage),
  401. void *done_arg, grpc_cq_completion *storage) {
  402. storage->tag = tag;
  403. storage->done = done;
  404. storage->done_arg = done_arg;
  405. storage->next = (uintptr_t)(is_success);
  406. check_tag_in_cq(cc, tag, true); /* Used in debug builds only */
  407. /* Add the completion to the queue */
  408. cq_event_queue_push(&cc->queue, storage);
  409. gpr_atm_no_barrier_fetch_add(&cc->things_queued_ever, 1);
  410. int shutdown = gpr_unref(&cc->pending_events);
  411. if (!shutdown) {
  412. gpr_mu_lock(cc->mu);
  413. grpc_error *kick_error = cc->poller_vtable->kick(POLLSET_FROM_CQ(cc), NULL);
  414. gpr_mu_unlock(cc->mu);
  415. if (kick_error != GRPC_ERROR_NONE) {
  416. const char *msg = grpc_error_string(kick_error);
  417. gpr_log(GPR_ERROR, "Kick failed: %s", msg);
  418. GRPC_ERROR_UNREF(kick_error);
  419. }
  420. } else {
  421. GPR_ASSERT(!gpr_atm_no_barrier_load(&cc->shutdown));
  422. GPR_ASSERT(cc->shutdown_called);
  423. gpr_atm_no_barrier_store(&cc->shutdown, 1);
  424. gpr_mu_lock(cc->mu);
  425. cc->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
  426. &cc->pollset_shutdown_done);
  427. gpr_mu_unlock(cc->mu);
  428. }
  429. }
  430. /* Queue a GRPC_OP_COMPLETED operation to a completion queue (with a completion
  431. * type of GRPC_CQ_PLUCK) */
  432. void grpc_cq_end_op_for_pluck(grpc_exec_ctx *exec_ctx,
  433. grpc_completion_queue *cc, void *tag,
  434. int is_success,
  435. void (*done)(grpc_exec_ctx *exec_ctx,
  436. void *done_arg,
  437. grpc_cq_completion *storage),
  438. void *done_arg, grpc_cq_completion *storage) {
  439. storage->tag = tag;
  440. storage->done = done;
  441. storage->done_arg = done_arg;
  442. storage->next = ((uintptr_t)&cc->completed_head) | ((uintptr_t)(is_success));
  443. gpr_mu_lock(cc->mu);
  444. check_tag_in_cq(cc, tag, false); /* Used in debug builds only */
  445. /* Add to the list of completions */
  446. gpr_atm_no_barrier_fetch_add(&cc->things_queued_ever, 1);
  447. cc->completed_tail->next =
  448. ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next);
  449. cc->completed_tail = storage;
  450. int shutdown = gpr_unref(&cc->pending_events);
  451. if (!shutdown) {
  452. grpc_pollset_worker *pluck_worker = NULL;
  453. for (int i = 0; i < cc->num_pluckers; i++) {
  454. if (cc->pluckers[i].tag == tag) {
  455. pluck_worker = *cc->pluckers[i].worker;
  456. break;
  457. }
  458. }
  459. grpc_error *kick_error =
  460. cc->poller_vtable->kick(POLLSET_FROM_CQ(cc), pluck_worker);
  461. gpr_mu_unlock(cc->mu);
  462. if (kick_error != GRPC_ERROR_NONE) {
  463. const char *msg = grpc_error_string(kick_error);
  464. gpr_log(GPR_ERROR, "Kick failed: %s", msg);
  465. GRPC_ERROR_UNREF(kick_error);
  466. }
  467. } else {
  468. GPR_ASSERT(!gpr_atm_no_barrier_load(&cc->shutdown));
  469. GPR_ASSERT(cc->shutdown_called);
  470. gpr_atm_no_barrier_store(&cc->shutdown, 1);
  471. cc->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
  472. &cc->pollset_shutdown_done);
  473. gpr_mu_unlock(cc->mu);
  474. }
  475. }
  476. /* Signal the end of an operation - if this is the last waiting-to-be-queued
  477. event, then enter shutdown mode */
  478. /* Queue a GRPC_OP_COMPLETED operation */
  479. void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
  480. void *tag, grpc_error *error,
  481. void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg,
  482. grpc_cq_completion *storage),
  483. void *done_arg, grpc_cq_completion *storage) {
  484. GPR_TIMER_BEGIN("grpc_cq_end_op", 0);
  485. if (grpc_api_trace ||
  486. (grpc_trace_operation_failures && error != GRPC_ERROR_NONE)) {
  487. const char *errmsg = grpc_error_string(error);
  488. GRPC_API_TRACE(
  489. "grpc_cq_end_op(exec_ctx=%p, cc=%p, tag=%p, error=%s, done=%p, "
  490. "done_arg=%p, storage=%p)",
  491. 7, (exec_ctx, cc, tag, errmsg, done, done_arg, storage));
  492. if (grpc_trace_operation_failures && error != GRPC_ERROR_NONE) {
  493. gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg);
  494. }
  495. }
  496. /* Call the appropriate function to queue the completion based on the
  497. completion queue type */
  498. int is_success = (error == GRPC_ERROR_NONE);
  499. if (cc->completion_type == GRPC_CQ_NEXT) {
  500. grpc_cq_end_op_for_next(exec_ctx, cc, tag, is_success, done, done_arg,
  501. storage);
  502. } else if (cc->completion_type == GRPC_CQ_PLUCK) {
  503. grpc_cq_end_op_for_pluck(exec_ctx, cc, tag, is_success, done, done_arg,
  504. storage);
  505. } else {
  506. gpr_log(GPR_ERROR, "Unexpected completion type %d", cc->completion_type);
  507. abort();
  508. }
  509. GPR_TIMER_END("grpc_cq_end_op", 0);
  510. GRPC_ERROR_UNREF(error);
  511. }
  512. typedef struct {
  513. gpr_atm last_seen_things_queued_ever;
  514. grpc_completion_queue *cq;
  515. gpr_timespec deadline;
  516. grpc_cq_completion *stolen_completion;
  517. void *tag; /* for pluck */
  518. bool first_loop;
  519. } cq_is_finished_arg;
  520. static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) {
  521. cq_is_finished_arg *a = arg;
  522. grpc_completion_queue *cq = a->cq;
  523. GPR_ASSERT(a->stolen_completion == NULL);
  524. gpr_atm current_last_seen_things_queued_ever =
  525. gpr_atm_no_barrier_load(&cq->things_queued_ever);
  526. if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) {
  527. a->last_seen_things_queued_ever =
  528. gpr_atm_no_barrier_load(&cq->things_queued_ever);
  529. /* Pop a cq_completion from the queue. Returns NULL if the queue is empty
  530. * might return NULL in some cases even if the queue is not empty; but that
  531. * is ok and doesn't affect correctness. Might effect the tail latencies a
  532. * bit) */
  533. a->stolen_completion = cq_event_queue_pop(&cq->queue);
  534. if (a->stolen_completion != NULL) {
  535. return true;
  536. }
  537. }
  538. return !a->first_loop &&
  539. gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0;
  540. }
  541. #ifndef NDEBUG
  542. static void dump_pending_tags(grpc_completion_queue *cc) {
  543. if (!grpc_trace_pending_tags) return;
  544. gpr_strvec v;
  545. gpr_strvec_init(&v);
  546. gpr_strvec_add(&v, gpr_strdup("PENDING TAGS:"));
  547. gpr_mu_lock(cc->mu);
  548. for (size_t i = 0; i < cc->outstanding_tag_count; i++) {
  549. char *s;
  550. gpr_asprintf(&s, " %p", cc->outstanding_tags[i]);
  551. gpr_strvec_add(&v, s);
  552. }
  553. gpr_mu_unlock(cc->mu);
  554. char *out = gpr_strvec_flatten(&v, NULL);
  555. gpr_strvec_destroy(&v);
  556. gpr_log(GPR_DEBUG, "%s", out);
  557. gpr_free(out);
  558. }
  559. #else
  560. static void dump_pending_tags(grpc_completion_queue *cc) {}
  561. #endif
  562. grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
  563. gpr_timespec deadline, void *reserved) {
  564. grpc_event ret;
  565. gpr_timespec now;
  566. if (cc->completion_type != GRPC_CQ_NEXT) {
  567. gpr_log(GPR_ERROR,
  568. "grpc_completion_queue_next() cannot be called on this completion "
  569. "queue since its completion type is not GRPC_CQ_NEXT");
  570. abort();
  571. }
  572. GPR_TIMER_BEGIN("grpc_completion_queue_next", 0);
  573. GRPC_API_TRACE(
  574. "grpc_completion_queue_next("
  575. "cc=%p, "
  576. "deadline=gpr_timespec { tv_sec: %" PRId64
  577. ", tv_nsec: %d, clock_type: %d }, "
  578. "reserved=%p)",
  579. 5, (cc, deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type,
  580. reserved));
  581. GPR_ASSERT(!reserved);
  582. dump_pending_tags(cc);
  583. deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
  584. GRPC_CQ_INTERNAL_REF(cc, "next");
  585. cq_is_finished_arg is_finished_arg = {
  586. .last_seen_things_queued_ever =
  587. gpr_atm_no_barrier_load(&cc->things_queued_ever),
  588. .cq = cc,
  589. .deadline = deadline,
  590. .stolen_completion = NULL,
  591. .tag = NULL,
  592. .first_loop = true};
  593. grpc_exec_ctx exec_ctx =
  594. GRPC_EXEC_CTX_INITIALIZER(0, cq_is_next_finished, &is_finished_arg);
  595. for (;;) {
  596. gpr_timespec iteration_deadline = deadline;
  597. if (is_finished_arg.stolen_completion != NULL) {
  598. grpc_cq_completion *c = is_finished_arg.stolen_completion;
  599. is_finished_arg.stolen_completion = NULL;
  600. ret.type = GRPC_OP_COMPLETE;
  601. ret.success = c->next & 1u;
  602. ret.tag = c->tag;
  603. c->done(&exec_ctx, c->done_arg, c);
  604. break;
  605. }
  606. grpc_cq_completion *c = cq_event_queue_pop(&cc->queue);
  607. if (c != NULL) {
  608. ret.type = GRPC_OP_COMPLETE;
  609. ret.success = c->next & 1u;
  610. ret.tag = c->tag;
  611. c->done(&exec_ctx, c->done_arg, c);
  612. break;
  613. } else {
  614. /* If c == NULL it means either the queue is empty OR in an transient
  615. inconsistent state. If it is the latter, we shold do a 0-timeout poll
  616. so that the thread comes back quickly from poll to make a second
  617. attempt at popping. Not doing this can potentially deadlock this thread
  618. forever (if the deadline is infinity) */
  619. if (cq_event_queue_num_items(&cc->queue) > 0) {
  620. iteration_deadline = gpr_time_0(GPR_CLOCK_MONOTONIC);
  621. }
  622. }
  623. if (gpr_atm_no_barrier_load(&cc->shutdown)) {
  624. /* Before returning, check if the queue has any items left over (since
  625. gpr_mpscq_pop() can sometimes return NULL even if the queue is not
  626. empty. If so, keep retrying but do not return GRPC_QUEUE_SHUTDOWN */
  627. if (cq_event_queue_num_items(&cc->queue) > 0) {
  628. /* Go to the beginning of the loop. No point doing a poll because
  629. (cc->shutdown == true) is only possible when there is no pending work
  630. (i.e cc->pending_events == 0) and any outstanding grpc_cq_completion
  631. events are already queued on this cq */
  632. continue;
  633. }
  634. memset(&ret, 0, sizeof(ret));
  635. ret.type = GRPC_QUEUE_SHUTDOWN;
  636. break;
  637. }
  638. now = gpr_now(GPR_CLOCK_MONOTONIC);
  639. if (!is_finished_arg.first_loop && gpr_time_cmp(now, deadline) >= 0) {
  640. memset(&ret, 0, sizeof(ret));
  641. ret.type = GRPC_QUEUE_TIMEOUT;
  642. dump_pending_tags(cc);
  643. break;
  644. }
  645. /* Check alarms - these are a global resource so we just ping
  646. each time through on every pollset.
  647. May update deadline to ensure timely wakeups. */
  648. if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
  649. GPR_TIMER_MARK("alarm_triggered", 0);
  650. grpc_exec_ctx_flush(&exec_ctx);
  651. continue;
  652. }
  653. /* The main polling work happens in grpc_pollset_work */
  654. gpr_mu_lock(cc->mu);
  655. grpc_error *err = cc->poller_vtable->work(&exec_ctx, POLLSET_FROM_CQ(cc),
  656. NULL, now, iteration_deadline);
  657. gpr_mu_unlock(cc->mu);
  658. if (err != GRPC_ERROR_NONE) {
  659. const char *msg = grpc_error_string(err);
  660. gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg);
  661. GRPC_ERROR_UNREF(err);
  662. memset(&ret, 0, sizeof(ret));
  663. ret.type = GRPC_QUEUE_TIMEOUT;
  664. dump_pending_tags(cc);
  665. break;
  666. }
  667. is_finished_arg.first_loop = false;
  668. }
  669. GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret);
  670. GRPC_CQ_INTERNAL_UNREF(cc, "next");
  671. grpc_exec_ctx_finish(&exec_ctx);
  672. GPR_ASSERT(is_finished_arg.stolen_completion == NULL);
  673. GPR_TIMER_END("grpc_completion_queue_next", 0);
  674. return ret;
  675. }
  676. static int add_plucker(grpc_completion_queue *cc, void *tag,
  677. grpc_pollset_worker **worker) {
  678. if (cc->num_pluckers == GRPC_MAX_COMPLETION_QUEUE_PLUCKERS) {
  679. return 0;
  680. }
  681. cc->pluckers[cc->num_pluckers].tag = tag;
  682. cc->pluckers[cc->num_pluckers].worker = worker;
  683. cc->num_pluckers++;
  684. return 1;
  685. }
  686. static void del_plucker(grpc_completion_queue *cc, void *tag,
  687. grpc_pollset_worker **worker) {
  688. int i;
  689. for (i = 0; i < cc->num_pluckers; i++) {
  690. if (cc->pluckers[i].tag == tag && cc->pluckers[i].worker == worker) {
  691. cc->num_pluckers--;
  692. GPR_SWAP(plucker, cc->pluckers[i], cc->pluckers[cc->num_pluckers]);
  693. return;
  694. }
  695. }
  696. GPR_UNREACHABLE_CODE(return );
  697. }
  698. static bool cq_is_pluck_finished(grpc_exec_ctx *exec_ctx, void *arg) {
  699. cq_is_finished_arg *a = arg;
  700. grpc_completion_queue *cq = a->cq;
  701. GPR_ASSERT(a->stolen_completion == NULL);
  702. gpr_atm current_last_seen_things_queued_ever =
  703. gpr_atm_no_barrier_load(&cq->things_queued_ever);
  704. if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) {
  705. gpr_mu_lock(cq->mu);
  706. a->last_seen_things_queued_ever =
  707. gpr_atm_no_barrier_load(&cq->things_queued_ever);
  708. grpc_cq_completion *c;
  709. grpc_cq_completion *prev = &cq->completed_head;
  710. while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) !=
  711. &cq->completed_head) {
  712. if (c->tag == a->tag) {
  713. prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1);
  714. if (c == cq->completed_tail) {
  715. cq->completed_tail = prev;
  716. }
  717. gpr_mu_unlock(cq->mu);
  718. a->stolen_completion = c;
  719. return true;
  720. }
  721. prev = c;
  722. }
  723. gpr_mu_unlock(cq->mu);
  724. }
  725. return !a->first_loop &&
  726. gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0;
  727. }
  728. grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
  729. gpr_timespec deadline, void *reserved) {
  730. grpc_event ret;
  731. grpc_cq_completion *c;
  732. grpc_cq_completion *prev;
  733. grpc_pollset_worker *worker = NULL;
  734. gpr_timespec now;
  735. GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0);
  736. if (cc->completion_type != GRPC_CQ_PLUCK) {
  737. gpr_log(GPR_ERROR,
  738. "grpc_completion_queue_pluck() cannot be called on this completion "
  739. "queue since its completion type is not GRPC_CQ_PLUCK");
  740. abort();
  741. }
  742. if (grpc_cq_pluck_trace) {
  743. GRPC_API_TRACE(
  744. "grpc_completion_queue_pluck("
  745. "cc=%p, tag=%p, "
  746. "deadline=gpr_timespec { tv_sec: %" PRId64
  747. ", tv_nsec: %d, clock_type: %d }, "
  748. "reserved=%p)",
  749. 6, (cc, tag, deadline.tv_sec, deadline.tv_nsec,
  750. (int)deadline.clock_type, reserved));
  751. }
  752. GPR_ASSERT(!reserved);
  753. dump_pending_tags(cc);
  754. deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
  755. GRPC_CQ_INTERNAL_REF(cc, "pluck");
  756. gpr_mu_lock(cc->mu);
  757. cq_is_finished_arg is_finished_arg = {
  758. .last_seen_things_queued_ever =
  759. gpr_atm_no_barrier_load(&cc->things_queued_ever),
  760. .cq = cc,
  761. .deadline = deadline,
  762. .stolen_completion = NULL,
  763. .tag = tag,
  764. .first_loop = true};
  765. grpc_exec_ctx exec_ctx =
  766. GRPC_EXEC_CTX_INITIALIZER(0, cq_is_pluck_finished, &is_finished_arg);
  767. for (;;) {
  768. if (is_finished_arg.stolen_completion != NULL) {
  769. gpr_mu_unlock(cc->mu);
  770. c = is_finished_arg.stolen_completion;
  771. is_finished_arg.stolen_completion = NULL;
  772. ret.type = GRPC_OP_COMPLETE;
  773. ret.success = c->next & 1u;
  774. ret.tag = c->tag;
  775. c->done(&exec_ctx, c->done_arg, c);
  776. break;
  777. }
  778. prev = &cc->completed_head;
  779. while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) !=
  780. &cc->completed_head) {
  781. if (c->tag == tag) {
  782. prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1);
  783. if (c == cc->completed_tail) {
  784. cc->completed_tail = prev;
  785. }
  786. gpr_mu_unlock(cc->mu);
  787. ret.type = GRPC_OP_COMPLETE;
  788. ret.success = c->next & 1u;
  789. ret.tag = c->tag;
  790. c->done(&exec_ctx, c->done_arg, c);
  791. goto done;
  792. }
  793. prev = c;
  794. }
  795. if (cc->shutdown) {
  796. gpr_mu_unlock(cc->mu);
  797. memset(&ret, 0, sizeof(ret));
  798. ret.type = GRPC_QUEUE_SHUTDOWN;
  799. break;
  800. }
  801. if (!add_plucker(cc, tag, &worker)) {
  802. gpr_log(GPR_DEBUG,
  803. "Too many outstanding grpc_completion_queue_pluck calls: maximum "
  804. "is %d",
  805. GRPC_MAX_COMPLETION_QUEUE_PLUCKERS);
  806. gpr_mu_unlock(cc->mu);
  807. memset(&ret, 0, sizeof(ret));
  808. /* TODO(ctiller): should we use a different result here */
  809. ret.type = GRPC_QUEUE_TIMEOUT;
  810. dump_pending_tags(cc);
  811. break;
  812. }
  813. now = gpr_now(GPR_CLOCK_MONOTONIC);
  814. if (!is_finished_arg.first_loop && gpr_time_cmp(now, deadline) >= 0) {
  815. del_plucker(cc, tag, &worker);
  816. gpr_mu_unlock(cc->mu);
  817. memset(&ret, 0, sizeof(ret));
  818. ret.type = GRPC_QUEUE_TIMEOUT;
  819. dump_pending_tags(cc);
  820. break;
  821. }
  822. /* Check alarms - these are a global resource so we just ping
  823. each time through on every pollset.
  824. May update deadline to ensure timely wakeups.
  825. TODO(ctiller): can this work be localized? */
  826. gpr_timespec iteration_deadline = deadline;
  827. if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
  828. GPR_TIMER_MARK("alarm_triggered", 0);
  829. gpr_mu_unlock(cc->mu);
  830. grpc_exec_ctx_flush(&exec_ctx);
  831. gpr_mu_lock(cc->mu);
  832. } else {
  833. grpc_error *err = cc->poller_vtable->work(
  834. &exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, iteration_deadline);
  835. if (err != GRPC_ERROR_NONE) {
  836. del_plucker(cc, tag, &worker);
  837. gpr_mu_unlock(cc->mu);
  838. const char *msg = grpc_error_string(err);
  839. gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg);
  840. GRPC_ERROR_UNREF(err);
  841. memset(&ret, 0, sizeof(ret));
  842. ret.type = GRPC_QUEUE_TIMEOUT;
  843. dump_pending_tags(cc);
  844. break;
  845. }
  846. }
  847. is_finished_arg.first_loop = false;
  848. del_plucker(cc, tag, &worker);
  849. }
  850. done:
  851. GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret);
  852. GRPC_CQ_INTERNAL_UNREF(cc, "pluck");
  853. grpc_exec_ctx_finish(&exec_ctx);
  854. GPR_ASSERT(is_finished_arg.stolen_completion == NULL);
  855. GPR_TIMER_END("grpc_completion_queue_pluck", 0);
  856. return ret;
  857. }
  858. /* Shutdown simply drops a ref that we reserved at creation time; if we drop
  859. to zero here, then enter shutdown mode and wake up any waiters */
  860. void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
  861. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  862. GPR_TIMER_BEGIN("grpc_completion_queue_shutdown", 0);
  863. GRPC_API_TRACE("grpc_completion_queue_shutdown(cc=%p)", 1, (cc));
  864. gpr_mu_lock(cc->mu);
  865. if (cc->shutdown_called) {
  866. gpr_mu_unlock(cc->mu);
  867. GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
  868. return;
  869. }
  870. cc->shutdown_called = 1;
  871. if (gpr_unref(&cc->pending_events)) {
  872. GPR_ASSERT(!cc->shutdown);
  873. cc->shutdown = 1;
  874. cc->poller_vtable->shutdown(&exec_ctx, POLLSET_FROM_CQ(cc),
  875. &cc->pollset_shutdown_done);
  876. }
  877. gpr_mu_unlock(cc->mu);
  878. grpc_exec_ctx_finish(&exec_ctx);
  879. GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
  880. }
  881. void grpc_completion_queue_destroy(grpc_completion_queue *cc) {
  882. GRPC_API_TRACE("grpc_completion_queue_destroy(cc=%p)", 1, (cc));
  883. GPR_TIMER_BEGIN("grpc_completion_queue_destroy", 0);
  884. grpc_completion_queue_shutdown(cc);
  885. if (cc->completion_type == GRPC_CQ_NEXT) {
  886. GPR_ASSERT(cq_event_queue_num_items(&cc->queue) == 0);
  887. }
  888. GRPC_CQ_INTERNAL_UNREF(cc, "destroy");
  889. GPR_TIMER_END("grpc_completion_queue_destroy", 0);
  890. }
  891. grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
  892. return cc->poller_vtable->can_get_pollset ? POLLSET_FROM_CQ(cc) : NULL;
  893. }
  894. grpc_completion_queue *grpc_cq_from_pollset(grpc_pollset *ps) {
  895. return CQ_FROM_POLLSET(ps);
  896. }
  897. void grpc_cq_mark_non_listening_server_cq(grpc_completion_queue *cc) {
  898. /* TODO: sreek - use cc->polling_type field here and add a validation check
  899. (i.e grpc_cq_mark_non_listening_server_cq can only be called on a cc whose
  900. polling_type is set to GRPC_CQ_NON_LISTENING */
  901. cc->is_non_listening_server_cq = 1;
  902. }
  903. bool grpc_cq_is_non_listening_server_cq(grpc_completion_queue *cc) {
  904. /* TODO (sreek) - return (cc->polling_type == GRPC_CQ_NON_LISTENING) */
  905. return (cc->is_non_listening_server_cq == 1);
  906. }
  907. void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; }
  908. bool grpc_cq_is_server_cq(grpc_completion_queue *cc) {
  909. return cc->is_server_cq;
  910. }
  911. bool grpc_cq_can_listen(grpc_completion_queue *cc) {
  912. return cc->poller_vtable->can_listen;
  913. }