Beispiel #1
0
/* Cleaning up a list with pending timers. */
void destruction_test(void) {
  grpc_timer timers[5];
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  grpc_timer_list_init(gpr_time_0(GPR_CLOCK_REALTIME));
  memset(cb_called, 0, sizeof(cb_called));

  grpc_timer_init(&exec_ctx, &timers[0], tfm(100), cb, (void *)(intptr_t)0,
                  gpr_time_0(GPR_CLOCK_REALTIME));
  grpc_timer_init(&exec_ctx, &timers[1], tfm(3), cb, (void *)(intptr_t)1,
                  gpr_time_0(GPR_CLOCK_REALTIME));
  grpc_timer_init(&exec_ctx, &timers[2], tfm(100), cb, (void *)(intptr_t)2,
                  gpr_time_0(GPR_CLOCK_REALTIME));
  grpc_timer_init(&exec_ctx, &timers[3], tfm(3), cb, (void *)(intptr_t)3,
                  gpr_time_0(GPR_CLOCK_REALTIME));
  grpc_timer_init(&exec_ctx, &timers[4], tfm(1), cb, (void *)(intptr_t)4,
                  gpr_time_0(GPR_CLOCK_REALTIME));
  GPR_ASSERT(1 == grpc_timer_check(&exec_ctx, tfm(2), NULL));
  grpc_exec_ctx_finish(&exec_ctx);
  GPR_ASSERT(1 == cb_called[4][1]);
  grpc_timer_cancel(&exec_ctx, &timers[0]);
  grpc_timer_cancel(&exec_ctx, &timers[3]);
  grpc_exec_ctx_finish(&exec_ctx);
  GPR_ASSERT(1 == cb_called[0][0]);
  GPR_ASSERT(1 == cb_called[3][0]);

  grpc_timer_list_shutdown(&exec_ctx);
  grpc_exec_ctx_finish(&exec_ctx);
  GPR_ASSERT(1 == cb_called[1][0]);
  GPR_ASSERT(1 == cb_called[2][0]);
}
Beispiel #2
0
static void add_test(void) {
  gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
  int i;
  grpc_timer timers[20];
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  grpc_timer_list_init(start);
  memset(cb_called, 0, sizeof(cb_called));

  /* 10 ms timers.  will expire in the current epoch */
  for (i = 0; i < 10; i++) {
    grpc_timer_init(&exec_ctx, &timers[i],
                    gpr_time_add(start, gpr_time_from_millis(10, GPR_TIMESPAN)),
                    cb, (void *)(intptr_t)i, start);
  }

  /* 1010 ms timers.  will expire in the next epoch */
  for (i = 10; i < 20; i++) {
    grpc_timer_init(
        &exec_ctx, &timers[i],
        gpr_time_add(start, gpr_time_from_millis(1010, GPR_TIMESPAN)), cb,
        (void *)(intptr_t)i, start);
  }

  /* collect timers.  Only the first batch should be ready. */
  GPR_ASSERT(10 == grpc_timer_check(&exec_ctx,
                                    gpr_time_add(start, gpr_time_from_millis(
                                                            500, GPR_TIMESPAN)),
                                    NULL));
  grpc_exec_ctx_finish(&exec_ctx);
  for (i = 0; i < 20; i++) {
    GPR_ASSERT(cb_called[i][1] == (i < 10));
    GPR_ASSERT(cb_called[i][0] == 0);
  }

  GPR_ASSERT(0 == grpc_timer_check(&exec_ctx,
                                   gpr_time_add(start, gpr_time_from_millis(
                                                           600, GPR_TIMESPAN)),
                                   NULL));
  grpc_exec_ctx_finish(&exec_ctx);
  for (i = 0; i < 30; i++) {
    GPR_ASSERT(cb_called[i][1] == (i < 10));
    GPR_ASSERT(cb_called[i][0] == 0);
  }

  /* collect the rest of the timers */
  GPR_ASSERT(10 == grpc_timer_check(
                       &exec_ctx, gpr_time_add(start, gpr_time_from_millis(
                                                          1500, GPR_TIMESPAN)),
                       NULL));
  grpc_exec_ctx_finish(&exec_ctx);
  for (i = 0; i < 30; i++) {
    GPR_ASSERT(cb_called[i][1] == (i < 20));
    GPR_ASSERT(cb_called[i][0] == 0);
  }

  GPR_ASSERT(0 == grpc_timer_check(&exec_ctx,
                                   gpr_time_add(start, gpr_time_from_millis(
                                                           1600, GPR_TIMESPAN)),
                                   NULL));
  for (i = 0; i < 30; i++) {
    GPR_ASSERT(cb_called[i][1] == (i < 20));
    GPR_ASSERT(cb_called[i][0] == 0);
  }

  grpc_timer_list_shutdown(&exec_ctx);
  grpc_exec_ctx_finish(&exec_ctx);
}
Beispiel #3
0
void grpc_iomgr_shutdown(void) {
  gpr_timespec shutdown_deadline = gpr_time_add(
      gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN));
  gpr_timespec last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;

  grpc_iomgr_platform_flush();

  gpr_mu_lock(&g_mu);
  g_shutdown = 1;
  while (g_root_object.next != &g_root_object) {
    if (gpr_time_cmp(
            gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), last_warning_time),
            gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
      if (g_root_object.next != &g_root_object) {
        gpr_log(GPR_DEBUG, "Waiting for %d iomgr objects to be destroyed",
                count_objects());
      }
      last_warning_time = gpr_now(GPR_CLOCK_REALTIME);
    }
    if (grpc_timer_check(&exec_ctx, gpr_inf_future(GPR_CLOCK_MONOTONIC),
                         NULL)) {
      gpr_mu_unlock(&g_mu);
      grpc_exec_ctx_flush(&exec_ctx);
      gpr_mu_lock(&g_mu);
      continue;
    }
    if (g_root_object.next != &g_root_object) {
      gpr_timespec short_deadline = gpr_time_add(
          gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(100, GPR_TIMESPAN));
      if (gpr_cv_wait(&g_rcv, &g_mu, short_deadline)) {
        if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > 0) {
          if (g_root_object.next != &g_root_object) {
            gpr_log(GPR_DEBUG,
                    "Failed to free %d iomgr objects before shutdown deadline: "
                    "memory leaks are likely",
                    count_objects());
            dump_objects("LEAKED");
            if (grpc_iomgr_abort_on_leaks()) {
              abort();
            }
          }
          break;
        }
      }
    }
  }
  gpr_mu_unlock(&g_mu);

  grpc_timer_list_shutdown(&exec_ctx);
  grpc_exec_ctx_finish(&exec_ctx);

  /* ensure all threads have left g_mu */
  gpr_mu_lock(&g_mu);
  gpr_mu_unlock(&g_mu);

  grpc_pollset_global_shutdown();
  grpc_iomgr_platform_shutdown();
  grpc_exec_ctx_global_shutdown();
  gpr_mu_destroy(&g_mu);
  gpr_cv_destroy(&g_rcv);
}