Esempio n. 1
0
static void server_on_recv(void *ptr, int success) {
  grpc_call_element *elem = ptr;
  call_data *calld = elem->call_data;
  channel_data *chand = elem->channel_data;

  if (success && !calld->got_initial_metadata) {
    size_t i;
    size_t nops = calld->recv_ops->nops;
    grpc_stream_op *ops = calld->recv_ops->ops;
    for (i = 0; i < nops; i++) {
      grpc_stream_op *op = &ops[i];
      if (op->type != GRPC_OP_METADATA) continue;
      grpc_metadata_batch_filter(&op->data.metadata, server_filter, elem);
      if (0 != gpr_time_cmp(op->data.metadata.deadline, gpr_inf_future)) {
        calld->deadline = op->data.metadata.deadline;
      }
      calld->got_initial_metadata = 1;
      start_new_rpc(elem);
      break;
    }
  }

  switch (*calld->recv_state) {
    case GRPC_STREAM_OPEN:
      break;
    case GRPC_STREAM_SEND_CLOSED:
      break;
    case GRPC_STREAM_RECV_CLOSED:
      gpr_mu_lock(&chand->server->mu);
      if (calld->state == NOT_STARTED) {
        calld->state = ZOMBIED;
        grpc_iomgr_add_callback(kill_zombie, elem);
      }
      gpr_mu_unlock(&chand->server->mu);
      break;
    case GRPC_STREAM_CLOSED:
      gpr_mu_lock(&chand->server->mu);
      if (calld->state == NOT_STARTED) {
        calld->state = ZOMBIED;
        grpc_iomgr_add_callback(kill_zombie, elem);
      } else if (calld->state == PENDING) {
        call_list_remove(calld, PENDING_START);
        calld->state = ZOMBIED;
        grpc_iomgr_add_callback(kill_zombie, elem);
      }
      gpr_mu_unlock(&chand->server->mu);
      break;
  }

  calld->on_done_recv(calld->recv_user_data, success);
}
Esempio n. 2
0
void grpc_channel_internal_unref(grpc_channel *channel) {
  if (gpr_unref(&channel->refs)) {
    channel->destroy_closure.cb = destroy_channel;
    channel->destroy_closure.cb_arg = channel;
    grpc_iomgr_add_callback(&channel->destroy_closure);
  }
}
Esempio n. 3
0
static void on_secure_transport_setup_done(void *arg,
                                           grpc_security_status status,
                                           grpc_endpoint *wrapped_endpoint,
                                           grpc_endpoint *secure_endpoint) {
  connector *c = arg;
  grpc_iomgr_closure *notify;
  gpr_mu_lock(&c->mu);
  if (c->connecting_endpoint == NULL) {
    memset(c->result, 0, sizeof(*c->result));
    gpr_mu_unlock(&c->mu);
  } else if (status != GRPC_SECURITY_OK) {
    GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint);
    gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
    memset(c->result, 0, sizeof(*c->result));
    c->connecting_endpoint = NULL;
    gpr_mu_unlock(&c->mu);
  } else {
    GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint);
    c->connecting_endpoint = NULL;
    gpr_mu_unlock(&c->mu);
    c->result->transport = grpc_create_chttp2_transport(
        c->args.channel_args, secure_endpoint, c->args.metadata_context, 1);
    grpc_chttp2_transport_start_reading(c->result->transport, NULL, 0);
    c->result->filters = gpr_malloc(sizeof(grpc_channel_filter *) * 2);
    c->result->filters[0] = &grpc_http_client_filter;
    c->result->filters[1] = &grpc_client_auth_filter;
    c->result->num_filters = 2;
  }
  notify = c->notify;
  c->notify = NULL;
  grpc_iomgr_add_callback(notify);
}
Esempio n. 4
0
static void maybe_destroy_channel(grpc_child_channel *channel) {
  lb_channel_data *chand = LINK_BACK_ELEM_FROM_CHANNEL(channel)->channel_data;
  if (chand->destroyed && chand->disconnected && chand->active_calls == 0 &&
      !chand->sending_farewell && !chand->calling_back) {
    chand->finally_destroy_channel_closure.cb = finally_destroy_channel;
    chand->finally_destroy_channel_closure.cb_arg = channel;
    grpc_iomgr_add_callback(&chand->finally_destroy_channel_closure);
  } else if (chand->destroyed && !chand->disconnected &&
             chand->active_calls == 0 && !chand->sending_farewell &&
             !chand->sent_farewell) {
    chand->sending_farewell = 1;
    chand->send_farewells_closure.cb = send_farewells;
    chand->send_farewells_closure.cb_arg = channel;
    grpc_iomgr_add_callback(&chand->send_farewells_closure);
  }
}
Esempio n. 5
0
File: server.c Progetto: penser/grpc
static void destroy_channel(channel_data *chand) {
  if (is_channel_orphaned(chand)) return;
  GPR_ASSERT(chand->server != NULL);
  orphan_channel(chand);
  server_ref(chand->server);
  grpc_iomgr_add_callback(finish_destroy_channel, chand);
}
Esempio n. 6
0
void grpc_call_internal_unref(grpc_call *c, const char *reason,
                              int allow_immediate_deletion) {
  gpr_log(GPR_DEBUG, "CALL: unref %p %d -> %d [%s]", c,
          c->internal_refcount.count, c->internal_refcount.count - 1, reason);
#else
void grpc_call_internal_unref(grpc_call *c, int allow_immediate_deletion) {
#endif
  if (gpr_unref(&c->internal_refcount)) {
    if (allow_immediate_deletion) {
      destroy_call(c, 1);
    } else {
      grpc_iomgr_add_callback(destroy_call, c);
    }
  }
}

static void set_status_code(grpc_call *call, status_source source,
                            gpr_uint32 status) {
  call->status[source].is_set = 1;
  call->status[source].code = status;

  if (status != GRPC_STATUS_OK && !grpc_bbq_empty(&call->incoming_queue)) {
    grpc_bbq_flush(&call->incoming_queue);
  }
}
Esempio n. 7
0
File: call.c Progetto: qioixiy/grpc
void grpc_call_internal_unref(grpc_call *c, int allow_immediate_deletion) {
  if (gpr_unref(&c->internal_refcount)) {
    if (allow_immediate_deletion) {
      destroy_call(c, 1);
    } else {
      grpc_iomgr_add_callback(destroy_call, c);
    }
  }
}
Esempio n. 8
0
static void unref_by(grpc_fd *fd, int n) {
  gpr_atm old = gpr_atm_full_fetch_add(&fd->refst, -n);
  if (old == n) {
    grpc_iomgr_add_callback(&fd->on_done_closure);
    freelist_fd(fd);
    grpc_iomgr_unregister_object(&fd->iomgr_object);
  } else {
    GPR_ASSERT(old > n);
  }
}
Esempio n. 9
0
static void destroy_channel(channel_data *chand) {
  if (is_channel_orphaned(chand)) return;
  GPR_ASSERT(chand->server != NULL);
  orphan_channel(chand);
  server_ref(chand->server);
  maybe_finish_shutdown(chand->server);
  chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
  chand->finish_destroy_channel_closure.cb_arg = chand;
  grpc_iomgr_add_callback(&chand->finish_destroy_channel_closure);
}
Esempio n. 10
0
static void dns_shutdown(grpc_resolver *resolver) {
  dns_resolver *r = (dns_resolver *)resolver;
  gpr_mu_lock(&r->mu);
  if (r->next_completion != NULL) {
    *r->target_config = NULL;
    grpc_iomgr_add_callback(r->next_completion);
    r->next_completion = NULL;
  }
  gpr_mu_unlock(&r->mu);
}
Esempio n. 11
0
static void unix_shutdown(grpc_resolver *resolver) {
  unix_resolver *r = (unix_resolver *)resolver;
  gpr_mu_lock(&r->mu);
  if (r->next_completion != NULL) {
    *r->target_config = NULL;
    /* TODO(ctiller): add delayed callback */
    grpc_iomgr_add_callback(r->next_completion);
    r->next_completion = NULL;
  }
  gpr_mu_unlock(&r->mu);
}
Esempio n. 12
0
static void shutdown_channel(channel_data *chand, int send_goaway,
                             int send_disconnect) {
  shutdown_channel_args *sca;
  GRPC_CHANNEL_INTERNAL_REF(chand->channel, "shutdown");
  sca = gpr_malloc(sizeof(shutdown_channel_args));
  sca->chand = chand;
  sca->send_goaway = send_goaway;
  sca->send_disconnect = send_disconnect;
  sca->finish_shutdown_channel_closure.cb = finish_shutdown_channel;
  sca->finish_shutdown_channel_closure.cb_arg = sca;
  grpc_iomgr_add_callback(&sca->finish_shutdown_channel_closure);
}
Esempio n. 13
0
static void dns_maybe_finish_next_locked(dns_resolver *r) {
  if (r->next_completion != NULL &&
      r->resolved_version != r->published_version) {
    *r->target_config = r->resolved_config;
    if (r->resolved_config) {
      grpc_client_config_ref(r->resolved_config);
    }
    grpc_iomgr_add_callback(r->next_completion);
    r->next_completion = NULL;
    r->published_version = r->resolved_version;
  }
}
Esempio n. 14
0
static void connected(void *arg, grpc_endpoint *tcp) {
  connector *c = arg;
  grpc_iomgr_closure *notify;
  if (tcp != NULL) {
    grpc_setup_secure_transport(&c->security_connector->base, tcp,
                                on_secure_transport_setup_done, c);
  } else {
    memset(c->result, 0, sizeof(*c->result));
    notify = c->notify;
    c->notify = NULL;
    grpc_iomgr_add_callback(notify);
  }
}
Esempio n. 15
0
static void fake_oauth2_get_request_metadata(grpc_credentials *creds,
                                             const char *service_url,
                                             grpc_credentials_metadata_cb cb,
                                             void *user_data) {
  grpc_fake_oauth2_credentials *c = (grpc_fake_oauth2_credentials *)creds;

  if (c->is_async) {
    grpc_iomgr_add_callback(
        on_simulated_token_fetch_done,
        grpc_credentials_metadata_request_create(creds, cb, user_data));
  } else {
    cb(user_data, &c->access_token_md, 1, GRPC_CREDENTIALS_OK);
  }
}
Esempio n. 16
0
static void basic_pollset_add_fd(grpc_pollset *pollset, grpc_fd *fd,
                                 int and_unlock_pollset) {
  grpc_unary_promote_args *up_args;
  GPR_ASSERT(fd);
  if (fd == pollset->data.ptr) goto exit;

  if (!grpc_pollset_has_workers(pollset)) {
    /* Fast path -- no in flight cbs */
    /* TODO(klempner): Comment this out and fix any test failures or establish
     * they are due to timing issues */
    grpc_fd *fds[2];
    fds[0] = pollset->data.ptr;
    fds[1] = fd;

    if (fds[0] == NULL) {
      pollset->data.ptr = fd;
      GRPC_FD_REF(fd, "basicpoll");
    } else if (!grpc_fd_is_orphaned(fds[0])) {
      grpc_platform_become_multipoller(pollset, fds, GPR_ARRAY_SIZE(fds));
      GRPC_FD_UNREF(fds[0], "basicpoll");
    } else {
      /* old fd is orphaned and we haven't cleaned it up until now, so remain a
       * unary poller */
      GRPC_FD_UNREF(fds[0], "basicpoll");
      pollset->data.ptr = fd;
      GRPC_FD_REF(fd, "basicpoll");
    }
    goto exit;
  }

  /* Now we need to promote. This needs to happen when we're not polling. Since
   * this may be called from poll, the wait needs to happen asynchronously. */
  GRPC_FD_REF(fd, "basicpoll_add");
  pollset->in_flight_cbs++;
  up_args = gpr_malloc(sizeof(*up_args));
  up_args->pollset = pollset;
  up_args->fd = fd;
  up_args->original_vtable = pollset->vtable;
  up_args->promotion_closure.cb = basic_do_promote;
  up_args->promotion_closure.cb_arg = up_args;
  grpc_iomgr_add_callback(&up_args->promotion_closure);

  grpc_pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST);

exit:
  if (and_unlock_pollset) {
    gpr_mu_unlock(&pollset->mu);
  }
}
Esempio n. 17
0
/* Called when an alarm expires. */
static void alarm_cb(void *arg /* alarm_arg */, int success) {
  alarm_arg *a = arg;
  gpr_mu_lock(&a->mu);
  if (success) {
    a->counter++;
    a->done_success_ctr++;
  } else {
    a->done_cancel_ctr++;
  }
  a->done = 1;
  a->success = success;
  gpr_cv_signal(&a->cv);
  gpr_mu_unlock(&a->mu);
  grpc_iomgr_add_callback(followup_cb, &a->fcb_arg);
}
Esempio n. 18
0
void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker *tracker) {
    grpc_connectivity_state_watcher *w;
    while ((w = tracker->watchers)) {
        tracker->watchers = w->next;

        if (GRPC_CHANNEL_FATAL_FAILURE != *w->current) {
            *w->current = GRPC_CHANNEL_FATAL_FAILURE;
            grpc_iomgr_add_callback(w->notify);
        } else {
            grpc_iomgr_add_delayed_callback(w->notify, 0);
        }
        gpr_free(w);
    }
    gpr_free(tracker->name);
}
Esempio n. 19
0
static void multipoll_with_epoll_pollset_add_fd(grpc_pollset *pollset,
                                                grpc_fd *fd,
                                                int and_unlock_pollset) {
  if (and_unlock_pollset) {
    gpr_mu_unlock(&pollset->mu);
    finally_add_fd(pollset, fd);
  } else {
    delayed_add *da = gpr_malloc(sizeof(*da));
    da->pollset = pollset;
    da->fd = fd;
    GRPC_FD_REF(fd, "delayed_add");
    grpc_iomgr_closure_init(&da->closure, perform_delayed_add, da);
    pollset->in_flight_cbs++;
    grpc_iomgr_add_callback(&da->closure);
  }
}
Esempio n. 20
0
static void fake_oauth2_get_request_metadata(grpc_credentials *creds,
                                             const char *service_url,
                                             grpc_credentials_metadata_cb cb,
                                             void *user_data) {
  grpc_fake_oauth2_credentials *c = (grpc_fake_oauth2_credentials *)creds;

  if (c->is_async) {
    grpc_credentials_metadata_request *cb_arg =
        grpc_credentials_metadata_request_create(creds, cb, user_data);
    grpc_iomgr_closure_init(cb_arg->on_simulated_token_fetch_done_closure,
                            on_simulated_token_fetch_done, cb_arg);
    grpc_iomgr_add_callback(cb_arg->on_simulated_token_fetch_done_closure);
  } else {
    cb(user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
  }
}
Esempio n. 21
0
File: server.c Progetto: penser/grpc
void grpc_server_destroy(grpc_server *server) {
  channel_data *c;
  listener *l;
  size_t i;
  call_data *calld;

  gpr_mu_lock(&server->mu);
  if (!server->shutdown) {
    gpr_mu_unlock(&server->mu);
    grpc_server_shutdown(server);
    gpr_mu_lock(&server->mu);
  }

  while (server->listeners_destroyed != num_listeners(server)) {
    for (i = 0; i < server->cq_count; i++) {
      gpr_mu_unlock(&server->mu);
      grpc_cq_hack_spin_pollset(server->cqs[i]);
      gpr_mu_lock(&server->mu);
    }

    gpr_cv_wait(&server->cv, &server->mu,
                gpr_time_add(gpr_now(), gpr_time_from_millis(100)));
  }

  while (server->listeners) {
    l = server->listeners;
    server->listeners = l->next;
    gpr_free(l);
  }

  while ((calld = call_list_remove_head(&server->lists[PENDING_START],
                                        PENDING_START)) != NULL) {
    gpr_log(GPR_DEBUG, "server destroys call %p", calld->call);
    calld->state = ZOMBIED;
    grpc_iomgr_add_callback(
        kill_zombie,
        grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0));
  }

  for (c = server->root_channel_data.next; c != &server->root_channel_data;
       c = c->next) {
    shutdown_channel(c);
  }
  gpr_mu_unlock(&server->mu);

  server_unref(server);
}
Esempio n. 22
0
void grpc_fd_orphan(grpc_fd *fd, grpc_iomgr_closure *on_done,
                    const char *reason) {
  fd->on_done_closure = on_done;
  shutdown(fd->fd, SHUT_RDWR);
  REF_BY(fd, 1, reason); /* remove active status, but keep referenced */
  gpr_mu_lock(&fd->watcher_mu);
  if (!has_watchers(fd)) {
    close(fd->fd);
    if (fd->on_done_closure) {
      grpc_iomgr_add_callback(fd->on_done_closure);
    }
  } else {
    wake_all_watchers_locked(fd);
  }
  gpr_mu_unlock(&fd->watcher_mu);
  UNREF_BY(fd, 2, reason); /* drop the reference */
}
Esempio n. 23
0
File: server.c Progetto: mindis/grpc
static void read_closed(grpc_call_element *elem) {
  call_data *calld = elem->call_data;
  channel_data *chand = elem->channel_data;
  gpr_mu_lock(&chand->server->mu);
  switch (calld->state) {
    case ACTIVATED:
    case PENDING:
      grpc_call_read_closed(elem);
      break;
    case NOT_STARTED:
      calld->state = ZOMBIED;
      grpc_iomgr_add_callback(kill_zombie, elem);
      break;
    case ZOMBIED:
      break;
  }
  gpr_mu_unlock(&chand->server->mu);
}
Esempio n. 24
0
int grpc_connectivity_state_notify_on_state_change(
    grpc_connectivity_state_tracker *tracker, grpc_connectivity_state *current,
    grpc_iomgr_closure *notify) {
    if (grpc_connectivity_state_trace) {
        gpr_log(GPR_DEBUG, "CONWATCH: %s: from %s [cur=%s]", tracker->name,
                grpc_connectivity_state_name(*current),
                grpc_connectivity_state_name(tracker->current_state));
    }
    if (tracker->current_state != *current) {
        *current = tracker->current_state;
        grpc_iomgr_add_callback(notify);
    } else {
        grpc_connectivity_state_watcher *w = gpr_malloc(sizeof(*w));
        w->current = current;
        w->notify = notify;
        w->next = tracker->watchers;
        tracker->watchers = w;
    }
    return tracker->current_state == GRPC_CHANNEL_IDLE;
}
Esempio n. 25
0
File: server.c Progetto: mindis/grpc
static void stream_closed(grpc_call_element *elem) {
  call_data *calld = elem->call_data;
  channel_data *chand = elem->channel_data;
  gpr_mu_lock(&chand->server->mu);
  switch (calld->state) {
    case ACTIVATED:
      break;
    case PENDING:
      call_list_remove(calld, PENDING_START);
    /* fallthrough intended */
    case NOT_STARTED:
      calld->state = ZOMBIED;
      grpc_iomgr_add_callback(kill_zombie, elem);
      break;
    case ZOMBIED:
      break;
  }
  gpr_mu_unlock(&chand->server->mu);
  grpc_call_stream_closed(elem);
}
Esempio n. 26
0
void grpc_fd_end_poll(grpc_fd_watcher *watcher, int got_read, int got_write) {
    int was_polling = 0;
    int kick = 0;
    grpc_fd *fd = watcher->fd;

    if (fd == NULL) {
        return;
    }

    gpr_mu_lock(&fd->watcher_mu);
    if (watcher == fd->read_watcher) {
        /* remove read watcher, kick if we still need a read */
        was_polling = 1;
        kick = kick || !got_read;
        fd->read_watcher = NULL;
    }
    if (watcher == fd->write_watcher) {
        /* remove write watcher, kick if we still need a write */
        was_polling = 1;
        kick = kick || !got_write;
        fd->write_watcher = NULL;
    }
    if (!was_polling) {
        /* remove from inactive list */
        watcher->next->prev = watcher->prev;
        watcher->prev->next = watcher->next;
    }
    if (kick) {
        maybe_wake_one_watcher_locked(fd);
    }
    if (grpc_fd_is_orphaned(fd) && !has_watchers(fd) && !fd->closed) {
        fd->closed = 1;
        close(fd->fd);
        if (fd->on_done_closure != NULL) {
            grpc_iomgr_add_callback(fd->on_done_closure);
        }
    }
    gpr_mu_unlock(&fd->watcher_mu);

    GRPC_FD_UNREF(fd, "poll");
}
Esempio n. 27
0
static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file,
                     int line) {
  gpr_atm old;
  gpr_log(GPR_DEBUG, "FD %d %p unref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
          gpr_atm_no_barrier_load(&fd->refst),
          gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line);
#else
static void unref_by(grpc_fd *fd, int n) {
  gpr_atm old;
#endif
  old = gpr_atm_full_fetch_add(&fd->refst, -n);
  if (old == n) {
    if (fd->on_done_closure) {
      grpc_iomgr_add_callback(fd->on_done_closure);
    }
    grpc_iomgr_unregister_object(&fd->iomgr_object);
    freelist_fd(fd);
  } else {
    GPR_ASSERT(old > n);
  }
}
Esempio n. 28
0
static void unix_maybe_finish_next_locked(unix_resolver *r) {
  grpc_client_config *cfg;
  grpc_lb_policy *lb_policy;
  grpc_subchannel *subchannel;
  grpc_subchannel_args args;

  if (r->next_completion != NULL && !r->published) {
    cfg = grpc_client_config_create();
    memset(&args, 0, sizeof(args));
    args.addr = (struct sockaddr *)&r->addr;
    args.addr_len = r->addr_len;
    subchannel =
        grpc_subchannel_factory_create_subchannel(r->subchannel_factory, &args);
    lb_policy = r->lb_policy_factory(&subchannel, 1);
    grpc_client_config_set_lb_policy(cfg, lb_policy);
    GRPC_LB_POLICY_UNREF(lb_policy, "unix");
    r->published = 1;
    *r->target_config = cfg;
    grpc_iomgr_add_callback(r->next_completion);
    r->next_completion = NULL;
  }
}
Esempio n. 29
0
void grpc_channel_internal_unref(grpc_channel *channel, const char *reason) {
  gpr_log(GPR_DEBUG, "CHANNEL: unref %p %d -> %d [%s]", channel,
          channel->refs.count, channel->refs.count - 1, reason);
#else
void grpc_channel_internal_unref(grpc_channel *channel) {
#endif
  if (gpr_unref(&channel->refs)) {
    channel->destroy_closure.cb = destroy_channel;
    channel->destroy_closure.cb_arg = channel;
    grpc_iomgr_add_callback(&channel->destroy_closure);
  }
}

void grpc_channel_destroy(grpc_channel *channel) {
  grpc_transport_op op;
  grpc_channel_element *elem;
  memset(&op, 0, sizeof(op));
  op.disconnect = 1;
  elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0);
  elem->filter->start_transport_op(elem, &op);

  GRPC_CHANNEL_INTERNAL_UNREF(channel, "channel");
}
Esempio n. 30
0
File: server.c Progetto: penser/grpc
static void shutdown_channel(channel_data *chand) {
  grpc_channel_internal_ref(chand->channel);
  grpc_iomgr_add_callback(finish_shutdown_channel, chand);
}