diff options
Diffstat (limited to 'src/core/lib')
-rw-r--r-- | src/core/lib/channel/channelz.cc | 23 | ||||
-rw-r--r-- | src/core/lib/channel/channelz.h | 3 | ||||
-rw-r--r-- | src/core/lib/channel/channelz_registry.cc | 5 | ||||
-rw-r--r-- | src/core/lib/gpr/sync_posix.cc | 100 | ||||
-rw-r--r-- | src/core/lib/gprpp/memory.h | 13 | ||||
-rw-r--r-- | src/core/lib/iomgr/exec_ctx.cc | 13 | ||||
-rw-r--r-- | src/core/lib/iomgr/sockaddr_utils.cc | 1 | ||||
-rw-r--r-- | src/core/lib/iomgr/timer_manager.cc | 6 |
8 files changed, 136 insertions, 28 deletions
diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc index 0cb2890518..8a596ad460 100644 --- a/src/core/lib/channel/channelz.cc +++ b/src/core/lib/channel/channelz.cc @@ -203,31 +203,34 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes) ServerNode::~ServerNode() {} -char* ServerNode::RenderServerSockets(intptr_t start_socket_id) { +char* ServerNode::RenderServerSockets(intptr_t start_socket_id, + intptr_t max_results) { + // if user does not set max_results, we choose 500. + size_t pagination_limit = max_results == 0 ? 500 : max_results; grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT); grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; ChildSocketsList socket_refs; grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id); + // declared early so it can be used outside of the loop. + size_t i = 0; if (!socket_refs.empty()) { // create list of socket refs grpc_json* array_parent = grpc_json_create_child( nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false); - for (size_t i = 0; i < socket_refs.size(); ++i) { - grpc_json* socket_ref_json = - grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr, - GRPC_JSON_OBJECT, false); + for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) { + grpc_json* socket_ref_json = grpc_json_create_child( + nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false); json_iterator = grpc_json_add_number_string_child( socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid()); grpc_json_create_child(json_iterator, socket_ref_json, "name", socket_refs[i]->remote(), GRPC_JSON_STRING, false); } } - // For now we do not have any pagination rules. In the future we could - // pick a constant for max_channels_sent for a GetServers request. - // Tracking: https://github.com/grpc/grpc/issues/16019. - json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, - GRPC_JSON_TRUE, false); + if (i == socket_refs.size()) { + json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr, + GRPC_JSON_TRUE, false); + } char* json_str = grpc_json_dump_to_string(top_level_json, 0); grpc_json_destroy(top_level_json); return json_str; diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h index 96a4333083..e43792126f 100644 --- a/src/core/lib/channel/channelz.h +++ b/src/core/lib/channel/channelz.h @@ -210,7 +210,8 @@ class ServerNode : public BaseNode { grpc_json* RenderJson() override; - char* RenderServerSockets(intptr_t start_socket_id); + char* RenderServerSockets(intptr_t start_socket_id, + intptr_t pagination_limit); // proxy methods to composed classes. void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) { diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index bc23b90a66..7cca247d64 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -252,7 +252,8 @@ char* grpc_channelz_get_server(intptr_t server_id) { } char* grpc_channelz_get_server_sockets(intptr_t server_id, - intptr_t start_socket_id) { + intptr_t start_socket_id, + intptr_t max_results) { grpc_core::channelz::BaseNode* base_node = grpc_core::channelz::ChannelzRegistry::Get(server_id); if (base_node == nullptr || @@ -263,7 +264,7 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id, // actually a server node grpc_core::channelz::ServerNode* server_node = static_cast<grpc_core::channelz::ServerNode*>(base_node); - return server_node->RenderServerSockets(start_socket_id); + return server_node->RenderServerSockets(start_socket_id, max_results); } char* grpc_channelz_get_channel(intptr_t channel_id) { diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc index 69bd609485..c09a7598ac 100644 --- a/src/core/lib/gpr/sync_posix.cc +++ b/src/core/lib/gpr/sync_posix.cc @@ -30,11 +30,18 @@ // For debug of the timer manager crash only. // TODO (mxyan): remove after bug is fixed. #ifdef GRPC_DEBUG_TIMER_MANAGER +#include <string.h> void (*g_grpc_debug_timer_manager_stats)( int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count, int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value, int64_t timer_mu_value, int64_t abstime_sec_value, - int64_t abstime_nsec_value) = nullptr; + int64_t abstime_nsec_value, int64_t abs_deadline_sec_value, + int64_t abs_deadline_nsec_value, int64_t now1_sec_value, + int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value, + int64_t add_result_sec_value, int64_t add_result_nsec_value, + int64_t sub_result_sec_value, int64_t sub_result_nsec_value, + int64_t next_value, int64_t start_time_sec, + int64_t start_time_nsec) = nullptr; int64_t g_timer_manager_init_count = 0; int64_t g_timer_manager_shutdown_count = 0; int64_t g_fork_count = 0; @@ -43,6 +50,19 @@ int64_t g_timer_cv_value = 0; int64_t g_timer_mu_value = 0; int64_t g_abstime_sec_value = -1; int64_t g_abstime_nsec_value = -1; +int64_t g_abs_deadline_sec_value = -1; +int64_t g_abs_deadline_nsec_value = -1; +int64_t g_now1_sec_value = -1; +int64_t g_now1_nsec_value = -1; +int64_t g_now2_sec_value = -1; +int64_t g_now2_nsec_value = -1; +int64_t g_add_result_sec_value = -1; +int64_t g_add_result_nsec_value = -1; +int64_t g_sub_result_sec_value = -1; +int64_t g_sub_result_nsec_value = -1; +int64_t g_next_value = -1; +int64_t g_start_time_sec = -1; +int64_t g_start_time_nsec = -1; #endif // GRPC_DEBUG_TIMER_MANAGER #ifdef GPR_LOW_LEVEL_COUNTERS @@ -90,17 +110,74 @@ void gpr_cv_init(gpr_cv* cv) { void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); } +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +static gpr_timespec gpr_convert_clock_type_debug_timespec( + gpr_timespec t, gpr_clock_type clock_type, gpr_timespec& now1, + gpr_timespec& now2, gpr_timespec& add_result, gpr_timespec& sub_result) { + if (t.clock_type == clock_type) { + return t; + } + + if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) { + t.clock_type = clock_type; + return t; + } + + if (clock_type == GPR_TIMESPAN) { + return gpr_time_sub(t, gpr_now(t.clock_type)); + } + + if (t.clock_type == GPR_TIMESPAN) { + return gpr_time_add(gpr_now(clock_type), t); + } + + now1 = gpr_now(t.clock_type); + sub_result = gpr_time_sub(t, now1); + now2 = gpr_now(clock_type); + add_result = gpr_time_add(now2, sub_result); + return add_result; +} + +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ + sub_result) \ + gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), \ + (add_result), (sub_result)) +#else +#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \ + sub_result) \ + gpr_convert_clock_type((t), (clock_type)) +#endif + int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { int err = 0; +#ifdef GRPC_DEBUG_TIMER_MANAGER + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. + gpr_timespec abs_deadline_copy; + abs_deadline_copy.tv_sec = abs_deadline.tv_sec; + abs_deadline_copy.tv_nsec = abs_deadline.tv_nsec; + gpr_timespec now1; + gpr_timespec now2; + gpr_timespec add_result; + gpr_timespec sub_result; + memset(&now1, 0, sizeof(now1)); + memset(&now2, 0, sizeof(now2)); + memset(&add_result, 0, sizeof(add_result)); + memset(&sub_result, 0, sizeof(sub_result)); +#endif if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) == 0) { err = pthread_cond_wait(cv, mu); } else { struct timespec abs_deadline_ts; #if GPR_LINUX - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC); + abs_deadline = gpr_convert_clock_type_debug( + abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result); #else - abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME); + abs_deadline = gpr_convert_clock_type_debug( + abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result); #endif // GPR_LINUX abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec); abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec; @@ -123,10 +200,25 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) { g_timer_wait_err = err; g_timer_cv_value = (int64_t)cv; g_timer_mu_value = (int64_t)mu; + g_abs_deadline_sec_value = abs_deadline_copy.tv_sec; + g_abs_deadline_nsec_value = abs_deadline_copy.tv_nsec; + g_now1_sec_value = now1.tv_sec; + g_now1_nsec_value = now1.tv_nsec; + g_now2_sec_value = now2.tv_sec; + g_now2_nsec_value = now2.tv_nsec; + g_add_result_sec_value = add_result.tv_sec; + g_add_result_nsec_value = add_result.tv_nsec; + g_sub_result_sec_value = sub_result.tv_sec; + g_sub_result_nsec_value = sub_result.tv_nsec; g_grpc_debug_timer_manager_stats( g_timer_manager_init_count, g_timer_manager_shutdown_count, g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value, - g_abstime_sec_value, g_abstime_nsec_value); + g_abstime_sec_value, g_abstime_nsec_value, g_abs_deadline_sec_value, + g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value, + g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value, + g_add_result_nsec_value, g_sub_result_sec_value, + g_sub_result_nsec_value, g_next_value, g_start_time_sec, + g_start_time_nsec); } } #endif diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h index e90bedcd9b..b4b63ae771 100644 --- a/src/core/lib/gprpp/memory.h +++ b/src/core/lib/gprpp/memory.h @@ -40,15 +40,10 @@ namespace grpc_core { -// The alignment of memory returned by gpr_malloc(). -constexpr size_t kAlignmentForDefaultAllocationInBytes = 8; - // Alternative to new, since we cannot use it (for fear of libstdc++) template <typename T, typename... Args> inline T* New(Args&&... args) { - void* p = alignof(T) > kAlignmentForDefaultAllocationInBytes - ? gpr_malloc_aligned(sizeof(T), alignof(T)) - : gpr_malloc(sizeof(T)); + void* p = gpr_malloc(sizeof(T)); return new (p) T(std::forward<Args>(args)...); } @@ -57,11 +52,7 @@ template <typename T> inline void Delete(T* p) { if (p == nullptr) return; p->~T(); - if (alignof(T) > kAlignmentForDefaultAllocationInBytes) { - gpr_free_aligned(p); - } else { - gpr_free(p); - } + gpr_free(p); } template <typename T> diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc index d68fa0714b..683dd2f649 100644 --- a/src/core/lib/iomgr/exec_ctx.cc +++ b/src/core/lib/iomgr/exec_ctx.cc @@ -53,6 +53,13 @@ static void exec_ctx_sched(grpc_closure* closure, grpc_error* error) { static gpr_timespec g_start_time; +// For debug of the timer manager crash only. +// TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER +extern int64_t g_start_time_sec; +extern int64_t g_start_time_nsec; +#endif // GRPC_DEBUG_TIMER_MANAGER + static grpc_millis timespec_to_millis_round_down(gpr_timespec ts) { ts = gpr_time_sub(ts, g_start_time); double x = GPR_MS_PER_SEC * static_cast<double>(ts.tv_sec) + @@ -117,6 +124,12 @@ void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) { void ExecCtx::GlobalInit(void) { g_start_time = gpr_now(GPR_CLOCK_MONOTONIC); + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER + g_start_time_sec = g_start_time.tv_sec; + g_start_time_nsec = g_start_time.tv_nsec; +#endif gpr_tls_init(&exec_ctx_); } diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 1b66dceb13..0839bdfef2 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -217,6 +217,7 @@ void grpc_string_to_sockaddr(grpc_resolved_address* out, char* addr, int port) { } char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) { + if (resolved_addr->len == 0) return nullptr; grpc_resolved_address addr_normalized; if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) { resolved_addr = &addr_normalized; diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc index ceba79f678..cb123298cf 100644 --- a/src/core/lib/iomgr/timer_manager.cc +++ b/src/core/lib/iomgr/timer_manager.cc @@ -67,6 +67,7 @@ static void timer_thread(void* completed_thread_ptr); extern int64_t g_timer_manager_init_count; extern int64_t g_timer_manager_shutdown_count; extern int64_t g_fork_count; +extern int64_t g_next_value; #endif // GRPC_DEBUG_TIMER_MANAGER static void gc_completed_threads(void) { @@ -193,6 +194,11 @@ static bool wait_until(grpc_millis next) { gpr_log(GPR_INFO, "sleep until kicked"); } + // For debug of the timer manager crash only. + // TODO (mxyan): remove after bug is fixed. +#ifdef GRPC_DEBUG_TIMER_MANAGER + g_next_value = next; +#endif gpr_cv_wait(&g_cv_wait, &g_mu, grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC)); |