|
|
|
@ -91,7 +91,7 @@ void grpc_subchannel_key_destroy(grpc_subchannel_key* k) { |
|
|
|
|
gpr_free(k); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void sck_avl_destroy(void* p, void* user_data) { |
|
|
|
|
static void sck_avl_destroy(void* p, void* unused) { |
|
|
|
|
grpc_subchannel_key_destroy(static_cast<grpc_subchannel_key*>(p)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -104,7 +104,7 @@ static long sck_avl_compare(void* a, void* b, void* unused) { |
|
|
|
|
static_cast<grpc_subchannel_key*>(b)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void scv_avl_destroy(void* p, void* user_data) { |
|
|
|
|
static void scv_avl_destroy(void* p, void* unused) { |
|
|
|
|
GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "subchannel_index"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -137,7 +137,7 @@ void grpc_subchannel_index_shutdown(void) { |
|
|
|
|
void grpc_subchannel_index_unref(void) { |
|
|
|
|
if (gpr_unref(&g_refcount)) { |
|
|
|
|
gpr_mu_destroy(&g_mu); |
|
|
|
|
grpc_avl_unref(g_subchannel_index, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl_unref(g_subchannel_index, nullptr); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -147,13 +147,12 @@ grpc_subchannel* grpc_subchannel_index_find(grpc_subchannel_key* key) { |
|
|
|
|
// Lock, and take a reference to the subchannel index.
|
|
|
|
|
// We don't need to do the search under a lock as avl's are immutable.
|
|
|
|
|
gpr_mu_lock(&g_mu); |
|
|
|
|
grpc_avl index = grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr); |
|
|
|
|
gpr_mu_unlock(&g_mu); |
|
|
|
|
|
|
|
|
|
grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF( |
|
|
|
|
(grpc_subchannel*)grpc_avl_get(index, key, grpc_core::ExecCtx::Get()), |
|
|
|
|
"index_find"); |
|
|
|
|
grpc_avl_unref(index, grpc_core::ExecCtx::Get()); |
|
|
|
|
(grpc_subchannel*)grpc_avl_get(index, key, nullptr), "index_find"); |
|
|
|
|
grpc_avl_unref(index, nullptr); |
|
|
|
|
|
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
@ -169,13 +168,11 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, |
|
|
|
|
// Compare and swap loop:
|
|
|
|
|
// - take a reference to the current index
|
|
|
|
|
gpr_mu_lock(&g_mu); |
|
|
|
|
grpc_avl index = |
|
|
|
|
grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr); |
|
|
|
|
gpr_mu_unlock(&g_mu); |
|
|
|
|
|
|
|
|
|
// - Check to see if a subchannel already exists
|
|
|
|
|
c = static_cast<grpc_subchannel*>( |
|
|
|
|
grpc_avl_get(index, key, grpc_core::ExecCtx::Get())); |
|
|
|
|
c = static_cast<grpc_subchannel*>(grpc_avl_get(index, key, nullptr)); |
|
|
|
|
if (c != nullptr) { |
|
|
|
|
c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register"); |
|
|
|
|
} |
|
|
|
@ -184,11 +181,9 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, |
|
|
|
|
need_to_unref_constructed = true; |
|
|
|
|
} else { |
|
|
|
|
// no -> update the avl and compare/swap
|
|
|
|
|
grpc_avl updated = |
|
|
|
|
grpc_avl_add(grpc_avl_ref(index, grpc_core::ExecCtx::Get()), |
|
|
|
|
subchannel_key_copy(key), |
|
|
|
|
GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), |
|
|
|
|
grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl updated = grpc_avl_add( |
|
|
|
|
grpc_avl_ref(index, nullptr), subchannel_key_copy(key), |
|
|
|
|
GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), nullptr); |
|
|
|
|
|
|
|
|
|
// it may happen (but it's expected to be unlikely)
|
|
|
|
|
// that some other thread has changed the index:
|
|
|
|
@ -200,9 +195,9 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key, |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&g_mu); |
|
|
|
|
|
|
|
|
|
grpc_avl_unref(updated, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl_unref(updated, nullptr); |
|
|
|
|
} |
|
|
|
|
grpc_avl_unref(index, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl_unref(index, nullptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (need_to_unref_constructed) { |
|
|
|
@ -219,24 +214,22 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key, |
|
|
|
|
// Compare and swap loop:
|
|
|
|
|
// - take a reference to the current index
|
|
|
|
|
gpr_mu_lock(&g_mu); |
|
|
|
|
grpc_avl index = |
|
|
|
|
grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr); |
|
|
|
|
gpr_mu_unlock(&g_mu); |
|
|
|
|
|
|
|
|
|
// Check to see if this key still refers to the previously
|
|
|
|
|
// registered subchannel
|
|
|
|
|
grpc_subchannel* c = static_cast<grpc_subchannel*>( |
|
|
|
|
grpc_avl_get(index, key, grpc_core::ExecCtx::Get())); |
|
|
|
|
grpc_subchannel* c = |
|
|
|
|
static_cast<grpc_subchannel*>(grpc_avl_get(index, key, nullptr)); |
|
|
|
|
if (c != constructed) { |
|
|
|
|
grpc_avl_unref(index, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl_unref(index, nullptr); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// compare and swap the update (some other thread may have
|
|
|
|
|
// mutated the index behind us)
|
|
|
|
|
grpc_avl updated = |
|
|
|
|
grpc_avl_remove(grpc_avl_ref(index, grpc_core::ExecCtx::Get()), key, |
|
|
|
|
grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl_remove(grpc_avl_ref(index, nullptr), key, nullptr); |
|
|
|
|
|
|
|
|
|
gpr_mu_lock(&g_mu); |
|
|
|
|
if (index.root == g_subchannel_index.root) { |
|
|
|
@ -245,8 +238,8 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key, |
|
|
|
|
} |
|
|
|
|
gpr_mu_unlock(&g_mu); |
|
|
|
|
|
|
|
|
|
grpc_avl_unref(updated, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl_unref(index, grpc_core::ExecCtx::Get()); |
|
|
|
|
grpc_avl_unref(updated, nullptr); |
|
|
|
|
grpc_avl_unref(index, nullptr); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|