completion_queue.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  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/string.h"
  45. #include "src/core/lib/surface/api_trace.h"
  46. #include "src/core/lib/surface/call.h"
  47. #include "src/core/lib/surface/event_string.h"
  48. int grpc_trace_operation_failures;
  49. #ifndef NDEBUG
  50. int grpc_trace_pending_tags;
  51. #endif
  52. typedef struct {
  53. grpc_pollset_worker **worker;
  54. void *tag;
  55. } plucker;
  56. typedef struct {
  57. bool can_get_pollset;
  58. bool can_listen;
  59. size_t (*size)(void);
  60. void (*init)(grpc_pollset *pollset, gpr_mu **mu);
  61. grpc_error *(*kick)(grpc_pollset *pollset,
  62. grpc_pollset_worker *specific_worker);
  63. grpc_error *(*work)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
  64. grpc_pollset_worker **worker, gpr_timespec now,
  65. gpr_timespec deadline);
  66. void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
  67. grpc_closure *closure);
  68. void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset);
  69. } cq_poller_vtable;
  70. typedef struct non_polling_worker {
  71. gpr_cv cv;
  72. bool kicked;
  73. struct non_polling_worker *next;
  74. struct non_polling_worker *prev;
  75. } non_polling_worker;
  76. typedef struct {
  77. gpr_mu mu;
  78. non_polling_worker *root;
  79. grpc_closure *shutdown;
  80. } non_polling_poller;
  81. static size_t non_polling_poller_size(void) {
  82. return sizeof(non_polling_poller);
  83. }
  84. static void non_polling_poller_init(grpc_pollset *pollset, gpr_mu **mu) {
  85. non_polling_poller *npp = (non_polling_poller *)pollset;
  86. gpr_mu_init(&npp->mu);
  87. *mu = &npp->mu;
  88. }
  89. static void non_polling_poller_destroy(grpc_exec_ctx *exec_ctx,
  90. 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. /* Completion queue structure */
  188. struct grpc_completion_queue {
  189. /** owned by pollset */
  190. gpr_mu *mu;
  191. grpc_cq_completion_type completion_type;
  192. const cq_poller_vtable *poller_vtable;
  193. /** completed events */
  194. grpc_cq_completion completed_head;
  195. grpc_cq_completion *completed_tail;
  196. /** Number of pending events (+1 if we're not shutdown) */
  197. gpr_refcount pending_events;
  198. /** Once owning_refs drops to zero, we will destroy the cq */
  199. gpr_refcount owning_refs;
  200. /** counter of how many things have ever been queued on this completion queue
  201. useful for avoiding locks to check the queue */
  202. gpr_atm things_queued_ever;
  203. /** 0 initially, 1 once we've begun shutting down */
  204. int shutdown;
  205. int shutdown_called;
  206. int is_server_cq;
  207. /** Can the server cq accept incoming channels */
  208. /* TODO: sreek - This will no longer be needed. Use polling_type set */
  209. int is_non_listening_server_cq;
  210. int num_pluckers;
  211. plucker pluckers[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
  212. grpc_closure pollset_shutdown_done;
  213. #ifndef NDEBUG
  214. void **outstanding_tags;
  215. size_t outstanding_tag_count;
  216. size_t outstanding_tag_capacity;
  217. #endif
  218. grpc_completion_queue *next_free;
  219. };
  220. #define POLLSET_FROM_CQ(cq) ((grpc_pollset *)(cq + 1))
  221. #define CQ_FROM_POLLSET(ps) (((grpc_completion_queue *)ps) - 1)
  222. int grpc_cq_pluck_trace;
  223. int grpc_cq_event_timeout_trace;
  224. #define GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, event) \
  225. if (grpc_api_trace && \
  226. (grpc_cq_pluck_trace || (event)->type != GRPC_QUEUE_TIMEOUT)) { \
  227. char *_ev = grpc_event_string(event); \
  228. gpr_log(GPR_INFO, "RETURN_EVENT[%p]: %s", cq, _ev); \
  229. gpr_free(_ev); \
  230. }
  231. static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *cc,
  232. grpc_error *error);
  233. grpc_completion_queue *grpc_completion_queue_create_internal(
  234. grpc_cq_completion_type completion_type,
  235. grpc_cq_polling_type polling_type) {
  236. grpc_completion_queue *cc;
  237. GPR_TIMER_BEGIN("grpc_completion_queue_create_internal", 0);
  238. GRPC_API_TRACE(
  239. "grpc_completion_queue_create_internal(completion_type=%d, "
  240. "polling_type=%d)",
  241. 2, (completion_type, polling_type));
  242. const cq_poller_vtable *poller_vtable =
  243. &g_poller_vtable_by_poller_type[polling_type];
  244. cc = gpr_zalloc(sizeof(grpc_completion_queue) + poller_vtable->size());
  245. poller_vtable->init(POLLSET_FROM_CQ(cc), &cc->mu);
  246. #ifndef NDEBUG
  247. cc->outstanding_tags = NULL;
  248. cc->outstanding_tag_capacity = 0;
  249. #endif
  250. cc->completion_type = completion_type;
  251. cc->poller_vtable = poller_vtable;
  252. /* Initial ref is dropped by grpc_completion_queue_shutdown */
  253. gpr_ref_init(&cc->pending_events, 1);
  254. /* One for destroy(), one for pollset_shutdown */
  255. gpr_ref_init(&cc->owning_refs, 2);
  256. cc->completed_tail = &cc->completed_head;
  257. cc->completed_head.next = (uintptr_t)cc->completed_tail;
  258. cc->shutdown = 0;
  259. cc->shutdown_called = 0;
  260. cc->is_server_cq = 0;
  261. cc->is_non_listening_server_cq = 0;
  262. cc->num_pluckers = 0;
  263. gpr_atm_no_barrier_store(&cc->things_queued_ever, 0);
  264. #ifndef NDEBUG
  265. cc->outstanding_tag_count = 0;
  266. #endif
  267. grpc_closure_init(&cc->pollset_shutdown_done, on_pollset_shutdown_done, cc,
  268. grpc_schedule_on_exec_ctx);
  269. GPR_TIMER_END("grpc_completion_queue_create_internal", 0);
  270. return cc;
  271. }
  272. grpc_cq_completion_type grpc_get_cq_completion_type(grpc_completion_queue *cc) {
  273. return cc->completion_type;
  274. }
  275. #ifdef GRPC_CQ_REF_COUNT_DEBUG
  276. void grpc_cq_internal_ref(grpc_completion_queue *cc, const char *reason,
  277. const char *file, int line) {
  278. gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p ref %d -> %d %s", cc,
  279. (int)cc->owning_refs.count, (int)cc->owning_refs.count + 1, reason);
  280. #else
  281. void grpc_cq_internal_ref(grpc_completion_queue *cc) {
  282. #endif
  283. gpr_ref(&cc->owning_refs);
  284. }
  285. static void on_pollset_shutdown_done(grpc_exec_ctx *exec_ctx, void *arg,
  286. grpc_error *error) {
  287. grpc_completion_queue *cc = arg;
  288. GRPC_CQ_INTERNAL_UNREF(exec_ctx, cc, "pollset_destroy");
  289. }
  290. #ifdef GRPC_CQ_REF_COUNT_DEBUG
  291. void grpc_cq_internal_unref(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
  292. const char *reason, const char *file, int line) {
  293. gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "CQ:%p unref %d -> %d %s", cc,
  294. (int)cc->owning_refs.count, (int)cc->owning_refs.count - 1, reason);
  295. #else
  296. void grpc_cq_internal_unref(grpc_exec_ctx *exec_ctx,
  297. grpc_completion_queue *cc) {
  298. #endif
  299. if (gpr_unref(&cc->owning_refs)) {
  300. GPR_ASSERT(cc->completed_head.next == (uintptr_t)&cc->completed_head);
  301. cc->poller_vtable->destroy(exec_ctx, POLLSET_FROM_CQ(cc));
  302. #ifndef NDEBUG
  303. gpr_free(cc->outstanding_tags);
  304. #endif
  305. gpr_free(cc);
  306. }
  307. }
  308. void grpc_cq_begin_op(grpc_completion_queue *cc, void *tag) {
  309. #ifndef NDEBUG
  310. gpr_mu_lock(cc->mu);
  311. GPR_ASSERT(!cc->shutdown_called);
  312. if (cc->outstanding_tag_count == cc->outstanding_tag_capacity) {
  313. cc->outstanding_tag_capacity = GPR_MAX(4, 2 * cc->outstanding_tag_capacity);
  314. cc->outstanding_tags =
  315. gpr_realloc(cc->outstanding_tags, sizeof(*cc->outstanding_tags) *
  316. cc->outstanding_tag_capacity);
  317. }
  318. cc->outstanding_tags[cc->outstanding_tag_count++] = tag;
  319. gpr_mu_unlock(cc->mu);
  320. #endif
  321. gpr_ref(&cc->pending_events);
  322. }
  323. /* Signal the end of an operation - if this is the last waiting-to-be-queued
  324. event, then enter shutdown mode */
  325. /* Queue a GRPC_OP_COMPLETED operation */
  326. void grpc_cq_end_op(grpc_exec_ctx *exec_ctx, grpc_completion_queue *cc,
  327. void *tag, grpc_error *error,
  328. void (*done)(grpc_exec_ctx *exec_ctx, void *done_arg,
  329. grpc_cq_completion *storage),
  330. void *done_arg, grpc_cq_completion *storage) {
  331. int shutdown;
  332. int i;
  333. grpc_pollset_worker *pluck_worker;
  334. #ifndef NDEBUG
  335. int found = 0;
  336. #endif
  337. GPR_TIMER_BEGIN("grpc_cq_end_op", 0);
  338. if (grpc_api_trace ||
  339. (grpc_trace_operation_failures && error != GRPC_ERROR_NONE)) {
  340. const char *errmsg = grpc_error_string(error);
  341. GRPC_API_TRACE(
  342. "grpc_cq_end_op(exec_ctx=%p, cc=%p, tag=%p, error=%s, done=%p, "
  343. "done_arg=%p, storage=%p)",
  344. 7, (exec_ctx, cc, tag, errmsg, done, done_arg, storage));
  345. if (grpc_trace_operation_failures && error != GRPC_ERROR_NONE) {
  346. gpr_log(GPR_ERROR, "Operation failed: tag=%p, error=%s", tag, errmsg);
  347. }
  348. }
  349. storage->tag = tag;
  350. storage->done = done;
  351. storage->done_arg = done_arg;
  352. storage->next = ((uintptr_t)&cc->completed_head) |
  353. ((uintptr_t)(error == GRPC_ERROR_NONE));
  354. gpr_mu_lock(cc->mu);
  355. #ifndef NDEBUG
  356. for (i = 0; i < (int)cc->outstanding_tag_count; i++) {
  357. if (cc->outstanding_tags[i] == tag) {
  358. cc->outstanding_tag_count--;
  359. GPR_SWAP(void *, cc->outstanding_tags[i],
  360. cc->outstanding_tags[cc->outstanding_tag_count]);
  361. found = 1;
  362. break;
  363. }
  364. }
  365. GPR_ASSERT(found);
  366. #endif
  367. shutdown = gpr_unref(&cc->pending_events);
  368. gpr_atm_no_barrier_fetch_add(&cc->things_queued_ever, 1);
  369. if (!shutdown) {
  370. cc->completed_tail->next =
  371. ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next);
  372. cc->completed_tail = storage;
  373. pluck_worker = NULL;
  374. for (i = 0; i < cc->num_pluckers; i++) {
  375. if (cc->pluckers[i].tag == tag) {
  376. pluck_worker = *cc->pluckers[i].worker;
  377. break;
  378. }
  379. }
  380. grpc_error *kick_error =
  381. cc->poller_vtable->kick(POLLSET_FROM_CQ(cc), pluck_worker);
  382. gpr_mu_unlock(cc->mu);
  383. if (kick_error != GRPC_ERROR_NONE) {
  384. const char *msg = grpc_error_string(kick_error);
  385. gpr_log(GPR_ERROR, "Kick failed: %s", msg);
  386. GRPC_ERROR_UNREF(kick_error);
  387. }
  388. } else {
  389. cc->completed_tail->next =
  390. ((uintptr_t)storage) | (1u & (uintptr_t)cc->completed_tail->next);
  391. cc->completed_tail = storage;
  392. GPR_ASSERT(!cc->shutdown);
  393. GPR_ASSERT(cc->shutdown_called);
  394. cc->shutdown = 1;
  395. cc->poller_vtable->shutdown(exec_ctx, POLLSET_FROM_CQ(cc),
  396. &cc->pollset_shutdown_done);
  397. gpr_mu_unlock(cc->mu);
  398. }
  399. GPR_TIMER_END("grpc_cq_end_op", 0);
  400. GRPC_ERROR_UNREF(error);
  401. }
  402. typedef struct {
  403. gpr_atm last_seen_things_queued_ever;
  404. grpc_completion_queue *cq;
  405. gpr_timespec deadline;
  406. grpc_cq_completion *stolen_completion;
  407. void *tag; /* for pluck */
  408. bool first_loop;
  409. } cq_is_finished_arg;
  410. static bool cq_is_next_finished(grpc_exec_ctx *exec_ctx, void *arg) {
  411. cq_is_finished_arg *a = arg;
  412. grpc_completion_queue *cq = a->cq;
  413. GPR_ASSERT(a->stolen_completion == NULL);
  414. gpr_atm current_last_seen_things_queued_ever =
  415. gpr_atm_no_barrier_load(&cq->things_queued_ever);
  416. if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) {
  417. gpr_mu_lock(cq->mu);
  418. a->last_seen_things_queued_ever =
  419. gpr_atm_no_barrier_load(&cq->things_queued_ever);
  420. if (cq->completed_tail != &cq->completed_head) {
  421. a->stolen_completion = (grpc_cq_completion *)cq->completed_head.next;
  422. cq->completed_head.next = a->stolen_completion->next & ~(uintptr_t)1;
  423. if (a->stolen_completion == cq->completed_tail) {
  424. cq->completed_tail = &cq->completed_head;
  425. }
  426. gpr_mu_unlock(cq->mu);
  427. return true;
  428. }
  429. gpr_mu_unlock(cq->mu);
  430. }
  431. return !a->first_loop &&
  432. gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0;
  433. }
  434. #ifndef NDEBUG
  435. static void dump_pending_tags(grpc_completion_queue *cc) {
  436. if (!grpc_trace_pending_tags) return;
  437. gpr_strvec v;
  438. gpr_strvec_init(&v);
  439. gpr_strvec_add(&v, gpr_strdup("PENDING TAGS:"));
  440. gpr_mu_lock(cc->mu);
  441. for (size_t i = 0; i < cc->outstanding_tag_count; i++) {
  442. char *s;
  443. gpr_asprintf(&s, " %p", cc->outstanding_tags[i]);
  444. gpr_strvec_add(&v, s);
  445. }
  446. gpr_mu_unlock(cc->mu);
  447. char *out = gpr_strvec_flatten(&v, NULL);
  448. gpr_strvec_destroy(&v);
  449. gpr_log(GPR_DEBUG, "%s", out);
  450. gpr_free(out);
  451. }
  452. #else
  453. static void dump_pending_tags(grpc_completion_queue *cc) {}
  454. #endif
  455. grpc_event grpc_completion_queue_next(grpc_completion_queue *cc,
  456. gpr_timespec deadline, void *reserved) {
  457. grpc_event ret;
  458. gpr_timespec now;
  459. if (cc->completion_type != GRPC_CQ_NEXT) {
  460. gpr_log(GPR_ERROR,
  461. "grpc_completion_queue_next() cannot be called on this completion "
  462. "queue since its completion type is not GRPC_CQ_NEXT");
  463. abort();
  464. }
  465. GPR_TIMER_BEGIN("grpc_completion_queue_next", 0);
  466. GRPC_API_TRACE(
  467. "grpc_completion_queue_next("
  468. "cc=%p, "
  469. "deadline=gpr_timespec { tv_sec: %" PRId64
  470. ", tv_nsec: %d, clock_type: %d }, "
  471. "reserved=%p)",
  472. 5, (cc, deadline.tv_sec, deadline.tv_nsec, (int)deadline.clock_type,
  473. reserved));
  474. GPR_ASSERT(!reserved);
  475. dump_pending_tags(cc);
  476. deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
  477. GRPC_CQ_INTERNAL_REF(cc, "next");
  478. gpr_mu_lock(cc->mu);
  479. cq_is_finished_arg is_finished_arg = {
  480. .last_seen_things_queued_ever =
  481. gpr_atm_no_barrier_load(&cc->things_queued_ever),
  482. .cq = cc,
  483. .deadline = deadline,
  484. .stolen_completion = NULL,
  485. .tag = NULL,
  486. .first_loop = true};
  487. grpc_exec_ctx exec_ctx =
  488. GRPC_EXEC_CTX_INITIALIZER(0, cq_is_next_finished, &is_finished_arg);
  489. for (;;) {
  490. if (is_finished_arg.stolen_completion != NULL) {
  491. gpr_mu_unlock(cc->mu);
  492. grpc_cq_completion *c = is_finished_arg.stolen_completion;
  493. is_finished_arg.stolen_completion = NULL;
  494. ret.type = GRPC_OP_COMPLETE;
  495. ret.success = c->next & 1u;
  496. ret.tag = c->tag;
  497. c->done(&exec_ctx, c->done_arg, c);
  498. break;
  499. }
  500. if (cc->completed_tail != &cc->completed_head) {
  501. grpc_cq_completion *c = (grpc_cq_completion *)cc->completed_head.next;
  502. cc->completed_head.next = c->next & ~(uintptr_t)1;
  503. if (c == cc->completed_tail) {
  504. cc->completed_tail = &cc->completed_head;
  505. }
  506. gpr_mu_unlock(cc->mu);
  507. ret.type = GRPC_OP_COMPLETE;
  508. ret.success = c->next & 1u;
  509. ret.tag = c->tag;
  510. c->done(&exec_ctx, c->done_arg, c);
  511. break;
  512. }
  513. if (cc->shutdown) {
  514. gpr_mu_unlock(cc->mu);
  515. memset(&ret, 0, sizeof(ret));
  516. ret.type = GRPC_QUEUE_SHUTDOWN;
  517. break;
  518. }
  519. now = gpr_now(GPR_CLOCK_MONOTONIC);
  520. if (!is_finished_arg.first_loop && gpr_time_cmp(now, deadline) >= 0) {
  521. gpr_mu_unlock(cc->mu);
  522. memset(&ret, 0, sizeof(ret));
  523. ret.type = GRPC_QUEUE_TIMEOUT;
  524. dump_pending_tags(cc);
  525. break;
  526. }
  527. /* Check alarms - these are a global resource so we just ping
  528. each time through on every pollset.
  529. May update deadline to ensure timely wakeups.
  530. TODO(ctiller): can this work be localized? */
  531. gpr_timespec iteration_deadline = deadline;
  532. if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
  533. GPR_TIMER_MARK("alarm_triggered", 0);
  534. gpr_mu_unlock(cc->mu);
  535. grpc_exec_ctx_flush(&exec_ctx);
  536. gpr_mu_lock(cc->mu);
  537. continue;
  538. } else {
  539. grpc_error *err = cc->poller_vtable->work(&exec_ctx, POLLSET_FROM_CQ(cc),
  540. NULL, now, iteration_deadline);
  541. if (err != GRPC_ERROR_NONE) {
  542. gpr_mu_unlock(cc->mu);
  543. const char *msg = grpc_error_string(err);
  544. gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg);
  545. GRPC_ERROR_UNREF(err);
  546. memset(&ret, 0, sizeof(ret));
  547. ret.type = GRPC_QUEUE_TIMEOUT;
  548. dump_pending_tags(cc);
  549. break;
  550. }
  551. }
  552. is_finished_arg.first_loop = false;
  553. }
  554. GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret);
  555. GRPC_CQ_INTERNAL_UNREF(&exec_ctx, cc, "next");
  556. grpc_exec_ctx_finish(&exec_ctx);
  557. GPR_ASSERT(is_finished_arg.stolen_completion == NULL);
  558. GPR_TIMER_END("grpc_completion_queue_next", 0);
  559. return ret;
  560. }
  561. static int add_plucker(grpc_completion_queue *cc, void *tag,
  562. grpc_pollset_worker **worker) {
  563. if (cc->num_pluckers == GRPC_MAX_COMPLETION_QUEUE_PLUCKERS) {
  564. return 0;
  565. }
  566. cc->pluckers[cc->num_pluckers].tag = tag;
  567. cc->pluckers[cc->num_pluckers].worker = worker;
  568. cc->num_pluckers++;
  569. return 1;
  570. }
  571. static void del_plucker(grpc_completion_queue *cc, void *tag,
  572. grpc_pollset_worker **worker) {
  573. int i;
  574. for (i = 0; i < cc->num_pluckers; i++) {
  575. if (cc->pluckers[i].tag == tag && cc->pluckers[i].worker == worker) {
  576. cc->num_pluckers--;
  577. GPR_SWAP(plucker, cc->pluckers[i], cc->pluckers[cc->num_pluckers]);
  578. return;
  579. }
  580. }
  581. GPR_UNREACHABLE_CODE(return );
  582. }
  583. static bool cq_is_pluck_finished(grpc_exec_ctx *exec_ctx, void *arg) {
  584. cq_is_finished_arg *a = arg;
  585. grpc_completion_queue *cq = a->cq;
  586. GPR_ASSERT(a->stolen_completion == NULL);
  587. gpr_atm current_last_seen_things_queued_ever =
  588. gpr_atm_no_barrier_load(&cq->things_queued_ever);
  589. if (current_last_seen_things_queued_ever != a->last_seen_things_queued_ever) {
  590. gpr_mu_lock(cq->mu);
  591. a->last_seen_things_queued_ever =
  592. gpr_atm_no_barrier_load(&cq->things_queued_ever);
  593. grpc_cq_completion *c;
  594. grpc_cq_completion *prev = &cq->completed_head;
  595. while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) !=
  596. &cq->completed_head) {
  597. if (c->tag == a->tag) {
  598. prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1);
  599. if (c == cq->completed_tail) {
  600. cq->completed_tail = prev;
  601. }
  602. gpr_mu_unlock(cq->mu);
  603. a->stolen_completion = c;
  604. return true;
  605. }
  606. prev = c;
  607. }
  608. gpr_mu_unlock(cq->mu);
  609. }
  610. return !a->first_loop &&
  611. gpr_time_cmp(a->deadline, gpr_now(a->deadline.clock_type)) < 0;
  612. }
  613. grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,
  614. gpr_timespec deadline, void *reserved) {
  615. grpc_event ret;
  616. grpc_cq_completion *c;
  617. grpc_cq_completion *prev;
  618. grpc_pollset_worker *worker = NULL;
  619. gpr_timespec now;
  620. GPR_TIMER_BEGIN("grpc_completion_queue_pluck", 0);
  621. if (cc->completion_type != GRPC_CQ_PLUCK) {
  622. gpr_log(GPR_ERROR,
  623. "grpc_completion_queue_pluck() cannot be called on this completion "
  624. "queue since its completion type is not GRPC_CQ_PLUCK");
  625. abort();
  626. }
  627. if (grpc_cq_pluck_trace) {
  628. GRPC_API_TRACE(
  629. "grpc_completion_queue_pluck("
  630. "cc=%p, tag=%p, "
  631. "deadline=gpr_timespec { tv_sec: %" PRId64
  632. ", tv_nsec: %d, clock_type: %d }, "
  633. "reserved=%p)",
  634. 6, (cc, tag, deadline.tv_sec, deadline.tv_nsec,
  635. (int)deadline.clock_type, reserved));
  636. }
  637. GPR_ASSERT(!reserved);
  638. dump_pending_tags(cc);
  639. deadline = gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC);
  640. GRPC_CQ_INTERNAL_REF(cc, "pluck");
  641. gpr_mu_lock(cc->mu);
  642. cq_is_finished_arg is_finished_arg = {
  643. .last_seen_things_queued_ever =
  644. gpr_atm_no_barrier_load(&cc->things_queued_ever),
  645. .cq = cc,
  646. .deadline = deadline,
  647. .stolen_completion = NULL,
  648. .tag = tag,
  649. .first_loop = true};
  650. grpc_exec_ctx exec_ctx =
  651. GRPC_EXEC_CTX_INITIALIZER(0, cq_is_pluck_finished, &is_finished_arg);
  652. for (;;) {
  653. if (is_finished_arg.stolen_completion != NULL) {
  654. gpr_mu_unlock(cc->mu);
  655. c = is_finished_arg.stolen_completion;
  656. is_finished_arg.stolen_completion = NULL;
  657. ret.type = GRPC_OP_COMPLETE;
  658. ret.success = c->next & 1u;
  659. ret.tag = c->tag;
  660. c->done(&exec_ctx, c->done_arg, c);
  661. break;
  662. }
  663. prev = &cc->completed_head;
  664. while ((c = (grpc_cq_completion *)(prev->next & ~(uintptr_t)1)) !=
  665. &cc->completed_head) {
  666. if (c->tag == tag) {
  667. prev->next = (prev->next & (uintptr_t)1) | (c->next & ~(uintptr_t)1);
  668. if (c == cc->completed_tail) {
  669. cc->completed_tail = prev;
  670. }
  671. gpr_mu_unlock(cc->mu);
  672. ret.type = GRPC_OP_COMPLETE;
  673. ret.success = c->next & 1u;
  674. ret.tag = c->tag;
  675. c->done(&exec_ctx, c->done_arg, c);
  676. goto done;
  677. }
  678. prev = c;
  679. }
  680. if (cc->shutdown) {
  681. gpr_mu_unlock(cc->mu);
  682. memset(&ret, 0, sizeof(ret));
  683. ret.type = GRPC_QUEUE_SHUTDOWN;
  684. break;
  685. }
  686. if (!add_plucker(cc, tag, &worker)) {
  687. gpr_log(GPR_DEBUG,
  688. "Too many outstanding grpc_completion_queue_pluck calls: maximum "
  689. "is %d",
  690. GRPC_MAX_COMPLETION_QUEUE_PLUCKERS);
  691. gpr_mu_unlock(cc->mu);
  692. memset(&ret, 0, sizeof(ret));
  693. /* TODO(ctiller): should we use a different result here */
  694. ret.type = GRPC_QUEUE_TIMEOUT;
  695. dump_pending_tags(cc);
  696. break;
  697. }
  698. now = gpr_now(GPR_CLOCK_MONOTONIC);
  699. if (!is_finished_arg.first_loop && gpr_time_cmp(now, deadline) >= 0) {
  700. del_plucker(cc, tag, &worker);
  701. gpr_mu_unlock(cc->mu);
  702. memset(&ret, 0, sizeof(ret));
  703. ret.type = GRPC_QUEUE_TIMEOUT;
  704. dump_pending_tags(cc);
  705. break;
  706. }
  707. /* Check alarms - these are a global resource so we just ping
  708. each time through on every pollset.
  709. May update deadline to ensure timely wakeups.
  710. TODO(ctiller): can this work be localized? */
  711. gpr_timespec iteration_deadline = deadline;
  712. if (grpc_timer_check(&exec_ctx, now, &iteration_deadline)) {
  713. GPR_TIMER_MARK("alarm_triggered", 0);
  714. gpr_mu_unlock(cc->mu);
  715. grpc_exec_ctx_flush(&exec_ctx);
  716. gpr_mu_lock(cc->mu);
  717. } else {
  718. grpc_error *err = cc->poller_vtable->work(
  719. &exec_ctx, POLLSET_FROM_CQ(cc), &worker, now, iteration_deadline);
  720. if (err != GRPC_ERROR_NONE) {
  721. del_plucker(cc, tag, &worker);
  722. gpr_mu_unlock(cc->mu);
  723. const char *msg = grpc_error_string(err);
  724. gpr_log(GPR_ERROR, "Completion queue next failed: %s", msg);
  725. GRPC_ERROR_UNREF(err);
  726. memset(&ret, 0, sizeof(ret));
  727. ret.type = GRPC_QUEUE_TIMEOUT;
  728. dump_pending_tags(cc);
  729. break;
  730. }
  731. }
  732. is_finished_arg.first_loop = false;
  733. del_plucker(cc, tag, &worker);
  734. }
  735. done:
  736. GRPC_SURFACE_TRACE_RETURNED_EVENT(cc, &ret);
  737. GRPC_CQ_INTERNAL_UNREF(&exec_ctx, cc, "pluck");
  738. grpc_exec_ctx_finish(&exec_ctx);
  739. GPR_ASSERT(is_finished_arg.stolen_completion == NULL);
  740. GPR_TIMER_END("grpc_completion_queue_pluck", 0);
  741. return ret;
  742. }
  743. /* Shutdown simply drops a ref that we reserved at creation time; if we drop
  744. to zero here, then enter shutdown mode and wake up any waiters */
  745. void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
  746. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  747. GPR_TIMER_BEGIN("grpc_completion_queue_shutdown", 0);
  748. GRPC_API_TRACE("grpc_completion_queue_shutdown(cc=%p)", 1, (cc));
  749. gpr_mu_lock(cc->mu);
  750. if (cc->shutdown_called) {
  751. gpr_mu_unlock(cc->mu);
  752. GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
  753. return;
  754. }
  755. cc->shutdown_called = 1;
  756. if (gpr_unref(&cc->pending_events)) {
  757. GPR_ASSERT(!cc->shutdown);
  758. cc->shutdown = 1;
  759. cc->poller_vtable->shutdown(&exec_ctx, POLLSET_FROM_CQ(cc),
  760. &cc->pollset_shutdown_done);
  761. }
  762. gpr_mu_unlock(cc->mu);
  763. grpc_exec_ctx_finish(&exec_ctx);
  764. GPR_TIMER_END("grpc_completion_queue_shutdown", 0);
  765. }
  766. void grpc_completion_queue_destroy(grpc_completion_queue *cc) {
  767. GRPC_API_TRACE("grpc_completion_queue_destroy(cc=%p)", 1, (cc));
  768. GPR_TIMER_BEGIN("grpc_completion_queue_destroy", 0);
  769. grpc_completion_queue_shutdown(cc);
  770. grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  771. GRPC_CQ_INTERNAL_UNREF(&exec_ctx, cc, "destroy");
  772. grpc_exec_ctx_finish(&exec_ctx);
  773. GPR_TIMER_END("grpc_completion_queue_destroy", 0);
  774. }
  775. grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
  776. return cc->poller_vtable->can_get_pollset ? POLLSET_FROM_CQ(cc) : NULL;
  777. }
  778. grpc_completion_queue *grpc_cq_from_pollset(grpc_pollset *ps) {
  779. return CQ_FROM_POLLSET(ps);
  780. }
  781. void grpc_cq_mark_non_listening_server_cq(grpc_completion_queue *cc) {
  782. /* TODO: sreek - use cc->polling_type field here and add a validation check
  783. (i.e grpc_cq_mark_non_listening_server_cq can only be called on a cc whose
  784. polling_type is set to GRPC_CQ_NON_LISTENING */
  785. cc->is_non_listening_server_cq = 1;
  786. }
  787. bool grpc_cq_is_non_listening_server_cq(grpc_completion_queue *cc) {
  788. /* TODO (sreek) - return (cc->polling_type == GRPC_CQ_NON_LISTENING) */
  789. return (cc->is_non_listening_server_cq == 1);
  790. }
  791. void grpc_cq_mark_server_cq(grpc_completion_queue *cc) { cc->is_server_cq = 1; }
  792. bool grpc_cq_is_server_cq(grpc_completion_queue *cc) {
  793. return cc->is_server_cq;
  794. }
  795. bool grpc_cq_can_listen(grpc_completion_queue *cc) {
  796. return cc->poller_vtable->can_listen;
  797. }