|
|
|
@ -47,6 +47,7 @@ |
|
|
|
|
#include "src/core/lib/gpr/useful.h" |
|
|
|
|
#include "src/core/lib/gprpp/inlined_vector.h" |
|
|
|
|
#include "src/core/lib/gprpp/manual_constructor.h" |
|
|
|
|
#include "src/core/lib/gprpp/ref_counted.h" |
|
|
|
|
#include "src/core/lib/gprpp/sync.h" |
|
|
|
|
#include "src/core/lib/iomgr/block_annotate.h" |
|
|
|
|
#include "src/core/lib/iomgr/iomgr_internal.h" |
|
|
|
@ -89,7 +90,7 @@ typedef struct pollable pollable; |
|
|
|
|
/// - PO_MULTI - a pollable containing many fds
|
|
|
|
|
struct pollable { |
|
|
|
|
pollable_type type; // immutable
|
|
|
|
|
gpr_refcount refs; |
|
|
|
|
grpc_core::RefCount refs; |
|
|
|
|
|
|
|
|
|
int epfd; |
|
|
|
|
grpc_wakeup_fd wakeup; |
|
|
|
@ -135,17 +136,26 @@ static char* pollable_desc(pollable* p) { |
|
|
|
|
static pollable* g_empty_pollable; |
|
|
|
|
|
|
|
|
|
static grpc_error* pollable_create(pollable_type type, pollable** p); |
|
|
|
|
#ifdef NDEBUG |
|
|
|
|
static pollable* pollable_ref(pollable* p); |
|
|
|
|
static void pollable_unref(pollable* p); |
|
|
|
|
#define POLLABLE_REF(p, r) pollable_ref(p) |
|
|
|
|
#define POLLABLE_UNREF(p, r) pollable_unref(p) |
|
|
|
|
#else |
|
|
|
|
static pollable* pollable_ref(pollable* p, int line, const char* reason); |
|
|
|
|
static void pollable_unref(pollable* p, int line, const char* reason); |
|
|
|
|
#define POLLABLE_REF(p, r) pollable_ref((p), __LINE__, (r)) |
|
|
|
|
#define POLLABLE_UNREF(p, r) pollable_unref((p), __LINE__, (r)) |
|
|
|
|
#endif |
|
|
|
|
static pollable* pollable_ref(pollable* p, |
|
|
|
|
const grpc_core::DebugLocation& dbg_loc, |
|
|
|
|
const char* reason) { |
|
|
|
|
p->refs.Ref(dbg_loc, reason); |
|
|
|
|
return p; |
|
|
|
|
} |
|
|
|
|
static void pollable_unref(pollable* p, const grpc_core::DebugLocation& dbg_loc, |
|
|
|
|
const char* reason) { |
|
|
|
|
if (p == nullptr) return; |
|
|
|
|
if (GPR_UNLIKELY(p != nullptr && p->refs.Unref(dbg_loc, reason))) { |
|
|
|
|
GRPC_FD_TRACE("pollable_unref: Closing epfd: %d", p->epfd); |
|
|
|
|
close(p->epfd); |
|
|
|
|
grpc_wakeup_fd_destroy(&p->wakeup); |
|
|
|
|
gpr_mu_destroy(&p->owner_orphan_mu); |
|
|
|
|
gpr_mu_destroy(&p->mu); |
|
|
|
|
gpr_free(p); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#define POLLABLE_REF(p, r) pollable_ref((p), DEBUG_LOCATION, (r)) |
|
|
|
|
#define POLLABLE_UNREF(p, r) pollable_unref((p), DEBUG_LOCATION, (r)) |
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|
* Fd Declarations |
|
|
|
@ -283,7 +293,7 @@ struct grpc_pollset { |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
struct grpc_pollset_set { |
|
|
|
|
gpr_refcount refs; |
|
|
|
|
grpc_core::RefCount refs; |
|
|
|
|
gpr_mu mu; |
|
|
|
|
grpc_pollset_set* parent; |
|
|
|
|
|
|
|
|
@ -568,7 +578,7 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
(*p)->type = type; |
|
|
|
|
gpr_ref_init(&(*p)->refs, 1); |
|
|
|
|
new (&(*p)->refs) grpc_core::RefCount(1, &grpc_trace_pollable_refcount); |
|
|
|
|
gpr_mu_init(&(*p)->mu); |
|
|
|
|
(*p)->epfd = epfd; |
|
|
|
|
(*p)->owner_fd = nullptr; |
|
|
|
@ -582,41 +592,6 @@ static grpc_error* pollable_create(pollable_type type, pollable** p) { |
|
|
|
|
return GRPC_ERROR_NONE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef NDEBUG |
|
|
|
|
static pollable* pollable_ref(pollable* p) { |
|
|
|
|
#else |
|
|
|
|
static pollable* pollable_ref(pollable* p, int line, const char* reason) { |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_pollable_refcount)) { |
|
|
|
|
int r = static_cast<int> gpr_atm_no_barrier_load(&p->refs.count); |
|
|
|
|
gpr_log(__FILE__, line, GPR_LOG_SEVERITY_DEBUG, |
|
|
|
|
"POLLABLE:%p ref %d->%d %s", p, r, r + 1, reason); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
gpr_ref(&p->refs); |
|
|
|
|
return p; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef NDEBUG |
|
|
|
|
static void pollable_unref(pollable* p) { |
|
|
|
|
#else |
|
|
|
|
static void pollable_unref(pollable* p, int line, const char* reason) { |
|
|
|
|
if (p == nullptr) return; |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_trace_pollable_refcount)) { |
|
|
|
|
int r = static_cast<int> gpr_atm_no_barrier_load(&p->refs.count); |
|
|
|
|
gpr_log(__FILE__, line, GPR_LOG_SEVERITY_DEBUG, |
|
|
|
|
"POLLABLE:%p unref %d->%d %s", p, r, r - 1, reason); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
if (p != nullptr && gpr_unref(&p->refs)) { |
|
|
|
|
GRPC_FD_TRACE("pollable_unref: Closing epfd: %d", p->epfd); |
|
|
|
|
close(p->epfd); |
|
|
|
|
grpc_wakeup_fd_destroy(&p->wakeup); |
|
|
|
|
gpr_mu_destroy(&p->owner_orphan_mu); |
|
|
|
|
gpr_mu_destroy(&p->mu); |
|
|
|
|
gpr_free(p); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static grpc_error* pollable_add_fd(pollable* p, grpc_fd* fd) { |
|
|
|
|
grpc_error* error = GRPC_ERROR_NONE; |
|
|
|
|
static const char* err_desc = "pollable_add_fd"; |
|
|
|
@ -1331,13 +1306,13 @@ static grpc_pollset_set* pollset_set_create(void) { |
|
|
|
|
grpc_pollset_set* pss = |
|
|
|
|
static_cast<grpc_pollset_set*>(gpr_zalloc(sizeof(*pss))); |
|
|
|
|
gpr_mu_init(&pss->mu); |
|
|
|
|
gpr_ref_init(&pss->refs, 1); |
|
|
|
|
new (&pss->refs) grpc_core::RefCount(); |
|
|
|
|
return pss; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void pollset_set_unref(grpc_pollset_set* pss) { |
|
|
|
|
if (pss == nullptr) return; |
|
|
|
|
if (!gpr_unref(&pss->refs)) return; |
|
|
|
|
if (GPR_LIKELY(!pss->refs.Unref())) return; |
|
|
|
|
pollset_set_unref(pss->parent); |
|
|
|
|
gpr_mu_destroy(&pss->mu); |
|
|
|
|
for (size_t i = 0; i < pss->pollset_count; i++) { |
|
|
|
@ -1528,7 +1503,7 @@ static void pollset_set_add_pollset_set(grpc_pollset_set* a, |
|
|
|
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { |
|
|
|
|
gpr_log(GPR_INFO, "PSS: parent %p to %p", b, a); |
|
|
|
|
} |
|
|
|
|
gpr_ref(&a->refs); |
|
|
|
|
a->refs.Ref(); |
|
|
|
|
b->parent = a; |
|
|
|
|
if (a->fd_capacity < a->fd_count + b->fd_count) { |
|
|
|
|
a->fd_capacity = GPR_MAX(2 * a->fd_capacity, a->fd_count + b->fd_count); |
|
|
|
|