diff options
-rw-r--r-- | src/core/lib/channel/channelz_registry.cc | 30 | ||||
-rw-r--r-- | src/core/lib/channel/channelz_registry.h | 19 | ||||
-rw-r--r-- | test/core/channel/channelz_registry_test.cc | 9 |
3 files changed, 32 insertions, 26 deletions
diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index 31d66e847a..d7a595e08f 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -26,27 +26,14 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include <cstring> + namespace grpc_core { namespace { // singleton instance of the registry. ChannelzRegistry* g_channelz_registry = nullptr; -// avl vtable for uuid (intptr_t) -> channelz_obj (void*) -// this table is only looking, it does not own anything. -void destroy_intptr(void* not_used, void* user_data) {} -void* copy_intptr(void* key, void* user_data) { return key; } -long compare_intptr(void* key1, void* key2, void* user_data) { - return GPR_ICMP(key1, key2); -} - -void destroy_channelz_obj(void* channelz_obj, void* user_data) {} -void* copy_channelz_obj(void* channelz_obj, void* user_data) { - return channelz_obj; -} -const grpc_avl_vtable avl_vtable = {destroy_intptr, copy_intptr, compare_intptr, - destroy_channelz_obj, copy_channelz_obj}; - } // anonymous namespace void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); } @@ -58,19 +45,24 @@ ChannelzRegistry* ChannelzRegistry::Default() { return g_channelz_registry; } -ChannelzRegistry::ChannelzRegistry() : uuid_(1) { +ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); - avl_ = grpc_avl_create(&avl_vtable); + // init elements to nullptr + memset(entities_.data(), 0, sizeof(void*) * entities_.capacity()); } ChannelzRegistry::~ChannelzRegistry() { - grpc_avl_unref(avl_, nullptr); + // null out all elements so that the destructors don't try to run. + // this is a "view only" object. + memset(entities_.data(), 0, sizeof(void*) * entities_.capacity()); gpr_mu_destroy(&mu_); } void ChannelzRegistry::InternalUnregister(intptr_t uuid) { + GPR_ASSERT(uuid >= 1); gpr_mu_lock(&mu_); - avl_ = grpc_avl_remove(avl_, (void*)uuid, nullptr); + GPR_ASSERT((size_t)uuid <= entities_.size()); + entities_[uuid - 1] = nullptr; gpr_mu_unlock(&mu_); } diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index 4de7d478c5..6182e41b08 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -23,6 +23,7 @@ #include "src/core/lib/avl/avl.h" #include "src/core/lib/channel/channel_trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" #include <stdint.h> @@ -67,11 +68,11 @@ class ChannelzRegistry { // globally registers a channelz Object. Returns its unique uuid template <typename Object> intptr_t InternalRegister(Object* object) { - intptr_t prior = gpr_atm_no_barrier_fetch_add(&uuid_, 1); gpr_mu_lock(&mu_); - avl_ = grpc_avl_add(avl_, (void*)prior, object, nullptr); + entities_.push_back(static_cast<void*>(object)); + intptr_t uuid = entities_.size(); gpr_mu_unlock(&mu_); - return prior; + return uuid; } // globally unregisters the object that is associated to uuid. @@ -82,16 +83,20 @@ class ChannelzRegistry { template <typename Object> Object* InternalGet(intptr_t uuid) { gpr_mu_lock(&mu_); - Object* ret = - static_cast<Object*>(grpc_avl_get(avl_, (void*)uuid, nullptr)); + if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) { + gpr_mu_unlock(&mu_); + return nullptr; + } + Object* ret = static_cast<Object*>(entities_[uuid - 1]); gpr_mu_unlock(&mu_); return ret; } // private members + + // protects entities_ and uuid_ gpr_mu mu_; - grpc_avl avl_; - gpr_atm uuid_; + InlinedVector<void*, 20> entities_; }; } // namespace grpc_core diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc index eb6305eb4e..24e50933d7 100644 --- a/test/core/channel/channelz_registry_test.cc +++ b/test/core/channel/channelz_registry_test.cc @@ -82,6 +82,15 @@ TEST(ChannelzRegistryTest, MultipleTypeTest) { EXPECT_EQ(&str_to_register, retrieved_str); } +TEST(ChannelzRegistryTest, RegisterManyItems) { + int object_to_register = 42; + for (int i = 0; i < 100; i++) { + intptr_t uuid = ChannelzRegistry::Register(&object_to_register); + int* retrieved = ChannelzRegistry::Get<int>(uuid); + EXPECT_EQ(&object_to_register, retrieved); + } +} + namespace { class Foo { public: |