Esempio n. 1
0
/* Test that we can create a number of threads and wait for them. */
static void test(void) {
  int i;
  gpr_thd_id thd;
  gpr_thd_id thds[1000];
  struct test t;
  int n = 1000;
  gpr_thd_options options = gpr_thd_options_default();
  gpr_mu_init(&t.mu);
  gpr_cv_init(&t.done_cv);
  t.n = n;
  t.is_done = 0;
  for (i = 0; i != n; i++) {
    GPR_ASSERT(gpr_thd_new(&thd, &thd_body, &t, NULL));
  }
  gpr_mu_lock(&t.mu);
  while (!t.is_done) {
    gpr_cv_wait(&t.done_cv, &t.mu, gpr_inf_future(GPR_CLOCK_REALTIME));
  }
  gpr_mu_unlock(&t.mu);
  GPR_ASSERT(t.n == 0);
  gpr_thd_options_set_joinable(&options);
  for (i = 0; i < n; i++) {
    GPR_ASSERT(gpr_thd_new(&thds[i], &thd_body_joinable, NULL, &options));
  }
  for (i = 0; i < n; i++) {
    gpr_thd_join(thds[i]);
  }
}
Esempio n. 2
0
/* Spawn the thread if new work has arrived a no thread is up */
static void maybe_spawn_locked() {
  if (grpc_closure_list_empty(g_executor.closures) == 1) {
    return;
  }
  if (g_executor.shutting_down == 1) {
    return;
  }

  if (g_executor.busy != 0) {
    /* Thread still working. New work will be picked up by already running
     * thread. Not spawning anything. */
    return;
  } else if (g_executor.pending_join != 0) {
    /* Pickup the remains of the previous incarnations of the thread. */
    gpr_thd_join(g_executor.tid);
    g_executor.pending_join = 0;
  }

  /* All previous instances of the thread should have been joined at this point.
   * Spawn time! */
  g_executor.busy = 1;
  gpr_thd_new(&g_executor.tid, closure_exec_thread_func, NULL,
              &g_executor.options);
  g_executor.pending_join = 1;
}
Esempio n. 3
0
static void cpu_test(void) {
  uint32_t i;
  int cores_seen = 0;
  struct cpu_test ct;
  gpr_thd_id thd;
  ct.ncores = gpr_cpu_num_cores();
  GPR_ASSERT(ct.ncores > 0);
  ct.nthreads = (int)ct.ncores * 3;
  ct.used = gpr_malloc(ct.ncores * sizeof(int));
  memset(ct.used, 0, ct.ncores * sizeof(int));
  gpr_mu_init(&ct.mu);
  gpr_cv_init(&ct.done_cv);
  ct.is_done = 0;
  for (i = 0; i < ct.ncores * 3; i++) {
    GPR_ASSERT(gpr_thd_new(&thd, &worker_thread, &ct, NULL));
  }
  gpr_mu_lock(&ct.mu);
  while (!ct.is_done) {
    gpr_cv_wait(&ct.done_cv, &ct.mu, gpr_inf_future(GPR_CLOCK_REALTIME));
  }
  gpr_mu_unlock(&ct.mu);
  fprintf(stderr, "Saw cores [");
  for (i = 0; i < ct.ncores; i++) {
    if (ct.used[i]) {
      fprintf(stderr, "%d,", i);
      cores_seen++;
    }
  }
  fprintf(stderr, "] (%d/%d)\n", cores_seen, ct.ncores);
  gpr_free(ct.used);
}
Esempio n. 4
0
grpc_end2end_http_proxy* grpc_end2end_http_proxy_create(void) {
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_end2end_http_proxy* proxy = gpr_malloc(sizeof(*proxy));
  memset(proxy, 0, sizeof(*proxy));
  // Construct proxy address.
  const int proxy_port = grpc_pick_unused_port_or_die();
  gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port);
  gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name);
  // Create TCP server.
  proxy->channel_args = grpc_channel_args_copy(NULL);
  grpc_error* error = grpc_tcp_server_create(
      &exec_ctx, NULL, proxy->channel_args, &proxy->server);
  GPR_ASSERT(error == GRPC_ERROR_NONE);
  // Bind to port.
  grpc_resolved_address resolved_addr;
  struct sockaddr_in* addr = (struct sockaddr_in*)resolved_addr.addr;
  memset(&resolved_addr, 0, sizeof(resolved_addr));
  addr->sin_family = AF_INET;
  grpc_sockaddr_set_port(&resolved_addr, proxy_port);
  int port;
  error = grpc_tcp_server_add_port(proxy->server, &resolved_addr, &port);
  GPR_ASSERT(error == GRPC_ERROR_NONE);
  GPR_ASSERT(port == proxy_port);
  // Start server.
  proxy->pollset = gpr_malloc(grpc_pollset_size());
  grpc_pollset_init(proxy->pollset, &proxy->mu);
  grpc_tcp_server_start(&exec_ctx, proxy->server, &proxy->pollset, 1, on_accept,
                        proxy);
  grpc_exec_ctx_finish(&exec_ctx);
  // Start proxy thread.
  gpr_thd_options opt = gpr_thd_options_default();
  gpr_thd_options_set_joinable(&opt);
  GPR_ASSERT(gpr_thd_new(&proxy->thd, thread_main, proxy, &opt));
  return proxy;
}
Esempio n. 5
0
static void test_mt_sized(int size, int nth) {
  gpr_stack_lockfree *stack;
  struct test_arg args[MAX_THREADS];
  gpr_thd_id thds[MAX_THREADS];
  int sum;
  int i;
  gpr_thd_options options = gpr_thd_options_default();

  stack = gpr_stack_lockfree_create(size);
  for (i = 0; i < nth; i++) {
    args[i].stack = stack;
    args[i].stack_size = size;
    args[i].nthreads = nth;
    args[i].rank = i;
    args[i].sum = 0;
  }
  gpr_thd_options_set_joinable(&options);
  for (i = 0; i < nth; i++) {
    GPR_ASSERT(gpr_thd_new(&thds[i], test_mt_body, &args[i], &options));
  }
  sum = 0;
  for (i = 0; i < nth; i++) {
    gpr_thd_join(thds[i]);
    sum = sum + args[i].sum;
  }
  GPR_ASSERT((unsigned)sum == ((unsigned)size * (size - 1)) / 2);
  gpr_stack_lockfree_destroy(stack);
}
Esempio n. 6
0
File: proxy.c Progetto: An-mol/grpc
grpc_end2end_proxy *grpc_end2end_proxy_create(
    const grpc_end2end_proxy_def *def) {
  gpr_thd_options opt = gpr_thd_options_default();
  int proxy_port = grpc_pick_unused_port_or_die();
  int server_port = grpc_pick_unused_port_or_die();

  grpc_end2end_proxy *proxy = gpr_malloc(sizeof(*proxy));
  memset(proxy, 0, sizeof(*proxy));

  gpr_join_host_port(&proxy->proxy_port, "localhost", proxy_port);
  gpr_join_host_port(&proxy->server_port, "localhost", server_port);

  gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port,
          proxy->server_port);

  proxy->cq = grpc_completion_queue_create(NULL);
  proxy->server = def->create_server(proxy->proxy_port);
  proxy->client = def->create_client(proxy->server_port);

  grpc_server_register_completion_queue(proxy->server, proxy->cq, NULL);
  grpc_server_start(proxy->server);

  gpr_thd_options_set_joinable(&opt);
  GPR_ASSERT(gpr_thd_new(&proxy->thd, thread_main, proxy, &opt));

  request_call(proxy);

  return proxy;
}
Esempio n. 7
0
/* Test several threads running (*body)(struct test *m) for increasing settings
   of m->iterations, until about timeout_s to 2*timeout_s seconds have elapsed.
   If extra!=NULL, run (*extra)(m) in an additional thread.  */
static void test(const char *name, void (*body)(void *m),
                 void (*extra)(void *m), int timeout_s) {
  gpr_int64 iterations = 1024;
  struct test *m;
  gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
  gpr_timespec time_taken;
  gpr_timespec deadline = gpr_time_add(
      start, gpr_time_from_micros(timeout_s * 1000000, GPR_TIMESPAN));
  fprintf(stderr, "%s:", name);
  while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) {
    iterations <<= 1;
    fprintf(stderr, " %ld", (long)iterations);
    m = test_new(10, iterations);
    if (extra != NULL) {
      gpr_thd_id id;
      GPR_ASSERT(gpr_thd_new(&id, extra, m, NULL));
      m->done++; /* one more thread to wait for */
    }
    test_create_threads(m, body);
    test_wait(m);
    if (m->counter != m->threads * m->iterations) {
      fprintf(stderr, "counter %ld  threads %d  iterations %ld\n",
              (long)m->counter, m->threads, (long)m->iterations);
      GPR_ASSERT(0);
    }
    test_destroy(m);
  }
  time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start);
  fprintf(stderr, " done %ld.%09d s\n", (long)time_taken.tv_sec,
          (int)time_taken.tv_nsec);
}
Esempio n. 8
0
/* Create m->threads threads, each running (*body)(m) */
static void test_create_threads(struct test *m, void (*body)(void *arg)) {
  gpr_thd_id id;
  int i;
  for (i = 0; i != m->threads; i++) {
    GPR_ASSERT(gpr_thd_new(&id, body, m, NULL));
  }
}
static void poll_server_until_read_done(test_tcp_server *server,
                                        gpr_event *signal_when_done) {
  gpr_atm_rel_store(&state.done_atm, 0);
  gpr_thd_id id;
  poll_args *pa = gpr_malloc(sizeof(*pa));
  pa->server = server;
  pa->signal_when_done = signal_when_done;
  gpr_thd_new(&id, actually_poll_server, pa, NULL);
}
Esempio n. 10
0
void grpc_resolve_address(const char *name, const char *default_port,
                          grpc_resolve_cb cb, void *arg) {
  request *r = gpr_malloc(sizeof(request));
  gpr_thd_id id;
  grpc_iomgr_ref();
  r->name = gpr_strdup(name);
  r->default_port = gpr_strdup(default_port);
  r->cb = cb;
  r->arg = arg;
  gpr_thd_new(&id, do_request, r, NULL);
}
Esempio n. 11
0
File: iomgr.c Progetto: Infixz/grpc
void grpc_iomgr_init(void) {
  gpr_thd_id id;
  gpr_mu_init(&g_mu);
  gpr_cv_init(&g_rcv);
  grpc_alarm_list_init(gpr_now());
  g_root_object.next = g_root_object.prev = &g_root_object;
  g_root_object.name = "root";
  grpc_iomgr_platform_init();
  gpr_event_init(&g_background_callback_executor_done);
  gpr_thd_new(&id, background_callback_executor, NULL, NULL);
}
Esempio n. 12
0
void grpc_iocp_init(void) {
  gpr_thd_id id;

  g_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
                                  NULL, (ULONG_PTR)NULL, 0);
  GPR_ASSERT(g_iocp);

  gpr_event_init(&g_iocp_done);
  gpr_event_init(&g_shutdown_iocp);
  gpr_thd_new(&id, iocp_loop, NULL, NULL);
}
Esempio n. 13
0
File: iomgr.c Progetto: Abioy/kythe
void grpc_iomgr_init(void) {
  gpr_thd_id id;
  gpr_mu_init(&g_mu);
  gpr_cv_init(&g_cv);
  gpr_cv_init(&g_rcv);
  grpc_alarm_list_init(gpr_now());
  g_refs = 0;
  grpc_iomgr_platform_init();
  gpr_event_init(&g_background_callback_executor_done);
  gpr_thd_new(&id, background_callback_executor, NULL, NULL);
}
Esempio n. 14
0
static void test_mt_multipop(void) {
  gpr_log(GPR_DEBUG, "test_mt_multipop");
  gpr_event start;
  gpr_event_init(&start);
  gpr_thd_id thds[100];
  gpr_thd_id pull_thds[100];
  thd_args ta[GPR_ARRAY_SIZE(thds)];
  gpr_mpscq q;
  gpr_mpscq_init(&q);
  for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
    gpr_thd_options options = gpr_thd_options_default();
    gpr_thd_options_set_joinable(&options);
    ta[i].ctr = 0;
    ta[i].q = &q;
    ta[i].start = &start;
    GPR_ASSERT(gpr_thd_new(&thds[i], test_thread, &ta[i], &options));
  }
  pull_args pa;
  pa.ta = ta;
  pa.num_thds = GPR_ARRAY_SIZE(thds);
  pa.spins = 0;
  pa.num_done = 0;
  pa.q = &q;
  pa.start = &start;
  gpr_mu_init(&pa.mu);
  for (size_t i = 0; i < GPR_ARRAY_SIZE(pull_thds); i++) {
    gpr_thd_options options = gpr_thd_options_default();
    gpr_thd_options_set_joinable(&options);
    GPR_ASSERT(gpr_thd_new(&pull_thds[i], pull_thread, &pa, &options));
  }
  gpr_event_set(&start, (void *)1);
  for (size_t i = 0; i < GPR_ARRAY_SIZE(pull_thds); i++) {
    gpr_thd_join(pull_thds[i]);
  }
  gpr_log(GPR_DEBUG, "spins: %" PRIdPTR, pa.spins);
  for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
    gpr_thd_join(thds[i]);
  }
  gpr_mpscq_destroy(&q);
}
Esempio n. 15
0
static void md_only_test_get_request_metadata(
    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
  grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;

  if (c->is_async) {
    gpr_thd_id thd_id;
    grpc_credentials_metadata_request *cb_arg =
        grpc_credentials_metadata_request_create(creds, cb, user_data);
    gpr_thd_new(&thd_id, on_simulated_token_fetch_done, cb_arg, NULL);
  } else {
    cb(exec_ctx, user_data, c->md_store->entries, 1, GRPC_CREDENTIALS_OK);
  }
}
Esempio n. 16
0
void grpc_resolve_address(const char *name, const char *default_port,
                          grpc_resolve_cb cb, void *arg) {
  request *r = gpr_malloc(sizeof(request));
  gpr_thd_id id;
  char *label;
  gpr_asprintf(&label, "resolve:%s", name);
  grpc_iomgr_register_object(&r->iomgr_object, label);
  gpr_free(label);
  r->name = gpr_strdup(name);
  r->default_port = gpr_strdup(default_port);
  r->cb = cb;
  r->arg = arg;
  gpr_thd_new(&id, do_request, r, NULL);
}
Esempio n. 17
0
static int run_benchmark(char *socket_type, thread_args *client_args,
                         thread_args *server_args) {
  gpr_thd_id tid;
  int rv = 0;

  rv = create_socket(socket_type, &client_args->fds, &server_args->fds);
  if (rv < 0) {
    return rv;
  }

  gpr_log(GPR_INFO, "Starting test %s %s %d", client_args->strategy_name,
          socket_type, client_args->msg_size);

  gpr_thd_new(&tid, server_thread_wrap, server_args, NULL);
  client_thread(client_args);
  return 0;
}
Esempio n. 18
0
static void test_too_many_plucks(void) {
  grpc_event ev;
  grpc_completion_queue *cc;
  void *tags[GRPC_MAX_COMPLETION_QUEUE_PLUCKERS];
  grpc_cq_completion completions[GPR_ARRAY_SIZE(tags)];
  gpr_thd_id thread_ids[GPR_ARRAY_SIZE(tags)];
  struct thread_state thread_states[GPR_ARRAY_SIZE(tags)];
  gpr_thd_options thread_options = gpr_thd_options_default();
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  unsigned i, j;

  LOG_TEST("test_too_many_plucks");

  cc = grpc_completion_queue_create(NULL);
  gpr_thd_options_set_joinable(&thread_options);

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    tags[i] = create_test_tag();
    for (j = 0; j < i; j++) {
      GPR_ASSERT(tags[i] != tags[j]);
    }
    thread_states[i].cc = cc;
    thread_states[i].tag = tags[i];
    gpr_thd_new(thread_ids + i, pluck_one, thread_states + i, &thread_options);
  }

  /* wait until all other threads are plucking */
  gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(1000));

  ev = grpc_completion_queue_pluck(cc, create_test_tag(),
                                   gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
  GPR_ASSERT(ev.type == GRPC_QUEUE_TIMEOUT);

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    grpc_cq_begin_op(cc, tags[i]);
    grpc_cq_end_op(&exec_ctx, cc, tags[i], GRPC_ERROR_NONE,
                   do_nothing_end_completion, NULL, &completions[i]);
  }

  for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) {
    gpr_thd_join(thread_ids[i]);
  }

  shutdown_and_destroy(cc);
  grpc_exec_ctx_finish(&exec_ctx);
}
Esempio n. 19
0
static void test_threading(void) {
  threading_shared shared;
  shared.pollset = gpr_zalloc(grpc_pollset_size());
  grpc_pollset_init(shared.pollset, &shared.mu);

  gpr_thd_id thds[10];
  for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
    gpr_thd_options opt = gpr_thd_options_default();
    gpr_thd_options_set_joinable(&opt);
    gpr_thd_new(&thds[i], test_threading_loop, &shared, &opt);
  }
  grpc_wakeup_fd fd;
  GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_fd_init", grpc_wakeup_fd_init(&fd)));
  shared.wakeup_fd = &fd;
  shared.wakeup_desc = grpc_fd_create(fd.read_fd, "wakeup");
  shared.wakeups = 0;
  {
    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
    grpc_pollset_add_fd(&exec_ctx, shared.pollset, shared.wakeup_desc);
    grpc_fd_notify_on_read(
        &exec_ctx, shared.wakeup_desc,
        GRPC_CLOSURE_INIT(&shared.on_wakeup, test_threading_wakeup, &shared,
                          grpc_schedule_on_exec_ctx));
    grpc_exec_ctx_finish(&exec_ctx);
  }
  GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_first",
                               grpc_wakeup_fd_wakeup(shared.wakeup_fd)));
  for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
    gpr_thd_join(thds[i]);
  }
  fd.read_fd = 0;
  grpc_wakeup_fd_destroy(&fd);
  {
    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
    grpc_fd_shutdown(&exec_ctx, shared.wakeup_desc, GRPC_ERROR_CANCELLED);
    grpc_fd_orphan(&exec_ctx, shared.wakeup_desc, NULL, NULL,
                   false /* already_closed */, "done");
    grpc_pollset_shutdown(&exec_ctx, shared.pollset,
                          GRPC_CLOSURE_CREATE(destroy_pollset, shared.pollset,
                                              grpc_schedule_on_exec_ctx));
    grpc_exec_ctx_finish(&exec_ctx);
  }
  gpr_free(shared.pollset);
}
// This test tries to catch deadlock situations.
// With short timeouts on "watches" and long timeouts on cq next calls,
// so that a QUEUE_TIMEOUT likely means that something is stuck.
int run_concurrent_watches_with_short_timeouts_test() {
  grpc_init();

  gpr_thd_id threads[NUM_THREADS];

  char *localhost = gpr_strdup("localhost:54321");
  gpr_thd_options options = gpr_thd_options_default();
  gpr_thd_options_set_joinable(&options);

  for (size_t i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_new(&threads[i], watches_with_short_timeouts, localhost, &options);
  }
  for (size_t i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_join(threads[i]);
  }
  gpr_free(localhost);

  grpc_shutdown();
  return 0;
}
Esempio n. 21
0
static void test_concurrency(void) {
#define NUM_THREADS 1000
  gpr_thd_id tid[NUM_THREADS];
  int i = 0;
  thd_arg arg;
  arg.num_done = 0;
  gpr_mu_init(&arg.mu);
  gpr_cv_init(&arg.done);
  census_tracing_init();
  for (i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_new(tid + i, mimic_trace_op_sequences, &arg, NULL);
  }
  gpr_mu_lock(&arg.mu);
  while (arg.num_done < NUM_THREADS) {
    gpr_log(GPR_INFO, "num done %d", arg.num_done);
    gpr_cv_wait(&arg.done, &arg.mu, gpr_inf_future);
  }
  gpr_mu_unlock(&arg.mu);
  census_tracing_shutdown();
#undef NUM_THREADS
}
Esempio n. 22
0
static void test_mt(void) {
  gpr_log(GPR_DEBUG, "test_mt");
  gpr_event start;
  gpr_event_init(&start);
  gpr_thd_id thds[100];
  thd_args ta[GPR_ARRAY_SIZE(thds)];
  gpr_mpscq q;
  gpr_mpscq_init(&q);
  for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
    gpr_thd_options options = gpr_thd_options_default();
    gpr_thd_options_set_joinable(&options);
    ta[i].ctr = 0;
    ta[i].q = &q;
    ta[i].start = &start;
    GPR_ASSERT(gpr_thd_new(&thds[i], test_thread, &ta[i], &options));
  }
  size_t num_done = 0;
  size_t spins = 0;
  gpr_event_set(&start, (void *)1);
  while (num_done != GPR_ARRAY_SIZE(thds)) {
    gpr_mpscq_node *n;
    while ((n = gpr_mpscq_pop(&q)) == NULL) {
      spins++;
    }
    test_node *tn = (test_node *)n;
    GPR_ASSERT(*tn->ctr == tn->i - 1);
    *tn->ctr = tn->i;
    if (tn->i == THREAD_ITERATIONS) num_done++;
    gpr_free(tn);
  }
  gpr_log(GPR_DEBUG, "spins: %" PRIdPTR, spins);
  for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
    gpr_thd_join(thds[i]);
  }
  gpr_mpscq_destroy(&q);
}
Esempio n. 23
0
static void init_output() {
  gpr_thd_options options = gpr_thd_options_default();
  gpr_thd_options_set_joinable(&options);
  GPR_ASSERT(gpr_thd_new(&g_writing_thread, writing_thread, NULL, &options));
  atexit(finish_writing);
}
Esempio n. 24
0
void grpc_run_bad_client_test(const char *name, const char *client_payload,
                              size_t client_payload_length,
                              grpc_bad_client_server_side_validator validator) {
  grpc_endpoint_pair sfd;
  thd_args a;
  gpr_thd_id id;
  gpr_slice slice =
      gpr_slice_from_copied_buffer(client_payload, client_payload_length);

  /* Add a debug log */
  gpr_log(GPR_INFO, "TEST: %s", name);

  /* Init grpc */
  grpc_init();

  /* Create endpoints */
  sfd = grpc_iomgr_create_endpoint_pair(65536);

  /* Create server, completion events */
  a.server = grpc_server_create_from_filters(NULL, 0, NULL);
  a.cq = grpc_completion_queue_create();
  gpr_event_init(&a.done_thd);
  gpr_event_init(&a.done_write);
  a.validator = validator;
  grpc_server_register_completion_queue(a.server, a.cq);
  grpc_server_start(a.server);
  grpc_create_chttp2_transport(server_setup_transport, &a, NULL, sfd.server,
                               NULL, 0, grpc_mdctx_create(), 0);

  /* Bind everything into the same pollset */
  grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(a.cq));
  grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq));

  /* Check a ground truth */
  GPR_ASSERT(grpc_server_has_open_connections(a.server));

  /* Start validator */
  gpr_thd_new(&id, thd_func, &a, NULL);

  /* Write data */
  switch (grpc_endpoint_write(sfd.client, &slice, 1, done_write, &a)) {
    case GRPC_ENDPOINT_WRITE_DONE:
      done_write(&a, 1);
      break;
    case GRPC_ENDPOINT_WRITE_PENDING:
      break;
    case GRPC_ENDPOINT_WRITE_ERROR:
      done_write(&a, 0);
      break;
  }

  /* Await completion */
  GPR_ASSERT(
      gpr_event_wait(&a.done_write, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));
  GPR_ASSERT(gpr_event_wait(&a.done_thd, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));

  /* Shutdown */
  grpc_endpoint_destroy(sfd.client);
  grpc_server_destroy(a.server);
  grpc_completion_queue_destroy(a.cq);

  grpc_shutdown();
}
Esempio n. 25
0
static void test_threading(int producers, int consumers) {
  test_thread_options *options =
      gpr_malloc((producers + consumers) * sizeof(test_thread_options));
  gpr_event phase1 = GPR_EVENT_INIT;
  gpr_event phase2 = GPR_EVENT_INIT;
  grpc_completion_queue *cc = grpc_completion_queue_create(NULL);
  int i;
  int total_consumed = 0;
  static int optid = 101;

  gpr_log(GPR_INFO, "%s: %d producers, %d consumers", "test_threading",
          producers, consumers);

  /* start all threads: they will wait for phase1 */
  for (i = 0; i < producers + consumers; i++) {
    gpr_thd_id id;
    gpr_event_init(&options[i].on_started);
    gpr_event_init(&options[i].on_phase1_done);
    gpr_event_init(&options[i].on_finished);
    options[i].phase1 = &phase1;
    options[i].phase2 = &phase2;
    options[i].events_triggered = 0;
    options[i].cc = cc;
    options[i].id = optid++;
    GPR_ASSERT(gpr_thd_new(&id,
                           i < producers ? producer_thread : consumer_thread,
                           options + i, NULL));
    gpr_event_wait(&options[i].on_started, ten_seconds_time());
  }

  /* start phase1: producers will pre-declare all operations they will
     complete */
  gpr_log(GPR_INFO, "start phase 1");
  gpr_event_set(&phase1, (void *)(gpr_intptr)1);

  gpr_log(GPR_INFO, "wait phase 1");
  for (i = 0; i < producers + consumers; i++) {
    GPR_ASSERT(gpr_event_wait(&options[i].on_phase1_done, ten_seconds_time()));
  }
  gpr_log(GPR_INFO, "done phase 1");

  /* start phase2: operations will complete, and consumers will consume them */
  gpr_log(GPR_INFO, "start phase 2");
  gpr_event_set(&phase2, (void *)(gpr_intptr)1);

  /* in parallel, we shutdown the completion channel - all events should still
     be consumed */
  grpc_completion_queue_shutdown(cc);

  /* join all threads */
  gpr_log(GPR_INFO, "wait phase 2");
  for (i = 0; i < producers + consumers; i++) {
    GPR_ASSERT(gpr_event_wait(&options[i].on_finished, ten_seconds_time()));
  }
  gpr_log(GPR_INFO, "done phase 2");

  /* destroy the completion channel */
  grpc_completion_queue_destroy(cc);

  /* verify that everything was produced and consumed */
  for (i = 0; i < producers + consumers; i++) {
    if (i < producers) {
      GPR_ASSERT(options[i].events_triggered == TEST_THREAD_EVENTS);
    } else {
      total_consumed += options[i].events_triggered;
    }
  }
  GPR_ASSERT(total_consumed == producers * TEST_THREAD_EVENTS);

  gpr_free(options);
}
Esempio n. 26
0
static void poll_pollset_until_request_done(args_struct *args) {
  gpr_atm_rel_store(&args->done_atm, 0);
  gpr_thd_id id;
  gpr_thd_new(&id, actually_poll, args, NULL);
}
int run_concurrent_connectivity_test() {
  struct server_thread_args args;
  memset(&args, 0, sizeof(args));

  grpc_init();

  gpr_thd_id threads[NUM_THREADS];
  gpr_thd_id server;

  char *localhost = gpr_strdup("localhost:54321");
  gpr_thd_options options = gpr_thd_options_default();
  gpr_thd_options_set_joinable(&options);

  /* First round, no server */
  gpr_log(GPR_DEBUG, "Wave 1");
  for (size_t i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_new(&threads[i], create_loop_destroy, localhost, &options);
  }
  for (size_t i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_join(threads[i]);
  }
  gpr_free(localhost);

  /* Second round, actual grpc server */
  gpr_log(GPR_DEBUG, "Wave 2");
  int port = grpc_pick_unused_port_or_die();
  gpr_asprintf(&args.addr, "localhost:%d", port);
  args.server = grpc_server_create(NULL, NULL);
  grpc_server_add_insecure_http2_port(args.server, args.addr);
  args.cq = grpc_completion_queue_create_for_next(NULL);
  grpc_server_register_completion_queue(args.server, args.cq, NULL);
  grpc_server_start(args.server);
  gpr_thd_new(&server, server_thread, &args, &options);

  for (size_t i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_new(&threads[i], create_loop_destroy, args.addr, &options);
  }
  for (size_t i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_join(threads[i]);
  }
  grpc_server_shutdown_and_notify(args.server, args.cq, tag(0xd1e));

  gpr_thd_join(server);
  grpc_server_destroy(args.server);
  grpc_completion_queue_destroy(args.cq);
  gpr_free(args.addr);

  /* Third round, bogus tcp server */
  gpr_log(GPR_DEBUG, "Wave 3");
  args.pollset = gpr_zalloc(grpc_pollset_size());
  grpc_pollset_init(args.pollset, &args.mu);
  gpr_event_init(&args.ready);
  gpr_thd_new(&server, bad_server_thread, &args, &options);
  gpr_event_wait(&args.ready, gpr_inf_future(GPR_CLOCK_MONOTONIC));

  for (size_t i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_new(&threads[i], create_loop_destroy, args.addr, &options);
  }
  for (size_t i = 0; i < NUM_THREADS; ++i) {
    gpr_thd_join(threads[i]);
  }

  gpr_atm_rel_store(&args.stop, 1);
  gpr_thd_join(server);
  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
  grpc_pollset_shutdown(&exec_ctx, args.pollset,
                        GRPC_CLOSURE_CREATE(done_pollset_shutdown, args.pollset,
                                            grpc_schedule_on_exec_ctx));
  grpc_exec_ctx_finish(&exec_ctx);

  grpc_shutdown();
  return 0;
}
Esempio n. 28
0
static void test_connectivity(grpc_end2end_test_config config) {
  grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
  grpc_connectivity_state state;
  cq_verifier *cqv = cq_verifier_create(f.cq);
  child_events ce;
  gpr_thd_options thdopt = gpr_thd_options_default();
  gpr_thd_id thdid;

  config.init_client(&f, NULL);

  ce.channel = f.client;
  ce.cq = f.cq;
  gpr_event_init(&ce.started);
  gpr_thd_options_set_joinable(&thdopt);
  GPR_ASSERT(gpr_thd_new(&thdid, child_thread, &ce, &thdopt));

  gpr_event_wait(&ce.started, gpr_inf_future(GPR_CLOCK_MONOTONIC));

  /* channels should start life in IDLE, and stay there */
  GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 0) ==
             GRPC_CHANNEL_IDLE);
  gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100));
  GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 0) ==
             GRPC_CHANNEL_IDLE);

  /* start watching for a change */
  gpr_log(GPR_DEBUG, "watching");
  grpc_channel_watch_connectivity_state(
      f.client, GRPC_CHANNEL_IDLE, gpr_now(GPR_CLOCK_MONOTONIC), f.cq, tag(1));

  /* eventually the child thread completion should trigger */
  gpr_thd_join(thdid);

  /* check that we're still in idle, and start connecting */
  GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) ==
             GRPC_CHANNEL_IDLE);
  /* start watching for a change */
  grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_IDLE,
                                        GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3),
                                        f.cq, tag(2));

  /* and now the watch should trigger */
  cq_expect_completion(cqv, tag(2), 1);
  cq_verify(cqv);
  state = grpc_channel_check_connectivity_state(f.client, 0);
  GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
             state == GRPC_CHANNEL_CONNECTING);

  /* quickly followed by a transition to TRANSIENT_FAILURE */
  grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_CONNECTING,
                                        GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3),
                                        f.cq, tag(3));
  cq_expect_completion(cqv, tag(3), 1);
  cq_verify(cqv);
  state = grpc_channel_check_connectivity_state(f.client, 0);
  GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
             state == GRPC_CHANNEL_CONNECTING);

  gpr_log(GPR_DEBUG, "*** STARTING SERVER ***");

  /* now let's bring up a server to connect to */
  config.init_server(&f, NULL);

  gpr_log(GPR_DEBUG, "*** STARTED SERVER ***");

  /* we'll go through some set of transitions (some might be missed), until
     READY is reached */
  while (state != GRPC_CHANNEL_READY) {
    grpc_channel_watch_connectivity_state(
        f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(4));
    cq_expect_completion(cqv, tag(4), 1);
    cq_verify(cqv);
    state = grpc_channel_check_connectivity_state(f.client, 0);
    GPR_ASSERT(state == GRPC_CHANNEL_READY ||
               state == GRPC_CHANNEL_CONNECTING ||
               state == GRPC_CHANNEL_TRANSIENT_FAILURE);
  }

  /* bring down the server again */
  /* we should go immediately to TRANSIENT_FAILURE */
  gpr_log(GPR_DEBUG, "*** SHUTTING DOWN SERVER ***");

  grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_READY,
                                        GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3),
                                        f.cq, tag(5));

  grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));

  cq_expect_completion(cqv, tag(5), 1);
  cq_expect_completion(cqv, tag(0xdead), 1);
  cq_verify(cqv);
  state = grpc_channel_check_connectivity_state(f.client, 0);
  GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
             state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_IDLE);

  /* cleanup server */
  grpc_server_destroy(f.server);

  gpr_log(GPR_DEBUG, "*** SHUTDOWN SERVER ***");

  grpc_channel_destroy(f.client);
  grpc_completion_queue_shutdown(f.cq);
  grpc_completion_queue_destroy(f.cq);
  config.tear_down_data(&f);

  cq_verifier_destroy(cqv);
}
Esempio n. 29
0
void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator,
                              const char *client_payload,
                              size_t client_payload_length, gpr_uint32 flags) {
  grpc_endpoint_pair sfd;
  thd_args a;
  gpr_thd_id id;
  char *hex;
  grpc_transport *transport;
  grpc_mdctx *mdctx = grpc_mdctx_create();
  gpr_slice slice =
      gpr_slice_from_copied_buffer(client_payload, client_payload_length);

  hex = gpr_dump(client_payload, client_payload_length,
                 GPR_DUMP_HEX | GPR_DUMP_ASCII);

  /* Add a debug log */
  gpr_log(GPR_INFO, "TEST: %s", hex);

  gpr_free(hex);

  /* Init grpc */
  grpc_init();

  /* Create endpoints */
  sfd = grpc_iomgr_create_endpoint_pair("fixture", 65536);

  /* Create server, completion events */
  a.server = grpc_server_create_from_filters(NULL, 0, NULL);
  a.cq = grpc_completion_queue_create(NULL);
  gpr_event_init(&a.done_thd);
  gpr_event_init(&a.done_write);
  a.validator = validator;
  grpc_server_register_completion_queue(a.server, a.cq, NULL);
  grpc_server_start(a.server);
  transport = grpc_create_chttp2_transport(NULL, sfd.server, mdctx, 0);
  server_setup_transport(&a, transport, mdctx);
  grpc_chttp2_transport_start_reading(transport, NULL, 0);

  /* Bind everything into the same pollset */
  grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(a.cq));
  grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq));

  /* Check a ground truth */
  GPR_ASSERT(grpc_server_has_open_connections(a.server));

  /* Start validator */
  gpr_thd_new(&id, thd_func, &a, NULL);

  /* Write data */
  switch (grpc_endpoint_write(sfd.client, &slice, 1, done_write, &a)) {
    case GRPC_ENDPOINT_WRITE_DONE:
      done_write(&a, 1);
      break;
    case GRPC_ENDPOINT_WRITE_PENDING:
      break;
    case GRPC_ENDPOINT_WRITE_ERROR:
      done_write(&a, 0);
      break;
  }

  /* Await completion */
  GPR_ASSERT(
      gpr_event_wait(&a.done_write, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));

  if (flags & GRPC_BAD_CLIENT_DISCONNECT) {
    grpc_endpoint_destroy(sfd.client);
    sfd.client = NULL;
  }

  GPR_ASSERT(gpr_event_wait(&a.done_thd, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));

  /* Shutdown */
  if (sfd.client) {
    grpc_endpoint_destroy(sfd.client);
  }
  grpc_server_shutdown_and_notify(a.server, a.cq, NULL);
  GPR_ASSERT(grpc_completion_queue_pluck(
                 a.cq, NULL, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL)
                 .type == GRPC_OP_COMPLETE);
  grpc_server_destroy(a.server);
  grpc_completion_queue_destroy(a.cq);

  grpc_shutdown();
}
Esempio n. 30
0
// This test launches a minimal TLS server on a separate thread and then
// establishes a TLS handshake via the core library to the server. The TLS
// server validates ALPN aspects of the handshake and supplies the protocol
// specified in the server_alpn_preferred argument to the client.
static bool client_ssl_test(char *server_alpn_preferred) {
  bool success = true;

  grpc_init();

  // Find a port we can bind to. Retries added to handle flakes in port server
  // and port picking.
  int port = -1;
  int server_socket = -1;
  int socket_retries = 10;
  while (server_socket == -1 && socket_retries-- > 0) {
    port = grpc_pick_unused_port_or_die();
    server_socket = create_socket(port);
    if (server_socket == -1) {
      sleep(1);
    }
  }
  GPR_ASSERT(server_socket > 0);

  // Launch the TLS server thread.
  gpr_thd_options thdopt = gpr_thd_options_default();
  gpr_thd_id thdid;
  gpr_thd_options_set_joinable(&thdopt);
  server_args args = {.socket = server_socket,
                      .alpn_preferred = server_alpn_preferred};
  GPR_ASSERT(gpr_thd_new(&thdid, server_thread, &args, &thdopt));

  // Load key pair and establish client SSL credentials.
  grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
  gpr_slice ca_slice, cert_slice, key_slice;
  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
                               grpc_load_file(SSL_CA_PATH, 1, &ca_slice)));
  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
                               grpc_load_file(SSL_CERT_PATH, 1, &cert_slice)));
  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
                               grpc_load_file(SSL_KEY_PATH, 1, &key_slice)));
  const char *ca_cert = (const char *)GPR_SLICE_START_PTR(ca_slice);
  pem_key_cert_pair.private_key = (const char *)GPR_SLICE_START_PTR(key_slice);
  pem_key_cert_pair.cert_chain = (const char *)GPR_SLICE_START_PTR(cert_slice);
  grpc_channel_credentials *ssl_creds =
      grpc_ssl_credentials_create(ca_cert, &pem_key_cert_pair, NULL);

  // Establish a channel pointing at the TLS server. Since the gRPC runtime is
  // lazy, this won't necessarily establish a connection yet.
  char *target;
  gpr_asprintf(&target, "127.0.0.1:%d", port);
  grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                {"foo.test.google.fr"}};
  grpc_channel_args grpc_args;
  grpc_args.num_args = 1;
  grpc_args.args = &ssl_name_override;
  grpc_channel *channel =
      grpc_secure_channel_create(ssl_creds, target, &grpc_args, NULL);
  GPR_ASSERT(channel);
  gpr_free(target);

  // Initially the channel will be idle, the
  // grpc_channel_check_connectivity_state triggers an attempt to connect.
  GPR_ASSERT(grpc_channel_check_connectivity_state(
                 channel, 1 /* try_to_connect */) == GRPC_CHANNEL_IDLE);

  // Wait a bounded number of times for the channel to be ready. When the
  // channel is ready, the initial TLS handshake will have successfully
  // completed and we know that the client's ALPN list satisfied the server.
  int retries = 10;
  grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
  while (state != GRPC_CHANNEL_READY && retries-- > 0) {
    grpc_channel_watch_connectivity_state(
        channel, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), cq, NULL);
    gpr_timespec cq_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
    grpc_event ev = grpc_completion_queue_next(cq, cq_deadline, NULL);
    GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
    state =
        grpc_channel_check_connectivity_state(channel, 0 /* try_to_connect */);
  }
  grpc_completion_queue_destroy(cq);
  if (retries < 0) {
    success = false;
  }

  grpc_channel_destroy(channel);
  grpc_channel_credentials_release(ssl_creds);
  gpr_slice_unref(cert_slice);
  gpr_slice_unref(key_slice);
  gpr_slice_unref(ca_slice);

  gpr_thd_join(thdid);

  grpc_shutdown();

  return success;
}