Пример #1
0
/* Writes the given number of records of random size (up to kMaxRecordSize) and
   random data to the specified log. */
static void writer_thread(void* arg) {
  writer_thread_args* args = (writer_thread_args*)arg;
  /* Maximum number of times to spin between writes. */
  static const gpr_int32 MAX_SPIN_COUNT = 50;
  int records_written = 0;
  printf("   Writer: %d\n", args->index);
  while (records_written < args->num_records) {
    records_written += write_records_to_log(args->index, args->record_size,
                                            args->num_records - records_written,
                                            MAX_SPIN_COUNT);
    if (records_written < args->num_records) {
      /* Ran out of log space. Sleep for a bit and let the reader catch up.
         This should never happen for circular logs. */
      printf("   Writer stalled due to out-of-space: %d out of %d written\n",
             records_written, args->num_records);
      gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
    }
  }
  /* Done. Decrement count and signal. */
  gpr_mu_lock(args->mu);
  (*args->count)--;
  gpr_cv_broadcast(args->done);
  printf("   Writer done: %d\n", args->index);
  gpr_mu_unlock(args->mu);
}
Пример #2
0
/* Create and append an event to the queue. Returns the event so that its data
   members can be filled in.
   Requires GRPC_POLLSET_MU(&cc->pollset) locked. */
static event *add_locked(grpc_completion_queue *cc, grpc_completion_type type,
                         void *tag, grpc_call *call,
                         grpc_event_finish_func on_finish, void *user_data) {
  event *ev = gpr_malloc(sizeof(event));
  gpr_uintptr bucket = ((gpr_uintptr)tag) % NUM_TAG_BUCKETS;
  ev->base.type = type;
  ev->base.tag = tag;
  ev->base.call = call;
  ev->on_finish = on_finish ? on_finish : null_on_finish;
  ev->on_finish_user_data = user_data;
  if (cc->queue == NULL) {
    cc->queue = ev->queue_next = ev->queue_prev = ev;
  } else {
    ev->queue_next = cc->queue;
    ev->queue_prev = cc->queue->queue_prev;
    ev->queue_next->queue_prev = ev->queue_prev->queue_next = ev;
  }
  if (cc->buckets[bucket] == NULL) {
    cc->buckets[bucket] = ev->bucket_next = ev->bucket_prev = ev;
  } else {
    ev->bucket_next = cc->buckets[bucket];
    ev->bucket_prev = cc->buckets[bucket]->bucket_prev;
    ev->bucket_next->bucket_prev = ev->bucket_prev->bucket_next = ev;
  }
  gpr_cv_broadcast(GRPC_POLLSET_CV(&cc->pollset));
  grpc_pollset_kick(&cc->pollset);
  return ev;
}
Пример #3
0
static void* set_abort_channel_polling_without_gil(void* arg) {
  (void)arg;
  gpr_mu_lock(&global_connection_polling_mu);
  abort_channel_polling = 1;
  gpr_cv_broadcast(&global_connection_polling_cv);
  gpr_mu_unlock(&global_connection_polling_mu);
  return NULL;
}
Пример #4
0
// Needs to be called under global_connection_polling_mu
static void grpc_rb_channel_watch_connection_state_op_complete(
    watch_state_op* op, int success) {
  GPR_ASSERT(!op->op.api_callback_args.called_back);
  op->op.api_callback_args.called_back = 1;
  op->op.api_callback_args.success = success;
  // wake up the watch API call thats waiting on this op
  gpr_cv_broadcast(&global_connection_polling_cv);
}
Пример #5
0
static void watch_channel_state_unblocking_func(void *arg) {
  grpc_rb_channel *wrapper = (grpc_rb_channel*)arg;
  gpr_log(GPR_DEBUG, "GRPC_RUBY: watch channel state unblocking func called");
  gpr_mu_lock(&wrapper->channel_mu);
  wrapper->abort_watch_connectivity_state = 1;
  gpr_cv_broadcast(&wrapper->channel_cv);
  gpr_mu_unlock(&wrapper->channel_mu);
}
Пример #6
0
void grpc_pollset_shutdown(grpc_pollset *pollset,
                           void (*shutdown_done)(void *arg),
                           void *shutdown_done_arg) {
    gpr_mu_lock(&pollset->mu);
    pollset->shutting_down = 1;
    gpr_cv_broadcast(&pollset->cv);
    gpr_mu_unlock(&pollset->mu);
    shutdown_done(shutdown_done_arg);
}
Пример #7
0
static void on_connect(void *arg, grpc_endpoint *tcp) {
  grpc_endpoint_shutdown(tcp);
  grpc_endpoint_destroy(tcp);

  gpr_mu_lock(&mu);
  nconnects++;
  gpr_cv_broadcast(&cv);
  gpr_mu_unlock(&mu);
}
Пример #8
0
void gpr_event_set(gpr_event *ev, void *value) {
  struct sync_array_s *s = hash(ev);
  gpr_mu_lock(&s->mu);
  GPR_ASSERT(gpr_atm_acq_load(&ev->state) == 0);
  gpr_atm_rel_store(&ev->state, (gpr_atm)value);
  gpr_cv_broadcast(&s->cv);
  gpr_mu_unlock(&s->mu);
  GPR_ASSERT(value != NULL);
}
Пример #9
0
static void decrement_active_ports_and_notify(server_port *sp) {
  sp->shutting_down = 0;
  sp->socket->read_info.outstanding = 0;
  gpr_mu_lock(&sp->server->mu);
  GPR_ASSERT(sp->server->active_ports > 0);
  if (0 == --sp->server->active_ports) {
    gpr_cv_broadcast(&sp->server->cv);
  }
  gpr_mu_unlock(&sp->server->mu);
}
Пример #10
0
static void wait_until_channel_polling_thread_started_unblocking_func(
    void* arg) {
  int* stop_waiting = (int*)arg;
  gpr_mu_lock(&global_connection_polling_mu);
  gpr_log(GPR_DEBUG,
          "GRPC_RUBY: interrupt wait for channel polling thread to start");
  *stop_waiting = 1;
  gpr_cv_broadcast(&global_connection_polling_cv);
  gpr_mu_unlock(&global_connection_polling_mu);
}
Пример #11
0
/* Signal the end of an operation - if this is the last waiting-to-be-queued
   event, then enter shutdown mode */
static void end_op_locked(grpc_completion_queue *cc,
                          grpc_completion_type type) {
#ifndef NDEBUG
  GPR_ASSERT(gpr_atm_full_fetch_add(&cc->pending_op_count[type], -1) > 0);
#endif
  if (gpr_unref(&cc->refs)) {
    GPR_ASSERT(!cc->shutdown);
    GPR_ASSERT(cc->shutdown_called);
    cc->shutdown = 1;
    gpr_cv_broadcast(GRPC_POLLSET_CV(&cc->pollset));
  }
}
Пример #12
0
/* Shutdown simply drops a ref that we reserved at creation time; if we drop
   to zero here, then enter shutdown mode and wake up any waiters */
void grpc_completion_queue_shutdown(grpc_completion_queue *cc) {
  gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
  cc->shutdown_called = 1;
  gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));

  if (gpr_unref(&cc->refs)) {
    gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
    GPR_ASSERT(!cc->shutdown);
    cc->shutdown = 1;
    gpr_cv_broadcast(GRPC_POLLSET_CV(&cc->pollset));
    gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
  }
}
Пример #13
0
void gpr_cancellable_cancel(gpr_cancellable *c) {
  if (!gpr_cancellable_is_cancelled(c)) {
    int failures;
    int backoff = 1;
    do {
      struct gpr_cancellable_list_ *l;
      struct gpr_cancellable_list_ *nl;
      gpr_mu *omu = 0; /* one-element cache of a processed gpr_mu */
      gpr_cv *ocv = 0; /* one-element cache of a processd gpr_cv */
      gpr_mu_lock(&c->mu);
      gpr_atm_rel_store(&c->cancelled, 1);
      failures = 0;
      for (l = c->waiters.next; l != &c->waiters; l = nl) {
        nl = l->next;
        if (omu != l->mu) {
          omu = l->mu;
          if (gpr_mu_trylock(l->mu)) {
            gpr_mu_unlock(l->mu);
            l->next->prev = l->prev; /* remove *l from list */
            l->prev->next = l->next;
            /* allow unconditional dequeue in gpr_cv_cancellable_wait() */
            l->next = l;
            l->prev = l;
            ocv = 0; /* force broadcast */
          } else {
            failures++;
          }
        }
        if (ocv != l->cv) {
          ocv = l->cv;
          gpr_cv_broadcast(l->cv);
        }
      }
      gpr_mu_unlock(&c->mu);
      if (failures != 0) {
        if (backoff < 10) {
          volatile int i;
          for (i = 0; i != (1 << backoff); i++) {
          }
          backoff++;
        } else {
          gpr_event ev;
          gpr_event_init(&ev);
          gpr_event_wait(
              &ev, gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
                                gpr_time_from_micros(1000, GPR_TIMESPAN)));
        }
      }
    } while (failures != 0);
  }
}
Пример #14
0
/* event manager callback when reads are ready */
static void on_read(void *arg, int success) {
  server_port *sp = arg;

  if (!success) {
    goto error;
  }

  /* loop until accept4 returns EAGAIN, and then re-arm notification */
  for (;;) {
    struct sockaddr_storage addr;
    socklen_t addrlen = sizeof(addr);
    char *addr_str;
    char *name;
    /* Note: If we ever decide to return this address to the user, remember to
             strip off the ::ffff:0.0.0.0/96 prefix first. */
    int fd = grpc_accept4(sp->fd, (struct sockaddr *)&addr, &addrlen, 1, 1);
    if (fd < 0) {
      switch (errno) {
        case EINTR:
          continue;
        case EAGAIN:
          grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
          return;
        default:
          gpr_log(GPR_ERROR, "Failed accept4: %s", strerror(errno));
          goto error;
      }
    }

    grpc_set_socket_no_sigpipe_if_possible(fd);

    grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
    gpr_asprintf(&name, "tcp-server-connection:%s", addr_str);

    sp->server->cb(sp->server->cb_arg,
                   grpc_tcp_create(grpc_fd_create(fd, name),
                                   GRPC_TCP_DEFAULT_READ_SLICE_SIZE));

    gpr_free(addr_str);
    gpr_free(name);
  }

  abort();

error:
  gpr_mu_lock(&sp->server->mu);
  if (0 == --sp->server->active_ports) {
    gpr_cv_broadcast(&sp->server->cv);
  }
  gpr_mu_unlock(&sp->server->mu);
}
Пример #15
0
/* Increment counter only when (m->counter%m->threads)==m->thread_id; then mark
   thread as done.  */
static void inc_by_turns(void *v /*=m*/) {
  struct test *m = v;
  gpr_int64 i;
  int id = thread_id(m);
  for (i = 0; i != m->iterations; i++) {
    gpr_mu_lock(&m->mu);
    while ((m->counter % m->threads) != id) {
      gpr_cv_wait(&m->cv, &m->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
    }
    m->counter++;
    gpr_cv_broadcast(&m->cv);
    gpr_mu_unlock(&m->mu);
  }
  mark_thread_done(m);
}
Пример #16
0
/* If it can be done without blocking, append x to *q and return non-zero.
   Otherwise return 0. */
int queue_try_append(queue *q, int x) {
  int result = 0;
  if (gpr_mu_trylock(&q->mu)) {
    if (q->length != N) {
      if (q->length == 0) { /* Wake threads blocked in queue_remove(). */
        gpr_cv_broadcast(&q->non_empty);
      }
      q->elem[(q->head + q->length) % N] = x;
      q->length++;
      result = 1;
    }
    gpr_mu_unlock(&q->mu);
  }
  return result;
}
Пример #17
0
// Note this loop breaks out with a single call of
// "run_poll_channels_loop_no_gil".
// This assumes that a ruby call the unblocking func
// indicates process shutdown.
// In the worst case, this stops polling channel connectivity
// early and falls back to current behavior.
static void* run_poll_channels_loop_no_gil(void* arg) {
  grpc_event event;
  watch_state_op* op = NULL;
  bg_watched_channel* bg = NULL;
  (void)arg;
  gpr_log(GPR_DEBUG, "GRPC_RUBY: run_poll_channels_loop_no_gil - begin");

  gpr_mu_lock(&global_connection_polling_mu);
  GPR_ASSERT(!channel_polling_thread_started);
  channel_polling_thread_started = 1;
  gpr_cv_broadcast(&global_connection_polling_cv);
  gpr_mu_unlock(&global_connection_polling_mu);

  for (;;) {
    event = grpc_completion_queue_next(
        channel_polling_cq, gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
    if (event.type == GRPC_QUEUE_SHUTDOWN) {
      break;
    }
    gpr_mu_lock(&global_connection_polling_mu);
    if (event.type == GRPC_OP_COMPLETE) {
      op = (watch_state_op*)event.tag;
      if (op->op_type == CONTINUOUS_WATCH) {
        bg = (bg_watched_channel*)op->op.continuous_watch_callback_args.bg;
        bg->refcount--;
        grpc_rb_channel_try_register_connection_polling(bg);
        gpr_free(op);
      } else if (op->op_type == WATCH_STATE_API) {
        grpc_rb_channel_watch_connection_state_op_complete(
            (watch_state_op*)event.tag, event.success);
      } else {
        GPR_ASSERT(0);
      }
    }
    gpr_mu_unlock(&global_connection_polling_mu);
  }
  grpc_completion_queue_destroy(channel_polling_cq);
  gpr_log(GPR_DEBUG,
          "GRPC_RUBY: run_poll_channels_loop_no_gil - exit connection polling "
          "loop");
  return NULL;
}
Пример #18
0
/* Wait until there is room in *q, then append x to *q. */
void queue_append(queue *q, int x) {
  gpr_mu_lock(&q->mu);
  /* To wait for a predicate without a deadline, loop on the negation of the
     predicate, and use gpr_cv_wait(..., gpr_inf_future(GPR_CLOCK_REALTIME))
     inside the loop
     to release the lock, wait, and reacquire on each iteration.  Code that
     makes the condition true should use gpr_cv_broadcast() on the
     corresponding condition variable.  The predicate must be on state
     protected by the lock.  */
  while (q->length == N) {
    gpr_cv_wait(&q->non_full, &q->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
  }
  if (q->length == 0) { /* Wake threads blocked in queue_remove(). */
    /* It's normal to use gpr_cv_broadcast() or gpr_signal() while
       holding the lock. */
    gpr_cv_broadcast(&q->non_empty);
  }
  q->elem[(q->head + q->length) % N] = x;
  q->length++;
  gpr_mu_unlock(&q->mu);
}
Пример #19
0
static void mimic_trace_op_sequences(void* arg) {
  census_op_id id;
  const char* method_name = "service_foo/method_bar";
  int i = 0;
  const int num_iter = 200;
  thd_arg* args = (thd_arg*)arg;
  GPR_ASSERT(args != NULL);
  gpr_log(GPR_INFO, "Start trace op sequence thread.");
  for (i = 0; i < num_iter; i++) {
    id = census_tracing_start_op();
    census_add_method_tag(id, method_name);
    /* pretend doing 1us work. */
    gpr_sleep_until(GRPC_TIMEOUT_MICROS_TO_DEADLINE(1));
    census_tracing_end_op(id);
  }
  gpr_log(GPR_INFO, "End trace op sequence thread.");
  gpr_mu_lock(&args->mu);
  args->num_done += 1;
  gpr_cv_broadcast(&args->done);
  gpr_mu_unlock(&args->mu);
}
Пример #20
0
/* Wait until the *q is non-empty or deadline abs_deadline passes.  If the
   queue is non-empty, remove its head entry, place it in *head, and return
   non-zero.  Otherwise return 0.  */
int queue_remove(queue *q, int *head, gpr_timespec abs_deadline) {
  int result = 0;
  gpr_mu_lock(&q->mu);
  /* To wait for a predicate with a deadline, loop on the negation of the
     predicate or until gpr_cv_wait() returns true.  Code that makes
     the condition true should use gpr_cv_broadcast() on the corresponding
     condition variable.  The predicate must be on state protected by the
     lock. */
  while (q->length == 0 && !gpr_cv_wait(&q->non_empty, &q->mu, abs_deadline)) {
  }
  if (q->length != 0) { /* Queue is non-empty. */
    result = 1;
    if (q->length == N) { /* Wake threads blocked in queue_append(). */
      gpr_cv_broadcast(&q->non_full);
    }
    *head = q->elem[q->head];
    q->head = (q->head + 1) % N;
    q->length--;
  } /* else deadline exceeded */
  gpr_mu_unlock(&q->mu);
  return result;
}
Пример #21
0
/* Event manager callback when reads are ready. */
static void on_accept(void *arg, int from_iocp) {
  server_port *sp = arg;
  SOCKET sock = sp->new_socket;
  grpc_winsocket_callback_info *info = &sp->socket->read_info;
  grpc_endpoint *ep = NULL;

  /* The shutdown sequence is done in two parts. This is the second
     part here, acknowledging the IOCP notification, and doing nothing
     else, especially not queuing a new accept. */
  if (sp->shutting_down) {
    GPR_ASSERT(from_iocp);
    sp->shutting_down = 0;
    gpr_mu_lock(&sp->server->mu);
    if (0 == --sp->server->active_ports) {
      gpr_cv_broadcast(&sp->server->cv);
    }
    gpr_mu_unlock(&sp->server->mu);
    return;
  }

  if (from_iocp) {
    /* The IOCP notified us of a completed operation. Let's grab the results,
       and act accordingly. */
    DWORD transfered_bytes = 0;
    DWORD flags;
    BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
                                              &transfered_bytes, FALSE, &flags);
    if (!wsa_success) {
      char *utf8_message = gpr_format_message(WSAGetLastError());
      gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message);
      gpr_free(utf8_message);
      closesocket(sock);
    } else {
      ep = grpc_tcp_create(grpc_winsocket_create(sock));
    }
  } else {
    /* If we're not notified from the IOCP, it means we are asked to shutdown.
       This will initiate that shutdown. Calling closesocket will trigger an
       IOCP notification, that will call this function a second time, from
       the IOCP thread. Of course, this only works if the socket was, in fact,
       listening. If that's not the case, we'd wait indefinitely. That's a bit
       of a degenerate case, but it can happen if you create a server, but
       don't start it. So let's support that by recursing once. */
    sp->shutting_down = 1;
    sp->new_socket = INVALID_SOCKET;
    if (sock != INVALID_SOCKET) {
      closesocket(sock);
    } else {
      on_accept(sp, 1);
    }
    return;
  }

  /* The only time we should call our callback, is where we successfully
     managed to accept a connection, and created an endpoint. */
  if (ep) sp->server->cb(sp->server->cb_arg, ep);
  /* As we were notified from the IOCP of one and exactly one accept,
      the former socked we created has now either been destroy or assigned
      to the new connection. We need to create a new one for the next
      connection. */
  start_accept(sp);
}
Пример #22
0
/* Event manager callback when reads are ready. */
static void on_accept(void *arg, int from_iocp) {
  server_port *sp = arg;
  SOCKET sock = sp->new_socket;
  grpc_winsocket_callback_info *info = &sp->socket->read_info;
  grpc_endpoint *ep = NULL;
  struct sockaddr_storage peer_name;
  char *peer_name_string;
  char *fd_name;
  int peer_name_len = sizeof(peer_name);
  DWORD transfered_bytes;
  DWORD flags;
  BOOL wsa_success;
  int err;

  /* The general mechanism for shutting down is to queue abortion calls. While
     this is necessary in the read/write case, it's useless for the accept
     case. We only need to adjust the pending callback count */
  if (!from_iocp) {
    gpr_mu_lock(&sp->server->mu);
    GPR_ASSERT(sp->server->iomgr_callbacks_pending > 0);
    if (0 == --sp->server->iomgr_callbacks_pending) {
      gpr_cv_broadcast(&sp->server->cv);
    }
    gpr_mu_unlock(&sp->server->mu);
    return;
  }

  /* The IOCP notified us of a completed operation. Let's grab the results,
      and act accordingly. */
  transfered_bytes = 0;
  wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
                                       &transfered_bytes, FALSE, &flags);
  if (!wsa_success) {
    if (sp->shutting_down) {
      /* During the shutdown case, we ARE expecting an error. So that's well,
         and we can wake up the shutdown thread. */
      decrement_active_ports_and_notify(sp);
      return;
    } else {
      char *utf8_message = gpr_format_message(WSAGetLastError());
      gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message);
      gpr_free(utf8_message);
      closesocket(sock);
    }
  } else {
    if (!sp->shutting_down) {
      peer_name_string = NULL;
      err = setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
                       (char *)&sp->socket->socket, sizeof(sp->socket->socket));
      if (err) {
        char *utf8_message = gpr_format_message(WSAGetLastError());
        gpr_log(GPR_ERROR, "setsockopt error: %s", utf8_message);
        gpr_free(utf8_message);
      }
      err = getpeername(sock, (struct sockaddr *)&peer_name, &peer_name_len);
      if (!err) {
        peer_name_string = grpc_sockaddr_to_uri((struct sockaddr *)&peer_name);
      } else {
        char *utf8_message = gpr_format_message(WSAGetLastError());
        gpr_log(GPR_ERROR, "getpeername error: %s", utf8_message);
        gpr_free(utf8_message);
      }
      gpr_asprintf(&fd_name, "tcp_server:%s", peer_name_string);
      ep = grpc_tcp_create(grpc_winsocket_create(sock, fd_name),
                           peer_name_string);
      gpr_free(fd_name);
      gpr_free(peer_name_string);
    }
  }

  /* The only time we should call our callback, is where we successfully
     managed to accept a connection, and created an endpoint. */
  if (ep) sp->server->cb(sp->server->cb_arg, ep);
  /* As we were notified from the IOCP of one and exactly one accept,
     the former socked we created has now either been destroy or assigned
     to the new connection. We need to create a new one for the next
     connection. */
  start_accept(sp);
}
Пример #23
0
/*
  call-seq:
    insecure_channel = Channel:new("myhost:8080", {'arg1': 'value1'},
                                   :this_channel_is_insecure)
    creds = ...
    secure_channel = Channel:new("myhost:443", {'arg1': 'value1'}, creds)

  Creates channel instances. */
static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
  VALUE channel_args = Qnil;
  VALUE credentials = Qnil;
  VALUE target = Qnil;
  grpc_rb_channel *wrapper = NULL;
  grpc_channel *ch = NULL;
  grpc_channel_credentials *creds = NULL;
  char *target_chars = NULL;
  grpc_channel_args args;
  MEMZERO(&args, grpc_channel_args, 1);

  /* "3" == 3 mandatory args */
  rb_scan_args(argc, argv, "3", &target, &channel_args, &credentials);

  TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper);
  wrapper->mu_init_done = 0;
  target_chars = StringValueCStr(target);
  grpc_rb_hash_convert_to_channel_args(channel_args, &args);
  if (TYPE(credentials) == T_SYMBOL) {
    if (id_insecure_channel != SYM2ID(credentials)) {
      rb_raise(rb_eTypeError,
               "bad creds symbol, want :this_channel_is_insecure");
      return Qnil;
    }
    ch = grpc_insecure_channel_create(target_chars, &args, NULL);
  } else {
    wrapper->credentials = credentials;
    creds = grpc_rb_get_wrapped_channel_credentials(credentials);
    ch = grpc_secure_channel_create(creds, target_chars, &args, NULL);
  }

  GPR_ASSERT(ch);

  wrapper->wrapped = ch;

  gpr_mu_init(&wrapper->channel_mu);
  gpr_cv_init(&wrapper->channel_cv);
  wrapper->mu_init_done = 1;

  gpr_mu_lock(&wrapper->channel_mu);
  wrapper->abort_watch_connectivity_state = 0;
  wrapper->current_connectivity_state = grpc_channel_check_connectivity_state(wrapper->wrapped, 0);
  wrapper->safe_to_destroy = 0;
  wrapper->request_safe_destroy = 0;

  gpr_cv_broadcast(&wrapper->channel_cv);
  gpr_mu_unlock(&wrapper->channel_mu);


  grpc_rb_channel_try_register_connection_polling(wrapper);

  if (args.args != NULL) {
    xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
  }
  if (ch == NULL) {
    rb_raise(rb_eRuntimeError, "could not create an rpc channel to target:%s",
             target_chars);
    return Qnil;
  }
  rb_ivar_set(self, id_target, target);
  wrapper->wrapped = ch;
  return self;
}
Пример #24
0
// Trigger a "socket" POLLIN in mock_poll()
void trigger_socket_event() {
  gpr_mu_lock(&poll_mu);
  socket_event = 1;
  gpr_cv_broadcast(&poll_cv);
  gpr_mu_unlock(&poll_mu);
}
Пример #25
0
void grpc_kick_poller(void) { gpr_cv_broadcast(&g_cv); }