Пример #1
0
static void win_maybe_shutdown_resource_user(grpc_exec_ctx *exec_ctx,
                                             grpc_tcp *tcp) {
  if (gpr_atm_full_fetch_add(&tcp->resource_user_shutdown_count, 1) == 0) {
    grpc_resource_user_shutdown(exec_ctx, &tcp->resource_user,
                                grpc_closure_create(win_unref_closure, tcp));
  }
}
Пример #2
0
static void do_iocp_work() {
  BOOL success;
  DWORD bytes = 0;
  DWORD flags = 0;
  ULONG_PTR completion_key;
  LPOVERLAPPED overlapped;
  gpr_timespec wait_time = gpr_inf_future;
  grpc_winsocket *socket;
  grpc_winsocket_callback_info *info;
  void(*f)(void *, int) = NULL;
  void *opaque = NULL;
  success = GetQueuedCompletionStatus(g_iocp, &bytes,
                                      &completion_key, &overlapped,
                                      gpr_time_to_millis(wait_time));
  if (!success && !overlapped) {
    /* The deadline got attained. */
    return;
  }
  GPR_ASSERT(completion_key && overlapped);
  if (overlapped == &g_iocp_custom_overlap) {
    if (completion_key == (ULONG_PTR) &g_iocp_kick_token) {
      /* We were awoken from a kick. */
      return;
    }
    gpr_log(GPR_ERROR, "Unknown custom completion key.");
    abort();
  }

  socket = (grpc_winsocket*) completion_key;
  if (overlapped == &socket->write_info.overlapped) {
    info = &socket->write_info;
  } else if (overlapped == &socket->read_info.overlapped) {
    info = &socket->read_info;
  } else {
    gpr_log(GPR_ERROR, "Unknown IOCP operation");
    abort();
  }
  success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes,
                                   FALSE, &flags);
  if (socket->orphan) {
    grpc_winsocket_destroy(socket);
    gpr_atm_full_fetch_add(&g_orphans, -1);
    return;
  }
  info->bytes_transfered = bytes;
  info->wsa_error = success ? 0 : WSAGetLastError();
  GPR_ASSERT(overlapped == &info->overlapped);
  gpr_mu_lock(&socket->state_mu);
  GPR_ASSERT(!info->has_pending_iocp);
  if (info->cb) {
    f = info->cb;
    opaque = info->opaque;
    info->cb = NULL;
  } else {
    info->has_pending_iocp = 1;
  }
  gpr_mu_unlock(&socket->state_mu);
  if (f) f(opaque, 1);
}
Пример #3
0
void grpc_resource_user_shutdown(grpc_exec_ctx *exec_ctx,
                                 grpc_resource_user *resource_user) {
  if (gpr_atm_full_fetch_add(&resource_user->shutdown, 1) == 0) {
    grpc_combiner_execute(exec_ctx, resource_user->resource_quota->combiner,
                          grpc_closure_create(ru_shutdown, resource_user),
                          GRPC_ERROR_NONE, false);
  }
}
Пример #4
0
static void start_destroy(grpc_exec_ctx *exec_ctx, grpc_combiner *lock) {
  gpr_atm old_state = gpr_atm_full_fetch_add(&lock->state, -STATE_UNORPHANED);
  GRPC_COMBINER_TRACE(gpr_log(
      GPR_DEBUG, "C:%p really_destroy old_state=%" PRIdPTR, lock, old_state));
  if (old_state == 1) {
    really_destroy(exec_ctx, lock);
  }
}
Пример #5
0
void grpc_iocp_kick(void) {
  BOOL success;

  gpr_atm_full_fetch_add(&g_custom_events, 1);
  success = PostQueuedCompletionStatus(g_iocp, 0, (ULONG_PTR)&g_iocp_kick_token,
                                       &g_iocp_custom_overlap);
  GPR_ASSERT(success);
}
Пример #6
0
static void ru_unref_by(grpc_exec_ctx *exec_ctx,
                        grpc_resource_user *resource_user, gpr_atm amount) {
  GPR_ASSERT(amount > 0);
  gpr_atm old = gpr_atm_full_fetch_add(&resource_user->refs, -amount);
  GPR_ASSERT(old >= amount);
  if (old == amount) {
    grpc_closure_sched(exec_ctx, &resource_user->destroy_closure,
                       GRPC_ERROR_NONE);
  }
}
Пример #7
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);
  }
}
Пример #8
0
static gpr_atm ref_mutate(grpc_lb_policy *c, gpr_atm delta,
                          int barrier REF_MUTATE_EXTRA_ARGS) {
    gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta)
                      : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta);
#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG
    gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
            "LB_POLICY: %p % 12s 0x%08x -> 0x%08x [%s]", c, purpose, old_val,
            old_val + delta, reason);
#endif
    return old_val;
}
Пример #9
0
static void ru_unref_by(grpc_exec_ctx *exec_ctx,
                        grpc_resource_user *resource_user, gpr_atm amount) {
  GPR_ASSERT(amount > 0);
  gpr_atm old = gpr_atm_full_fetch_add(&resource_user->refs, -amount);
  GPR_ASSERT(old >= amount);
  if (old == amount) {
    grpc_combiner_execute(exec_ctx, resource_user->resource_quota->combiner,
                          &resource_user->destroy_closure, GRPC_ERROR_NONE,
                          false);
  }
}
Пример #10
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));
  }
}
Пример #11
0
void grpc_workqueue_enqueue(grpc_exec_ctx *exec_ctx, grpc_workqueue *workqueue,
                            grpc_closure *closure, grpc_error *error) {
  GPR_TIMER_BEGIN("workqueue.enqueue", 0);
  gpr_atm last = gpr_atm_full_fetch_add(&workqueue->state, 2);
  GPR_ASSERT(last & 1);
  closure->error = error;
  gpr_mpscq_push(&workqueue->queue, &closure->next_data.atm_next);
  if (last == 1) {
    wakeup(exec_ctx, workqueue);
  }
  GPR_TIMER_END("workqueue.enqueue", 0);
}
Пример #12
0
static gpr_atm ref_mutate(grpc_lb_policy *c, gpr_atm delta,
                          int barrier REF_MUTATE_EXTRA_ARGS) {
  gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta)
                            : gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta);
#ifndef NDEBUG
  if (GRPC_TRACER_ON(grpc_trace_lb_policy_refcount)) {
    gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
            "LB_POLICY: 0x%p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c,
            purpose, old_val, old_val + delta, reason);
  }
#endif
  return old_val;
}
Пример #13
0
void grpc_iocp_work(grpc_exec_ctx *exec_ctx, gpr_timespec deadline) {
  BOOL success;
  DWORD bytes = 0;
  DWORD flags = 0;
  ULONG_PTR completion_key;
  LPOVERLAPPED overlapped;
  grpc_winsocket *socket;
  grpc_winsocket_callback_info *info;
  grpc_closure *closure = NULL;
  success = GetQueuedCompletionStatus(
      g_iocp, &bytes, &completion_key, &overlapped,
      deadline_to_millis_timeout(deadline, gpr_now(deadline.clock_type)));
  if (success == 0 && overlapped == NULL) {
    return;
  }
  GPR_ASSERT(completion_key && overlapped);
  if (overlapped == &g_iocp_custom_overlap) {
    gpr_atm_full_fetch_add(&g_custom_events, -1);
    if (completion_key == (ULONG_PTR)&g_iocp_kick_token) {
      /* We were awoken from a kick. */
      return;
    }
    gpr_log(GPR_ERROR, "Unknown custom completion key.");
    abort();
  }

  socket = (grpc_winsocket *)completion_key;
  if (overlapped == &socket->write_info.overlapped) {
    info = &socket->write_info;
  } else if (overlapped == &socket->read_info.overlapped) {
    info = &socket->read_info;
  } else {
    gpr_log(GPR_ERROR, "Unknown IOCP operation");
    abort();
  }
  success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes,
                                   FALSE, &flags);
  info->bytes_transfered = bytes;
  info->wsa_error = success ? 0 : WSAGetLastError();
  GPR_ASSERT(overlapped == &info->overlapped);
  GPR_ASSERT(!info->has_pending_iocp);
  gpr_mu_lock(&socket->state_mu);
  if (info->closure) {
    closure = info->closure;
    info->closure = NULL;
  } else {
    info->has_pending_iocp = 1;
  }
  gpr_mu_unlock(&socket->state_mu);
  grpc_exec_ctx_enqueue(exec_ctx, closure, true, NULL);
}
Пример #14
0
static void on_readable(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
  GPR_TIMER_BEGIN("workqueue.on_readable", 0);

  grpc_workqueue *workqueue = arg;

  if (error != GRPC_ERROR_NONE) {
    /* HACK: let wakeup_fd code know that we stole the fd */
    workqueue->wakeup_fd.read_fd = 0;
    grpc_wakeup_fd_destroy(&workqueue->wakeup_fd);
    grpc_fd_orphan(exec_ctx, workqueue->wakeup_read_fd, NULL, NULL, "destroy");
    GPR_ASSERT(gpr_atm_no_barrier_load(&workqueue->state) == 0);
    gpr_free(workqueue);
  } else {
    error = grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd);
    gpr_mpscq_node *n = gpr_mpscq_pop(&workqueue->queue);
    if (error == GRPC_ERROR_NONE) {
      grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd,
                             &workqueue->read_closure);
    } else {
      /* recurse to get error handling */
      on_readable(exec_ctx, arg, error);
    }
    if (n == NULL) {
      /* try again - queue in an inconsistant state */
      wakeup(exec_ctx, workqueue);
    } else {
      switch (gpr_atm_full_fetch_add(&workqueue->state, -2)) {
        case 3:  // had one count, one unorphaned --> done, unorphaned
          break;
        case 2:  // had one count, one orphaned --> done, orphaned
          workqueue_destroy(exec_ctx, workqueue);
          break;
        case 1:
        case 0:
          // these values are illegal - representing an already done or
          // deleted workqueue
          GPR_UNREACHABLE_CODE(break);
        default:
          // schedule a wakeup since there's more to do
          wakeup(exec_ctx, workqueue);
      }
      grpc_closure *cl = (grpc_closure *)n;
      grpc_error *clerr = cl->error;
      cl->cb(exec_ctx, cl->cb_arg, clerr);
      GRPC_ERROR_UNREF(clerr);
    }
  }

  GPR_TIMER_END("workqueue.on_readable", 0);
}
Пример #15
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) {
    freelist_fd(fd);
  } else {
    GPR_ASSERT(old > n);
  }
}
Пример #16
0
static void destroy_server(grpc_rb_server* server, gpr_timespec deadline) {
  grpc_event ev;
  // This can be started by app or implicitly by GC. Avoid a race between these.
  if (gpr_atm_full_fetch_add(&server->shutdown_started, (gpr_atm)1) == 0) {
    if (server->wrapped != NULL) {
      grpc_server_shutdown_and_notify(server->wrapped, server->queue, NULL);
      ev = rb_completion_queue_pluck(server->queue, NULL, deadline, NULL);
      if (ev.type == GRPC_QUEUE_TIMEOUT) {
        grpc_server_cancel_all_calls(server->wrapped);
        rb_completion_queue_pluck(server->queue, NULL,
                                  gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
      }
      grpc_server_destroy(server->wrapped);
      grpc_rb_completion_queue_destroy(server->queue);
      server->wrapped = NULL;
      server->queue = NULL;
    }
  }
}
Пример #17
0
grpc_iocp_work_status grpc_iocp_work(grpc_exec_ctx *exec_ctx,
                                     gpr_timespec deadline) {
  BOOL success;
  DWORD bytes = 0;
  DWORD flags = 0;
  ULONG_PTR completion_key;
  LPOVERLAPPED overlapped;
  grpc_winsocket *socket;
  grpc_winsocket_callback_info *info;
  success = GetQueuedCompletionStatus(
      g_iocp, &bytes, &completion_key, &overlapped,
      deadline_to_millis_timeout(deadline, gpr_now(deadline.clock_type)));
  if (success == 0 && overlapped == NULL) {
    return GRPC_IOCP_WORK_TIMEOUT;
  }
  GPR_ASSERT(completion_key && overlapped);
  if (overlapped == &g_iocp_custom_overlap) {
    gpr_atm_full_fetch_add(&g_custom_events, -1);
    if (completion_key == (ULONG_PTR)&g_iocp_kick_token) {
      /* We were awoken from a kick. */
      return GRPC_IOCP_WORK_KICK;
    }
    gpr_log(GPR_ERROR, "Unknown custom completion key.");
    abort();
  }

  socket = (grpc_winsocket *)completion_key;
  if (overlapped == &socket->write_info.overlapped) {
    info = &socket->write_info;
  } else if (overlapped == &socket->read_info.overlapped) {
    info = &socket->read_info;
  } else {
    abort();
  }
  success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes,
                                   FALSE, &flags);
  info->bytes_transfered = bytes;
  info->wsa_error = success ? 0 : WSAGetLastError();
  GPR_ASSERT(overlapped == &info->overlapped);
  grpc_socket_become_ready(exec_ctx, socket, info);
  return GRPC_IOCP_WORK_WORK;
}
Пример #18
0
static void unref_by(grpc_exec_ctx *exec_ctx, grpc_fd *fd, int n,
                     const char *reason, const char *file, int line) {
  if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
    gpr_log(GPR_DEBUG,
            "FD %d %p unref %d %" PRIdPTR " -> %" PRIdPTR " [%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_exec_ctx *exec_ctx, grpc_fd *fd, int n) {
#endif
  gpr_atm old = gpr_atm_full_fetch_add(&fd->refst, -n);
  if (old == n) {
    GRPC_CLOSURE_SCHED(exec_ctx, GRPC_CLOSURE_CREATE(fd_destroy, fd,
                                                     grpc_schedule_on_exec_ctx),
                       GRPC_ERROR_NONE);
  } else {
    GPR_ASSERT(old > n);
  }
}
Пример #19
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);
  }
}
Пример #20
0
void grpc_iocp_socket_orphan(grpc_winsocket *socket) {
  GPR_ASSERT(!socket->orphan);
  gpr_atm_full_fetch_add(&g_orphans, 1);
  socket->orphan = 1;
}
Пример #21
0
static void interned_slice_unref(grpc_exec_ctx *exec_ctx, void *p) {
  interned_slice_refcount *s = (interned_slice_refcount *)p;
  if (1 == gpr_atm_full_fetch_add(&s->refcnt, -1)) {
    interned_slice_destroy(s);
  }
}
Пример #22
0
int gpr_unref(gpr_refcount *r) {
  gpr_atm prior = gpr_atm_full_fetch_add(&r->count, -1);
  GPR_ASSERT(prior > 0);
  return prior == 1;
}
Пример #23
0
static void workqueue_orphan(grpc_exec_ctx *exec_ctx,
                             grpc_workqueue *workqueue) {
  if (gpr_atm_full_fetch_add(&workqueue->state, -1) == 1) {
    workqueue_destroy(exec_ctx, workqueue);
  }
}