pull/16455/head
Yash Tibrewal 6 years ago
parent fc332d2c92
commit bab043e865
  1. 72
      CMakeLists.txt
  2. 84
      Makefile
  3. 18
      build.yaml
  4. 7
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  5. 17
      src/core/ext/transport/chttp2/transport/context_list.cc
  6. 30
      src/core/ext/transport/chttp2/transport/context_list.h
  7. 4
      src/core/ext/transport/chttp2/transport/internal.h
  8. 3
      src/core/ext/transport/chttp2/transport/writing.cc
  9. 13
      src/core/lib/iomgr/buffer_list.cc
  10. 7
      src/core/lib/iomgr/buffer_list.h
  11. 2
      src/core/lib/iomgr/iomgr.cc
  12. 17
      src/core/lib/iomgr/tcp_posix.cc
  13. 39
      test/core/transport/chttp2/context_list_test.cc
  14. 26
      test/core/util/mock_endpoint.cc
  15. 4
      test/core/util/passthru_endpoint.cc
  16. 4
      test/core/util/trickle_endpoint.cc
  17. 4
      test/cpp/microbenchmarks/bm_chttp2_transport.cc
  18. 30
      tools/run_tests/generated/sources_and_headers.json
  19. 48
      tools/run_tests/generated/tests.json

@ -262,7 +262,6 @@ add_dependencies(buildtests_c combiner_test)
add_dependencies(buildtests_c compression_test)
add_dependencies(buildtests_c concurrent_connectivity_test)
add_dependencies(buildtests_c connection_refused_test)
add_dependencies(buildtests_c context_list_test)
add_dependencies(buildtests_c dns_resolver_connectivity_test)
add_dependencies(buildtests_c dns_resolver_cooldown_test)
add_dependencies(buildtests_c dns_resolver_test)
@ -589,6 +588,7 @@ add_dependencies(buildtests_cxx client_interceptors_end2end_test)
add_dependencies(buildtests_cxx client_lb_end2end_test)
add_dependencies(buildtests_cxx codegen_test_full)
add_dependencies(buildtests_cxx codegen_test_minimal)
add_dependencies(buildtests_cxx context_list_test)
add_dependencies(buildtests_cxx credentials_test)
add_dependencies(buildtests_cxx cxx_byte_buffer_test)
add_dependencies(buildtests_cxx cxx_slice_test)
@ -6459,39 +6459,6 @@ target_link_libraries(connection_refused_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(context_list_test
test/core/transport/chttp2/context_list_test.cc
)
target_include_directories(context_list_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
target_link_libraries(context_list_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
)
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
set_target_properties(context_list_test PROPERTIES LINKER_LANGUAGE C)
target_compile_options(context_list_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(dns_resolver_connectivity_test
test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
)
@ -12738,6 +12705,43 @@ target_link_libraries(codegen_test_minimal
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(context_list_test
test/core/transport/chttp2/context_list_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(context_list_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
PRIVATE third_party/googletest/googletest/include
PRIVATE third_party/googletest/googletest
PRIVATE third_party/googletest/googlemock/include
PRIVATE third_party/googletest/googlemock
PRIVATE ${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(context_list_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
${_gRPC_GFLAGS_LIBRARIES}
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)

@ -991,7 +991,6 @@ combiner_test: $(BINDIR)/$(CONFIG)/combiner_test
compression_test: $(BINDIR)/$(CONFIG)/compression_test
concurrent_connectivity_test: $(BINDIR)/$(CONFIG)/concurrent_connectivity_test
connection_refused_test: $(BINDIR)/$(CONFIG)/connection_refused_test
context_list_test: $(BINDIR)/$(CONFIG)/context_list_test
dns_resolver_connectivity_test: $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test
dns_resolver_cooldown_test: $(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test
dns_resolver_test: $(BINDIR)/$(CONFIG)/dns_resolver_test
@ -1169,6 +1168,7 @@ client_interceptors_end2end_test: $(BINDIR)/$(CONFIG)/client_interceptors_end2en
client_lb_end2end_test: $(BINDIR)/$(CONFIG)/client_lb_end2end_test
codegen_test_full: $(BINDIR)/$(CONFIG)/codegen_test_full
codegen_test_minimal: $(BINDIR)/$(CONFIG)/codegen_test_minimal
context_list_test: $(BINDIR)/$(CONFIG)/context_list_test
credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
cxx_byte_buffer_test: $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test
cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test
@ -1448,7 +1448,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/compression_test \
$(BINDIR)/$(CONFIG)/concurrent_connectivity_test \
$(BINDIR)/$(CONFIG)/connection_refused_test \
$(BINDIR)/$(CONFIG)/context_list_test \
$(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test \
$(BINDIR)/$(CONFIG)/dns_resolver_cooldown_test \
$(BINDIR)/$(CONFIG)/dns_resolver_test \
@ -1675,6 +1674,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/client_lb_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_test_full \
$(BINDIR)/$(CONFIG)/codegen_test_minimal \
$(BINDIR)/$(CONFIG)/context_list_test \
$(BINDIR)/$(CONFIG)/credentials_test \
$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \
$(BINDIR)/$(CONFIG)/cxx_slice_test \
@ -1858,6 +1858,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/client_lb_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_test_full \
$(BINDIR)/$(CONFIG)/codegen_test_minimal \
$(BINDIR)/$(CONFIG)/context_list_test \
$(BINDIR)/$(CONFIG)/credentials_test \
$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \
$(BINDIR)/$(CONFIG)/cxx_slice_test \
@ -1980,8 +1981,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/concurrent_connectivity_test || ( echo test concurrent_connectivity_test failed ; exit 1 )
$(E) "[RUN] Testing connection_refused_test"
$(Q) $(BINDIR)/$(CONFIG)/connection_refused_test || ( echo test connection_refused_test failed ; exit 1 )
$(E) "[RUN] Testing context_list_test"
$(Q) $(BINDIR)/$(CONFIG)/context_list_test || ( echo test context_list_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_connectivity_test"
$(Q) $(BINDIR)/$(CONFIG)/dns_resolver_connectivity_test || ( echo test dns_resolver_connectivity_test failed ; exit 1 )
$(E) "[RUN] Testing dns_resolver_cooldown_test"
@ -2324,6 +2323,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/codegen_test_full || ( echo test codegen_test_full failed ; exit 1 )
$(E) "[RUN] Testing codegen_test_minimal"
$(Q) $(BINDIR)/$(CONFIG)/codegen_test_minimal || ( echo test codegen_test_minimal failed ; exit 1 )
$(E) "[RUN] Testing context_list_test"
$(Q) $(BINDIR)/$(CONFIG)/context_list_test || ( echo test context_list_test failed ; exit 1 )
$(E) "[RUN] Testing credentials_test"
$(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 )
$(E) "[RUN] Testing cxx_byte_buffer_test"
@ -11216,38 +11217,6 @@ endif
endif
CONTEXT_LIST_TEST_SRC = \
test/core/transport/chttp2/context_list_test.cc \
CONTEXT_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONTEXT_LIST_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/context_list_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/context_list_test: $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/context_list_test
endif
$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a
deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(CONTEXT_LIST_TEST_OBJS:.o=.dep)
endif
endif
DNS_RESOLVER_CONNECTIVITY_TEST_SRC = \
test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc \
@ -17590,6 +17559,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto
$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
CONTEXT_LIST_TEST_SRC = \
test/core/transport/chttp2/context_list_test.cc \
CONTEXT_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONTEXT_LIST_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/context_list_test: openssl_dep_error
else
ifeq ($(NO_PROTOBUF),true)
# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
$(BINDIR)/$(CONFIG)/context_list_test: protobuf_dep_error
else
$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test
endif
endif
$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a
deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(CONTEXT_LIST_TEST_OBJS:.o=.dep)
endif
endif
CREDENTIALS_TEST_SRC = \
test/cpp/client/credentials_test.cc \

@ -2300,15 +2300,6 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: context_list_test
build: test
language: c
src:
- test/core/transport/chttp2/context_list_test.cc
deps:
- grpc_test_util
- grpc
uses_polling: false
- name: dns_resolver_connectivity_test
cpu_cost: 0.1
build: test
@ -4613,6 +4604,15 @@ targets:
- grpc++_codegen_base
- grpc++_codegen_base_src
uses_polling: false
- name: context_list_test
build: test
language: c++
src:
- test/core/transport/chttp2/context_list_test.cc
deps:
- grpc_test_util
- grpc
uses_polling: false
- name: credentials_test
gtest: true
build: test

@ -157,7 +157,6 @@ bool g_flow_control_enabled = true;
*/
grpc_chttp2_transport::~grpc_chttp2_transport() {
gpr_log(GPR_INFO, "destruct transport %p", t);
size_t i;
if (channelz_socket != nullptr) {
@ -172,11 +171,12 @@ grpc_chttp2_transport::~grpc_chttp2_transport() {
grpc_chttp2_hpack_compressor_destroy(&hpack_compressor);
grpc_core::ContextList::Execute(cl, nullptr, GRPC_ERROR_NONE);
cl = nullptr;
grpc_slice_buffer_destroy_internal(&read_buffer);
grpc_chttp2_hpack_parser_destroy(&hpack_parser);
grpc_chttp2_goaway_parser_destroy(&goaway_parser);
for (i = 0; i < STREAM_LIST_COUNT; i++) {
GPR_ASSERT(lists[i].head == nullptr);
GPR_ASSERT(lists[i].tail == nullptr);
@ -1072,9 +1072,6 @@ static void write_action(void* gt, grpc_error* error) {
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(gt);
void* cl = t->cl;
t->cl = nullptr;
if (cl) {
gpr_log(GPR_INFO, "cleared for write");
}
grpc_endpoint_write(
t->ep, &t->outbuf,
GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t,

@ -21,33 +21,30 @@
#include "src/core/ext/transport/chttp2/transport/context_list.h"
namespace {
void (*cb)(void*, const char*) = nullptr;
void (*cb)(void*, grpc_core::Timestamps*) = nullptr;
}
namespace grpc_core {
void ContextList::Execute(void* arg, grpc_core::Timestamps* ts,
grpc_error* error) {
gpr_log(GPR_INFO, "execute");
ContextList* head = static_cast<ContextList*>(arg);
ContextList* ptr;
while (head != nullptr) {
if (error == GRPC_ERROR_NONE && ts != nullptr) {
if (cb) {
cb(head->s->context, ts);
cb(head->s_->context, ts);
}
}
gpr_log(GPR_INFO, "one iteration %p %p", head, arg);
GRPC_CHTTP2_STREAM_UNREF(static_cast<grpc_chttp2_stream *>(head->s),
"timestamp exec");
//grpc_stream_unref(head->s->refcount);
GRPC_CHTTP2_STREAM_UNREF(static_cast<grpc_chttp2_stream*>(head->s_),
"timestamp");
ptr = head;
head = head->next;
gpr_free(ptr);
head = head->next_;
grpc_core::Delete(ptr);
}
}
void grpc_http2_set_write_timestamps_callback(
void (*fn)(void*, const char*)) {
void (*fn)(void*, grpc_core::Timestamps*)) {
cb = fn;
}
} /* namespace grpc_core */

@ -35,29 +35,25 @@ class ContextList {
/* Make sure context is not already present */
ContextList* ptr = *head;
GRPC_CHTTP2_STREAM_REF(s, "timestamp");
//grpc_stream_ref(s->refcount);
while (ptr != nullptr) {
if (ptr->s == s) {
GPR_ASSERT(false);
if (ptr->s_ == s) {
GPR_ASSERT(
false &&
"Trying to append a stream that is already present in the list");
}
ptr = ptr->next;
ptr = ptr->next_;
}
ContextList* elem =
static_cast<ContextList*>(gpr_malloc(sizeof(ContextList)));
elem->s = s;
elem->next = nullptr;
ContextList* elem = grpc_core::New<ContextList>();
elem->s_ = s;
if (*head == nullptr) {
*head = elem;
gpr_log(GPR_INFO, "new head");
gpr_log(GPR_INFO, "append %p %p", elem, *head);
return;
}
gpr_log(GPR_INFO, "append %p %p", elem, *head);
ptr = *head;
while (ptr->next != nullptr) {
ptr = ptr->next;
while (ptr->next_ != nullptr) {
ptr = ptr->next_;
}
ptr->next = elem;
ptr->next_ = elem;
}
/* Executes a function \a fn with each context in the list and \a ts. It also
@ -65,12 +61,12 @@ class ContextList {
static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error);
private:
grpc_chttp2_stream* s;
ContextList* next;
grpc_chttp2_stream* s_ = nullptr;
ContextList* next_ = nullptr;
};
void grpc_http2_set_write_timestamps_callback(
void (*fn)(void*, const char*));
void (*fn)(void*, grpc_core::Timestamps*));
} /* namespace grpc_core */
#endif /* GRPC_CORE_EXT_TRANSPORT_CONTEXT_LIST_H */

@ -485,7 +485,7 @@ struct grpc_chttp2_transport {
bool keepalive_permit_without_calls = false;
/** keep-alive state machine state */
grpc_chttp2_keepalive_state keepalive_state;
grpc_core::ContextList* cl;
grpc_core::ContextList* cl = nullptr;
grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> channelz_socket;
uint32_t num_messages_in_next_write = 0;
};
@ -640,6 +640,8 @@ struct grpc_chttp2_stream {
bool unprocessed_incoming_frames_decompressed = false;
/** gRPC header bytes that are already decompressed */
size_t decompressed_header_bytes = 0;
/** Whether the bytes needs to be traced using Fathom */
bool traced = false;
};
/** Transport writing call flow:

@ -488,8 +488,7 @@ class StreamWriteContext {
return; // early out: nothing to do
}
if (/* traced && */ grpc_endpoint_can_track_err(t_->ep)) {
gpr_log(GPR_INFO, "for transport %p", t_);
if (s_->traced && grpc_endpoint_can_track_err(t_->ep)) {
grpc_core::ContextList::Append(&t_->cl, s_);
}
while ((s_->flow_controlled_buffer.length > 0 ||

@ -31,7 +31,6 @@
namespace grpc_core {
void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no,
void* arg) {
gpr_log(GPR_INFO, "new entry %u", seq_no);
GPR_DEBUG_ASSERT(head != nullptr);
TracedBuffer* new_elem = New<TracedBuffer>(seq_no, arg);
/* Store the current time as the sendmsg time. */
@ -56,16 +55,21 @@ void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) {
gts->clock_type = GPR_CLOCK_REALTIME;
}
void default_timestamps_callback(void* arg, grpc_core::Timestamps* ts,
grpc_error* shudown_err) {
gpr_log(GPR_DEBUG, "Timestamps callback has not been registered");
}
/** The saved callback function that will be invoked when we get all the
* timestamps that we are going to get for a TracedBuffer. */
void (*timestamps_callback)(void*, grpc_core::Timestamps*,
grpc_error* shutdown_err);
grpc_error* shutdown_err) =
default_timestamps_callback;
} /* namespace */
void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
struct sock_extended_err* serr,
struct scm_timestamping* tss) {
gpr_log(GPR_INFO, "process timestamp %u", serr->ee_data);
GPR_DEBUG_ASSERT(head != nullptr);
TracedBuffer* elem = *head;
TracedBuffer* next = nullptr;
@ -87,7 +91,6 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
/* Got all timestamps. Do the callback and free this TracedBuffer.
* The thing below can be passed by value if we don't want the
* restriction on the lifetime. */
gpr_log(GPR_INFO, "calling");
timestamps_callback(elem->arg_, &(elem->ts_), GRPC_ERROR_NONE);
next = elem->next_;
Delete<TracedBuffer>(elem);
@ -106,10 +109,8 @@ void TracedBuffer::Shutdown(TracedBuffer** head, void* remaining,
grpc_error* shutdown_err) {
GPR_DEBUG_ASSERT(head != nullptr);
TracedBuffer* elem = *head;
gpr_log(GPR_INFO, "shutdown");
while (elem != nullptr) {
timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err);
gpr_log(GPR_INFO, "iter");
auto* next = elem->next_;
Delete<TracedBuffer>(elem);
elem = next;

@ -82,7 +82,12 @@ class TracedBuffer {
grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */
};
#else /* GRPC_LINUX_ERRQUEUE */
class TracedBuffer {};
class TracedBuffer {
public:
/* Dummy shutdown function */
static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
grpc_error* shutdown_err) {}
};
#endif /* GRPC_LINUX_ERRQUEUE */
/** Sets the callback function to call when timestamps for a write are

@ -33,7 +33,6 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/ext/transport/chttp2/transport/context_list.h"
#include "src/core/lib/iomgr/buffer_list.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
@ -59,7 +58,6 @@ void grpc_iomgr_init() {
g_root_object.name = (char*)"root";
grpc_network_status_init();
grpc_iomgr_platform_init();
grpc_tcp_set_write_timestamps_callback(grpc_core::ContextList::Execute);
}
void grpc_iomgr_start() { grpc_timer_manager_init(); }

@ -382,7 +382,6 @@ static void tcp_ref(grpc_tcp* tcp) { gpr_ref(&tcp->refcount); }
static void tcp_destroy(grpc_endpoint* ep) {
grpc_network_status_unregister_endpoint(ep);
grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
gpr_log(GPR_INFO, "tcp destroy %p %p", ep, tcp->outgoing_buffer_arg);
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
if (grpc_event_engine_can_track_errors()) {
gpr_mu_lock(&tcp->tb_mu);
@ -594,7 +593,6 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg,
ssize_t* sent_length,
grpc_error** error) {
if (!tcp->socket_ts_enabled) {
gpr_log(GPR_INFO, "set timestamps");
uint32_t opt = grpc_core::kTimestampingSocketOptions;
if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING,
static_cast<void*>(&opt), sizeof(opt)) != 0) {
@ -627,7 +625,6 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg,
*sent_length = length;
/* Only save timestamps if all the bytes were taken by sendmsg. */
if (sending_length == static_cast<size_t>(length)) {
gpr_log(GPR_INFO, "tcp new entry %p %p", tcp, tcp->outgoing_buffer_arg);
gpr_mu_lock(&tcp->tb_mu);
grpc_core::TracedBuffer::AddNewEntry(
&tcp->tb_head, static_cast<int>(tcp->bytes_counter + length),
@ -687,7 +684,6 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg,
* non-linux platforms, error processing is not used/enabled currently.
*/
static bool process_errors(grpc_tcp* tcp) {
gpr_log(GPR_INFO, "process errors");
while (true) {
struct iovec iov;
iov.iov_base = nullptr;
@ -750,8 +746,6 @@ static bool process_errors(grpc_tcp* tcp) {
}
static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
gpr_log(GPR_INFO, "handle error %p", arg);
GRPC_LOG_IF_ERROR("handle error", GRPC_ERROR_REF(error));
grpc_tcp* tcp = static_cast<grpc_tcp*>(arg);
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO, "TCP:%p got_error: %s", tcp, grpc_error_string(error));
@ -761,8 +755,6 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
static_cast<bool>(gpr_atm_acq_load(&tcp->stop_error_notification))) {
/* We aren't going to register to hear on error anymore, so it is safe to
* unref. */
gpr_log(GPR_INFO, "%p %d early return", error,
static_cast<bool>(gpr_atm_acq_load(&tcp->stop_error_notification)));
TCP_UNREF(tcp, "error-tracking");
return;
}
@ -797,6 +789,8 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
}
#endif /* GRPC_LINUX_ERRQUEUE */
/* If outgoing_buffer_arg is filled, shuts down the list early, so that any
* release operations needed can be performed on the arg */
void tcp_shutdown_buffer_list(grpc_tcp* tcp) {
if (tcp->outgoing_buffer_arg) {
gpr_mu_lock(&tcp->tb_mu);
@ -856,7 +850,6 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
if (tcp->outgoing_buffer_arg != nullptr) {
if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length,
error)) {
gpr_log(GPR_INFO, "something went wrong");
tcp_shutdown_buffer_list(tcp);
return true; /* something went wrong with timestamps */
}
@ -881,13 +874,11 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
}
return false;
} else if (errno == EPIPE) {
gpr_log(GPR_INFO, "something went wrong");
*error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp);
grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
tcp_shutdown_buffer_list(tcp);
return true;
} else {
gpr_log(GPR_INFO, "something went wrong");
*error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp);
grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
tcp_shutdown_buffer_list(tcp);
@ -951,7 +942,6 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, grpc_error* error) {
static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf,
grpc_closure* cb, void* arg) {
GPR_TIMER_SCOPE("tcp_write", 0);
gpr_log(GPR_INFO, "tcp_write %p %p", ep, arg);
grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
grpc_error* error = GRPC_ERROR_NONE;
@ -992,7 +982,6 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf,
}
notify_on_write(tcp);
} else {
gpr_log(GPR_INFO, "imm sched");
if (grpc_tcp_trace.enabled()) {
const char* str = grpc_error_string(error);
gpr_log(GPR_INFO, "write: %s", str);
@ -1041,7 +1030,6 @@ static bool tcp_can_track_err(grpc_endpoint* ep) {
struct sockaddr addr;
socklen_t len = sizeof(addr);
if (getsockname(tcp->fd, &addr, &len) < 0) {
gpr_log(GPR_ERROR, "getsockname");
return false;
}
if (addr.sa_family == AF_INET || addr.sa_family == AF_INET6) {
@ -1160,7 +1148,6 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd,
grpc_closure* done) {
grpc_network_status_unregister_endpoint(ep);
grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
gpr_log(GPR_INFO, "destroy and release %p %p", ep, tcp->outgoing_buffer_arg);
GPR_ASSERT(ep->vtable == &vtable);
tcp->release_fd = fd;
tcp->release_fd_cb = done;

@ -18,12 +18,17 @@
#include "src/core/lib/iomgr/port.h"
#include <new>
#include <vector>
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/ext/transport/chttp2/transport/context_list.h"
#include "src/core/lib/transport/transport.h"
#include "test/core/util/mock_endpoint.h"
#include "test/core/util/test_config.h"
#include <grpc/grpc.h>
#include "test/core/util/test_config.h"
static void TestExecuteFlushesListVerifier(void* arg,
grpc_core::Timestamps* ts) {
GPR_ASSERT(arg != nullptr);
@ -31,6 +36,8 @@ static void TestExecuteFlushesListVerifier(void* arg,
gpr_atm_rel_store(done, static_cast<gpr_atm>(1));
}
static void discard_write(grpc_slice slice) {}
/** Tests that all ContextList elements in the list are flushed out on
* execute.
* Also tests that arg is passed correctly.
@ -39,19 +46,41 @@ static void TestExecuteFlushesList() {
grpc_core::ContextList* list = nullptr;
grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier);
#define NUM_ELEM 5
grpc_chttp2_stream s[NUM_ELEM];
grpc_core::ExecCtx exec_ctx;
grpc_stream_refcount ref;
grpc_resource_quota* resource_quota =
grpc_resource_quota_create("context_list_test");
grpc_endpoint* mock_endpoint =
grpc_mock_endpoint_create(discard_write, resource_quota);
grpc_transport* t =
grpc_create_chttp2_transport(nullptr, mock_endpoint, true);
std::vector<grpc_chttp2_stream*> s;
s.reserve(NUM_ELEM);
gpr_atm verifier_called[NUM_ELEM];
for (auto i = 0; i < NUM_ELEM; i++) {
s[i].context = &verifier_called[i];
s.push_back(static_cast<grpc_chttp2_stream*>(
gpr_malloc(grpc_transport_stream_size(t))));
grpc_transport_init_stream(reinterpret_cast<grpc_transport*>(t),
reinterpret_cast<grpc_stream*>(s[i]), &ref,
nullptr, nullptr);
s[i]->context = &verifier_called[i];
gpr_atm_rel_store(&verifier_called[i], static_cast<gpr_atm>(0));
grpc_core::ContextList::Append(&list, &s[i]);
grpc_core::ContextList::Append(&list, s[i]);
}
grpc_core::Timestamps ts;
grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE);
for (auto i = 0; i < NUM_ELEM; i++) {
GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) ==
static_cast<gpr_atm>(1));
grpc_transport_destroy_stream(reinterpret_cast<grpc_transport*>(t),
reinterpret_cast<grpc_stream*>(s[i]),
nullptr);
exec_ctx.Flush();
gpr_free(s[i]);
}
grpc_transport_destroy(t);
grpc_resource_quota_unref(resource_quota);
exec_ctx.Flush();
}
static void TestContextList() { TestExecuteFlushesList(); }

@ -103,19 +103,19 @@ static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) {
static int me_get_fd(grpc_endpoint* ep) { return -1; }
static const grpc_endpoint_vtable vtable = {
me_read,
me_write,
me_add_to_pollset,
me_add_to_pollset_set,
me_delete_from_pollset_set,
me_shutdown,
me_destroy,
me_get_resource_user,
me_get_peer,
me_get_fd,
nullptr,
};
static bool me_can_track_err(grpc_endpoint* ep) { return false; }
static const grpc_endpoint_vtable vtable = {me_read,
me_write,
me_add_to_pollset,
me_add_to_pollset_set,
me_delete_from_pollset_set,
me_shutdown,
me_destroy,
me_get_resource_user,
me_get_peer,
me_get_fd,
me_can_track_err};
grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice),
grpc_resource_quota* resource_quota) {

@ -155,6 +155,8 @@ static char* me_get_peer(grpc_endpoint* ep) {
static int me_get_fd(grpc_endpoint* ep) { return -1; }
static bool me_can_track_err(grpc_endpoint* ep) { return false; }
static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) {
half* m = reinterpret_cast<half*>(ep);
return m->resource_user;
@ -171,7 +173,7 @@ static const grpc_endpoint_vtable vtable = {
me_get_resource_user,
me_get_peer,
me_get_fd,
nullptr,
me_can_track_err,
};
static void half_init(half* m, passthru_endpoint* parent,

@ -131,6 +131,8 @@ static int te_get_fd(grpc_endpoint* ep) {
return grpc_endpoint_get_fd(te->wrapped);
}
static bool te_can_track_err(grpc_endpoint* ep) { return false; }
static void te_finish_write(void* arg, grpc_error* error) {
trickle_endpoint* te = static_cast<trickle_endpoint*>(arg);
gpr_mu_lock(&te->mu);
@ -149,7 +151,7 @@ static const grpc_endpoint_vtable vtable = {te_read,
te_get_resource_user,
te_get_peer,
te_get_fd,
nullptr};
te_can_track_err};
grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap,
double bytes_per_second) {

@ -54,7 +54,8 @@ class DummyEndpoint : public grpc_endpoint {
destroy,
get_resource_user,
get_peer,
get_fd};
get_fd,
can_track_err};
grpc_endpoint::vtable = &my_vtable;
ru_ = grpc_resource_user_create(Library::get().rq(), "dummy_endpoint");
}
@ -125,6 +126,7 @@ class DummyEndpoint : public grpc_endpoint {
}
static char* get_peer(grpc_endpoint* ep) { return gpr_strdup("test"); }
static int get_fd(grpc_endpoint* ep) { return 0; }
static bool can_track_err(grpc_endpoint* ep) { return false; }
};
class Fixture {

@ -364,21 +364,6 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "context_list_test",
"src": [
"test/core/transport/chttp2/context_list_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -3522,6 +3507,21 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c++",
"name": "context_list_test",
"src": [
"test/core/transport/chttp2/context_list_test.cc"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",

@ -433,30 +433,6 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "context_list_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
@ -4147,6 +4123,30 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c++",
"name": "context_list_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save