completion_queue.c 28 KB

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