Merge with master and resolve conflict

reviewable/pr17308/r1
yang-g 6 years ago
commit 483e0ad3f2
  1. 3
      .gitmodules
  2. 1
      AUTHORS
  3. 2
      CONTRIBUTING.md
  4. 44
      WORKSPACE
  5. 4
      bazel/grpc_build_system.bzl
  6. 12
      bazel/grpc_deps.bzl
  7. 22
      doc/grpc_release_schedule.md
  8. 2
      include/grpc/impl/codegen/atm_gcc_sync.h
  9. 2
      include/grpc/impl/codegen/atm_windows.h
  10. 84
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  11. 1
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  12. 4
      src/core/ext/transport/chttp2/transport/internal.h
  13. 44
      src/core/lib/gprpp/inlined_vector.h
  14. 11
      src/core/lib/gprpp/ref_counted.h
  15. 4
      src/core/lib/iomgr/ev_epoll1_linux.cc
  16. 4
      src/core/lib/iomgr/ev_epollex_linux.cc
  17. 4
      src/core/lib/iomgr/ev_poll_posix.cc
  18. 22
      src/core/lib/iomgr/ev_posix.cc
  19. 10
      src/core/lib/iomgr/ev_posix.h
  20. 39
      src/core/lib/iomgr/internal_errqueue.cc
  21. 8
      src/core/lib/iomgr/internal_errqueue.h
  22. 6
      src/core/lib/iomgr/iomgr.cc
  23. 4
      src/core/lib/iomgr/iomgr.h
  24. 4
      src/core/lib/iomgr/iomgr_custom.cc
  25. 4
      src/core/lib/iomgr/iomgr_internal.cc
  26. 4
      src/core/lib/iomgr/iomgr_internal.h
  27. 7
      src/core/lib/iomgr/iomgr_posix.cc
  28. 7
      src/core/lib/iomgr/iomgr_posix_cfstream.cc
  29. 5
      src/core/lib/iomgr/iomgr_windows.cc
  30. 3
      src/core/lib/iomgr/port.h
  31. 29
      src/core/lib/iomgr/tcp_posix.cc
  32. 4
      src/core/lib/surface/init.cc
  33. 3
      src/core/lib/transport/transport.cc
  34. 6
      src/core/lib/transport/transport.h
  35. 6
      src/php/ext/grpc/php_grpc.c
  36. 2
      src/python/grpcio/grpc/__init__.py
  37. 7
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
  38. 8
      src/python/grpcio/grpc/_interceptor.py
  39. 2
      src/ruby/lib/grpc/generic/service.rb
  40. 22
      src/ruby/spec/generic/rpc_server_spec.rb
  41. 1
      src/ruby/spec/support/services.rb
  42. 2
      test/core/gpr/BUILD
  43. 164
      test/core/gprpp/inlined_vector_test.cc
  44. 2
      test/core/iomgr/BUILD
  45. 8
      test/cpp/end2end/grpclb_end2end_test.cc
  46. 1
      test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
  47. 2
      test/cpp/qps/BUILD
  48. 51
      third_party/toolchains/BUILD
  49. 1
      third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE
  50. 31
      third_party/toolchains/machine_size/BUILD
  51. 1
      third_party/upb
  52. 1
      tools/doxygen/Doxyfile.c++
  53. 1
      tools/doxygen/Doxyfile.c++.internal
  54. 1
      tools/doxygen/Doxyfile.core
  55. 1
      tools/doxygen/Doxyfile.core.internal
  56. 13
      tools/remote_build/rbe_common.bazelrc
  57. 1
      tools/run_tests/sanity/check_bazel_workspace.py
  58. 1
      tools/run_tests/sanity/check_submodules.sh

3
.gitmodules vendored

@ -51,3 +51,6 @@
[submodule "third_party/protoc-gen-validate"]
path = third_party/protoc-gen-validate
url = https://github.com/lyft/protoc-gen-validate.git
[submodule "third_party/upb"]
path = third_party/upb
url = https://github.com/google/upb.git

@ -1,2 +1,3 @@
Dropbox, Inc.
Google Inc.
WeWork Companies Inc.

@ -81,7 +81,7 @@ How to get your contributions merged smoothly and quickly.
copyright holder for the contribution (yourself, if you are signing the
individual CLA, or your company, for corporate CLAs) in the same PR as your
contribution. This needs to be done only once, for each company, or
individual.
individual. Please keep this file in alphabetical order.
- Maintain **clean commit history** and use **meaningful commit messages**.
PRs with messy commit history are difficult to review and won't be merged.

@ -1,45 +1,59 @@
workspace(name="com_github_grpc_grpc")
workspace(name = "com_github_grpc_grpc")
load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps")
grpc_deps()
grpc_test_only_deps()
register_execution_platforms(
"//third_party/toolchains:all",
)
register_toolchains(
"//third_party/toolchains:all",
)
new_http_archive(
name="cython",
sha256="d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
urls=[
name = "cython",
build_file = "//third_party:cython.BUILD",
sha256 = "d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
strip_prefix = "cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c",
urls = [
"https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz",
],
strip_prefix="cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c",
build_file="//third_party:cython.BUILD",
)
load("//third_party/py:python_configure.bzl", "python_configure")
python_configure(name="local_config_python")
python_configure(name = "local_config_python")
git_repository(
name="io_bazel_rules_python",
remote="https://github.com/bazelbuild/rules_python.git",
commit="8b5d0683a7d878b28fffe464779c8a53659fc645",
name = "io_bazel_rules_python",
commit = "8b5d0683a7d878b28fffe464779c8a53659fc645",
remote = "https://github.com/bazelbuild/rules_python.git",
)
load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import")
pip_repositories()
pip_import(
name="grpc_python_dependencies",
requirements="//:requirements.bazel.txt",
name = "grpc_python_dependencies",
requirements = "//:requirements.bazel.txt",
)
load("@grpc_python_dependencies//:requirements.bzl", "pip_install")
pip_install()
# NOTE(https://github.com/pubref/rules_protobuf/pull/196): Switch to upstream repo after this gets merged.
git_repository(
name="org_pubref_rules_protobuf",
remote="https://github.com/ghostwriternr/rules_protobuf",
tag="v0.8.2.1-alpha",
name = "org_pubref_rules_protobuf",
remote = "https://github.com/ghostwriternr/rules_protobuf",
tag = "v0.8.2.1-alpha",
)
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories")
py_proto_repositories()

@ -131,7 +131,7 @@ def grpc_proto_library(
generate_mocks = generate_mocks,
)
def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = []):
def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = [], exec_compatible_with = []):
copts = []
if language.upper() == "C":
copts = if_not_windows(["-std=c99"])
@ -145,6 +145,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
"linkopts": if_not_windows(["-pthread"]),
"size": size,
"timeout": timeout,
"exec_compatible_with": exec_compatible_with,
}
if uses_polling:
native.cc_test(testonly = True, tags = ["manual"], **args)
@ -162,6 +163,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
"$(location %s)" % name,
] + args["args"],
tags = tags,
exec_compatible_with = exec_compatible_with,
)
else:
native.cc_test(**args)

@ -8,6 +8,11 @@ def grpc_deps():
actual = "@com_github_nanopb_nanopb//:nanopb",
)
native.bind(
name = "upblib",
actual = "@upb//:upb",
)
native.bind(
name = "absl-base",
actual = "@com_google_absl//absl/base",
@ -184,6 +189,13 @@ def grpc_deps():
url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz",
)
if "upb" not in native.existing_rules():
native.http_archive(
name = "upb",
strip_prefix = "upb-9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3",
url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz",
)
# TODO: move some dependencies from "grpc_deps" here?
def grpc_test_only_deps():

@ -0,0 +1,22 @@
# gRPC Release Schedule
Below is the release schedule for gRPC [Java](https://github.com/grpc/grpc-java/releases), [Go](https://github.com/grpc/grpc-go/releases) and [Core](https://github.com/grpc/grpc/releases) and its dependent languages C++, C#, Objective-C, PHP, Python and Ruby.
Releases are scheduled every six weeks on Tuesdays on a best effort basis. In some unavoidable situations a release may be delayed or a language may skip a release altogether and do the next release to catch up with other languages. See the past releases in the links above. A six-week cycle gives us a good balance between delivering new features/fixes quickly and keeping the release overhead low.
Releases are cut from release branches. For Core and Java repos, the release branch is cut two weeks before the scheduled release date. For Go, the branch is cut just before the release. An RC (release candidate) is published for Core and its dependent languages just after the branch cut. This RC is later promoted to release version if no further changes are made to the release branch. We do our best to keep head of master branch stable at all times regardless of release schedule. Daily build packages from master branch for C#, PHP, Python, Ruby and Protoc plugins are published on [packages.grpc.io](https://packages.grpc.io/). If you depend on gRPC in production we recommend to set up your CI system to test the RCs and, if possible, the daily builds.
Names of gRPC releases are [here](https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md).
Release |Scheduled Branch Cut|Scheduled Release Date
--------|--------------------|-------------
v1.17.0 |Nov 19, 2018 |Dec 4, 2018
v1.18.0 |Jan 2, 2019 |Jan 15, 2019
v1.19.0 |Feb 12, 2019 |Feb 26, 2019
v1.20.0 |Mar 26, 2019 |Apr 9, 2019
v1.21.0 |May 7, 2019 |May 21, 2019
v1.22.0 |Jun 18, 2019 |Jul 2, 2019
v1.23.0 |Jul 30, 2019 |Aug 13, 2019
v1.24.0 |Sept 10, 2019 |Sept 24, 2019
v1.25.0 |Oct 22, 2019 |Nov 5, 2019
v1.26.0 |Dec 3, 2019 |Dec 17, 2019

@ -26,6 +26,8 @@
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
#define GPR_ATM_INC_CAS_THEN(blah) blah
#define GPR_ATM_INC_ADD_THEN(blah) blah
#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")

@ -25,6 +25,8 @@
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
#define GPR_ATM_INC_CAS_THEN(blah) blah
#define GPR_ATM_INC_ADD_THEN(blah) blah
#define gpr_atm_full_barrier MemoryBarrier

@ -749,7 +749,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
void* arg, grpc_error* error) {
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
// Empty payload means the LB call was cancelled.
// Null payload means the LB call was cancelled.
if (lb_calld != grpclb_policy->lb_calld_.get() ||
lb_calld->recv_message_payload_ == nullptr) {
lb_calld->Unref(DEBUG_LOCATION, "on_message_received");
@ -803,54 +803,45 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
gpr_free(ipport);
}
}
/* update serverlist */
if (serverlist->num_servers > 0) {
// Start sending client load report only after we start using the
// serverlist returned from the current LB call.
if (lb_calld->client_stats_report_interval_ > 0 &&
lb_calld->client_stats_ == nullptr) {
lb_calld->client_stats_.reset(New<GrpcLbClientStats>());
// TODO(roth): We currently track this ref manually. Once the
// ClosureRef API is ready, we should pass the RefCountedPtr<> along
// with the callback.
auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report");
self.release();
lb_calld->ScheduleNextClientLoadReportLocked();
}
if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_,
serverlist)) {
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Incoming server list identical to current, "
"ignoring.",
grpclb_policy);
}
grpc_grpclb_destroy_serverlist(serverlist);
} else { /* new serverlist */
if (grpclb_policy->serverlist_ != nullptr) {
/* dispose of the old serverlist */
grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_);
} else {
/* or dispose of the fallback */
grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_);
grpclb_policy->fallback_backend_addresses_ = nullptr;
if (grpclb_policy->fallback_timer_callback_pending_) {
grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
}
}
// and update the copy in the GrpcLb instance. This
// serverlist instance will be destroyed either upon the next
// update or when the GrpcLb instance is destroyed.
grpclb_policy->serverlist_ = serverlist;
grpclb_policy->serverlist_index_ = 0;
grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
}
} else {
// Start sending client load report only after we start using the
// serverlist returned from the current LB call.
if (lb_calld->client_stats_report_interval_ > 0 &&
lb_calld->client_stats_ == nullptr) {
lb_calld->client_stats_.reset(New<GrpcLbClientStats>());
// TODO(roth): We currently track this ref manually. Once the
// ClosureRef API is ready, we should pass the RefCountedPtr<> along
// with the callback.
auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report");
self.release();
lb_calld->ScheduleNextClientLoadReportLocked();
}
// Check if the serverlist differs from the previous one.
if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) {
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] Received empty server list, ignoring.",
gpr_log(GPR_INFO,
"[grpclb %p] Incoming server list identical to current, "
"ignoring.",
grpclb_policy);
}
grpc_grpclb_destroy_serverlist(serverlist);
} else { // New serverlist.
if (grpclb_policy->serverlist_ != nullptr) {
// Dispose of the old serverlist.
grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_);
} else {
// Dispose of the fallback.
grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_);
grpclb_policy->fallback_backend_addresses_ = nullptr;
if (grpclb_policy->fallback_timer_callback_pending_) {
grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
}
}
// Update the serverlist in the GrpcLb instance. This serverlist
// instance will be destroyed either upon the next update or when the
// GrpcLb instance is destroyed.
grpclb_policy->serverlist_ = serverlist;
grpclb_policy->serverlist_index_ = 0;
grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
}
} else {
// No valid initial response or serverlist found.
@ -1583,7 +1574,7 @@ void GrpcLb::AddPendingPick(PendingPick* pp) {
bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
grpc_error** error) {
// Check for drops if we are not using fallback backend addresses.
if (serverlist_ != nullptr) {
if (serverlist_ != nullptr && serverlist_->num_servers > 0) {
// Look at the index into the serverlist to see if we should drop this call.
grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++];
if (serverlist_index_ == serverlist_->num_servers) {
@ -1681,7 +1672,6 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
grpc_lb_addresses* addresses;
bool is_backend_from_grpclb_load_balancer = false;
if (serverlist_ != nullptr) {
GPR_ASSERT(serverlist_->num_servers > 0);
addresses = ProcessServerlist(serverlist_);
is_backend_from_grpclb_load_balancer = true;
} else {

@ -1390,6 +1390,7 @@ static void perform_stream_op_locked(void* stream_op,
GRPC_STATS_INC_HTTP2_OP_BATCHES();
s->context = op->payload->context;
s->traced = op->is_traced;
if (grpc_http_trace.enabled()) {
char* str = grpc_transport_stream_op_batch_string(op);
gpr_log(GPR_INFO, "perform_stream_op_locked: %s; on_complete = %p", str,

@ -642,10 +642,10 @@ struct grpc_chttp2_stream {
/** Whether bytes stored in unprocessed_incoming_byte_stream is decompressed
*/
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;
/** gRPC header bytes that are already decompressed */
size_t decompressed_header_bytes = 0;
};
/** Transport writing call flow:

@ -100,10 +100,7 @@ class InlinedVector {
void reserve(size_t capacity) {
if (capacity > capacity_) {
T* new_dynamic = static_cast<T*>(gpr_malloc(sizeof(T) * capacity));
for (size_t i = 0; i < size_; ++i) {
new (&new_dynamic[i]) T(std::move(data()[i]));
data()[i].~T();
}
move_elements(data(), new_dynamic, size_);
gpr_free(dynamic_);
dynamic_ = new_dynamic;
capacity_ = capacity;
@ -131,13 +128,25 @@ class InlinedVector {
size_--;
}
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
size_t capacity() const { return capacity_; }
void clear() {
destroy_elements();
init_data();
}
private:
void copy_from(const InlinedVector& v) {
// if v is allocated, copy over the buffer.
// if v is allocated, make sure we have enough capacity.
if (v.dynamic_ != nullptr) {
reserve(v.capacity_);
memcpy(dynamic_, v.dynamic_, v.size_ * sizeof(T));
} else {
memcpy(inline_, v.inline_, v.size_ * sizeof(T));
}
// copy over elements
for (size_t i = 0; i < v.size_; ++i) {
new (&(data()[i])) T(v[i]);
}
// copy over metadata
size_ = v.size_;
@ -145,11 +154,12 @@ class InlinedVector {
}
void move_from(InlinedVector& v) {
// if v is allocated, then we steal its buffer, else we copy it.
// if v is allocated, then we steal its dynamic array; otherwise, we
// move the elements individually.
if (v.dynamic_ != nullptr) {
dynamic_ = v.dynamic_;
} else {
memcpy(inline_, v.inline_, v.size_ * sizeof(T));
move_elements(v.data(), data(), v.size_);
}
// copy over metadata
size_ = v.size_;
@ -158,17 +168,13 @@ class InlinedVector {
v.init_data();
}
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
size_t capacity() const { return capacity_; }
void clear() {
destroy_elements();
init_data();
static void move_elements(T* src, T* dst, size_t num_elements) {
for (size_t i = 0; i < num_elements; ++i) {
new (&dst[i]) T(std::move(src[i]));
src[i].~T();
}
}
private:
void init_data() {
dynamic_ = nullptr;
size_ = 0;

@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
@ -76,12 +77,15 @@ class RefCount {
constexpr explicit RefCount(Value init = 1) : value_(init) {}
// Increases the ref-count by `n`.
void Ref(Value n = 1) { value_.fetch_add(n, std::memory_order_relaxed); }
void Ref(Value n = 1) {
GPR_ATM_INC_ADD_THEN(value_.fetch_add(n, std::memory_order_relaxed));
}
// Similar to Ref() with an assert on the ref-count being non-zero.
void RefNonZero() {
#ifndef NDEBUG
const Value prior = value_.fetch_add(1, std::memory_order_relaxed);
const Value prior =
GPR_ATM_INC_ADD_THEN(value_.fetch_add(1, std::memory_order_relaxed));
assert(prior > 0);
#else
Ref();
@ -90,7 +94,8 @@ class RefCount {
// Decrements the ref-count and returns true if the ref-count reaches 0.
bool Unref() {
const Value prior = value_.fetch_sub(1, std::memory_order_acq_rel);
const Value prior =
GPR_ATM_INC_ADD_THEN(value_.fetch_sub(1, std::memory_order_acq_rel));
GPR_DEBUG_ASSERT(prior > 0);
return prior == 1;
}

@ -1242,6 +1242,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag,
* Event engine binding
*/
static void shutdown_background_closure(void) {}
static void shutdown_engine(void) {
fd_global_shutdown();
pollset_global_shutdown();
@ -1255,6 +1257,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
true,
false,
fd_create,
fd_wrapped_fd,
@ -1284,6 +1287,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
shutdown_background_closure,
shutdown_engine,
};

@ -1604,6 +1604,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag,
* Event engine binding
*/
static void shutdown_background_closure(void) {}
static void shutdown_engine(void) {
fd_global_shutdown();
pollset_global_shutdown();
@ -1612,6 +1614,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
true,
false,
fd_create,
fd_wrapped_fd,
@ -1641,6 +1644,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
shutdown_background_closure,
shutdown_engine,
};

@ -1782,6 +1782,8 @@ static void global_cv_fd_table_shutdown() {
* event engine binding
*/
static void shutdown_background_closure(void) {}
static void shutdown_engine(void) {
pollset_global_shutdown();
if (grpc_cv_wakeup_fds_enabled()) {
@ -1796,6 +1798,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
false,
false,
fd_create,
fd_wrapped_fd,
@ -1825,6 +1828,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
shutdown_background_closure,
shutdown_engine,
};

@ -36,6 +36,7 @@
#include "src/core/lib/iomgr/ev_epoll1_linux.h"
#include "src/core/lib/iomgr/ev_epollex_linux.h"
#include "src/core/lib/iomgr/ev_poll_posix.h"
#include "src/core/lib/iomgr/internal_errqueue.h"
grpc_core::TraceFlag grpc_polling_trace(false,
"polling"); /* Disabled by default */
@ -236,19 +237,22 @@ void grpc_event_engine_shutdown(void) {
}
bool grpc_event_engine_can_track_errors(void) {
/* Only track errors if platform supports errqueue. */
#ifdef GRPC_LINUX_ERRQUEUE
return g_event_engine->can_track_err;
#else
/* Only track errors if platform supports errqueue. */
if (grpc_core::kernel_supports_errqueue()) {
return g_event_engine->can_track_err;
}
return false;
#endif /* GRPC_LINUX_ERRQUEUE */
}
bool grpc_event_engine_run_in_background(void) {
return g_event_engine->run_in_background;
}
grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) {
GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
return g_event_engine->fd_create(fd, name,
track_err && g_event_engine->can_track_err);
return g_event_engine->fd_create(
fd, name, track_err && grpc_event_engine_can_track_errors());
}
int grpc_fd_wrapped_fd(grpc_fd* fd) {
@ -395,4 +399,8 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) {
g_event_engine->pollset_set_del_fd(pollset_set, fd);
}
void grpc_shutdown_background_closure(void) {
g_event_engine->shutdown_background_closure();
}
#endif // GRPC_POSIX_SOCKET_EV

@ -42,6 +42,7 @@ typedef struct grpc_fd grpc_fd;
typedef struct grpc_event_engine_vtable {
size_t pollset_size;
bool can_track_err;
bool run_in_background;
grpc_fd* (*fd_create)(int fd, const char* name, bool track_err);
int (*fd_wrapped_fd)(grpc_fd* fd);
@ -79,6 +80,7 @@ typedef struct grpc_event_engine_vtable {
void (*pollset_set_add_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd);
void (*pollset_set_del_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd);
void (*shutdown_background_closure)(void);
void (*shutdown_engine)(void);
} grpc_event_engine_vtable;
@ -101,6 +103,11 @@ const char* grpc_get_poll_strategy_name();
*/
bool grpc_event_engine_can_track_errors();
/* Returns true if polling engine runs in the background, false otherwise.
* Currently only 'epollbg' runs in the background.
*/
bool grpc_event_engine_run_in_background();
/* Create a wrapped file descriptor.
Requires fd is a non-blocking file descriptor.
\a track_err if true means that error events would be tracked separately
@ -174,6 +181,9 @@ void grpc_pollset_add_fd(grpc_pollset* pollset, struct grpc_fd* fd);
void grpc_pollset_set_add_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
/* Shut down all the closures registered in the background poller. */
void grpc_shutdown_background_closure();
/* override to allow tests to hook poll() usage */
typedef int (*grpc_poll_function_type)(struct pollfd*, nfds_t, int);
extern grpc_poll_function_type grpc_poll_function;

@ -20,17 +20,50 @@
#include "src/core/lib/iomgr/port.h"
#include <grpc/impl/codegen/log.h>
#include "src/core/lib/iomgr/internal_errqueue.h"
#ifdef GRPC_POSIX_SOCKET_TCP
bool kernel_supports_errqueue() {
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>
namespace grpc_core {
static bool errqueue_supported = false;
bool kernel_supports_errqueue() { return errqueue_supported; }
void grpc_errqueue_init() {
/* Both-compile time and run-time linux kernel versions should be atleast 4.0.0
*/
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
return true;
struct utsname buffer;
if (uname(&buffer) != 0) {
gpr_log(GPR_ERROR, "uname: %s", strerror(errno));
return;
}
char* release = buffer.release;
if (release == nullptr) {
return;
}
if (strtol(release, nullptr, 10) >= 4) {
errqueue_supported = true;
} else {
gpr_log(GPR_DEBUG, "ERRQUEUE support not enabled");
}
#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
return false;
}
} /* namespace grpc_core */
#else
namespace grpc_core {
void grpc_errqueue_init() {}
} /* namespace grpc_core */
#endif /* GRPC_POSIX_SOCKET_TCP */

@ -76,8 +76,14 @@ constexpr uint32_t kTimestampingRecordingOptions =
* Currently allowing only linux kernels above 4.0.0
*/
bool kernel_supports_errqueue();
} // namespace grpc_core
} /* namespace grpc_core */
#endif /* GRPC_POSIX_SOCKET_TCP */
namespace grpc_core {
/* Initializes errqueue support */
void grpc_errqueue_init();
} /* namespace grpc_core */
#endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */

@ -36,6 +36,7 @@
#include "src/core/lib/iomgr/buffer_list.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/internal_errqueue.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/network_status_tracker.h"
#include "src/core/lib/iomgr/timer.h"
@ -58,6 +59,7 @@ void grpc_iomgr_init() {
g_root_object.name = (char*)"root";
grpc_network_status_init();
grpc_iomgr_platform_init();
grpc_core::grpc_errqueue_init();
}
void grpc_iomgr_start() { grpc_timer_manager_init(); }
@ -155,6 +157,10 @@ void grpc_iomgr_shutdown() {
gpr_cv_destroy(&g_rcv);
}
void grpc_iomgr_shutdown_background_closure() {
grpc_iomgr_platform_shutdown_background_closure();
}
void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name) {
obj->name = gpr_strdup(name);
gpr_mu_lock(&g_mu);

@ -35,6 +35,10 @@ void grpc_iomgr_start();
* exec_ctx. */
void grpc_iomgr_shutdown();
/** Signals the intention to shutdown all the closures registered in the
* background poller. */
void grpc_iomgr_shutdown_background_closure();
/* Exposed only for testing */
size_t grpc_iomgr_count_objects_for_testing();

@ -40,9 +40,11 @@ static void iomgr_platform_init(void) {
}
static void iomgr_platform_flush(void) {}
static void iomgr_platform_shutdown(void) { grpc_pollset_global_shutdown(); }
static void iomgr_platform_shutdown_background_closure(void) {}
static grpc_iomgr_platform_vtable vtable = {
iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
iomgr_platform_shutdown_background_closure};
void grpc_custom_iomgr_init(grpc_socket_vtable* socket,
grpc_custom_resolver_vtable* resolver,

@ -41,3 +41,7 @@ void grpc_iomgr_platform_init() { iomgr_platform_vtable->init(); }
void grpc_iomgr_platform_flush() { iomgr_platform_vtable->flush(); }
void grpc_iomgr_platform_shutdown() { iomgr_platform_vtable->shutdown(); }
void grpc_iomgr_platform_shutdown_background_closure() {
iomgr_platform_vtable->shutdown_background_closure();
}

@ -35,6 +35,7 @@ typedef struct grpc_iomgr_platform_vtable {
void (*init)(void);
void (*flush)(void);
void (*shutdown)(void);
void (*shutdown_background_closure)(void);
} grpc_iomgr_platform_vtable;
void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name);
@ -52,6 +53,9 @@ void grpc_iomgr_platform_flush(void);
/** tear down all platform specific global iomgr structures */
void grpc_iomgr_platform_shutdown(void);
/** shut down all the closures registered in the background poller */
void grpc_iomgr_platform_shutdown_background_closure(void);
bool grpc_iomgr_abort_on_leaks(void);
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H */

@ -51,8 +51,13 @@ static void iomgr_platform_shutdown(void) {
grpc_wakeup_fd_global_destroy();
}
static void iomgr_platform_shutdown_background_closure(void) {
grpc_shutdown_background_closure();
}
static grpc_iomgr_platform_vtable vtable = {
iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
grpc_set_tcp_client_impl(&grpc_posix_tcp_client_vtable);

@ -54,8 +54,13 @@ static void iomgr_platform_shutdown(void) {
grpc_wakeup_fd_global_destroy();
}
static void iomgr_platform_shutdown_background_closure(void) {
grpc_shutdown_background_closure();
}
static grpc_iomgr_platform_vtable vtable = {
iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
char* enable_cfstream = getenv(grpc_cfstream_env_var);

@ -71,8 +71,11 @@ static void iomgr_platform_shutdown(void) {
winsock_shutdown();
}
static void iomgr_platform_shutdown_background_closure(void) {}
static grpc_iomgr_platform_vtable vtable = {
iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
grpc_set_tcp_client_impl(&grpc_windows_tcp_client_vtable);

@ -62,8 +62,7 @@
#define GRPC_HAVE_UNIX_SOCKET 1
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
/* TODO(yashykt): Re-enable once Fathom changes are commited.
#define GRPC_LINUX_ERRQUEUE 1 */
#define GRPC_LINUX_ERRQUEUE 1
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
#define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1

@ -260,10 +260,17 @@ static void notify_on_write(grpc_tcp* tcp) {
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp);
}
cover_self(tcp);
GRPC_CLOSURE_INIT(&tcp->write_done_closure,
tcp_drop_uncovered_then_handle_write, tcp,
grpc_schedule_on_exec_ctx);
if (grpc_event_engine_run_in_background()) {
// If there is a polling engine always running in the background, there is
// no need to run the backup poller.
GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp,
grpc_schedule_on_exec_ctx);
} else {
cover_self(tcp);
GRPC_CLOSURE_INIT(&tcp->write_done_closure,
tcp_drop_uncovered_then_handle_write, tcp,
grpc_schedule_on_exec_ctx);
}
grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_done_closure);
}
@ -740,7 +747,7 @@ static bool process_errors(grpc_tcp* tcp) {
}
return false;
}
process_timestamp(tcp, &msg, cmsg);
cmsg = process_timestamp(tcp, &msg, cmsg);
}
}
}
@ -761,13 +768,11 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
/* We are still interested in collecting timestamps, so let's try reading
* them. */
if (!process_errors(tcp)) {
/* This was not a timestamps error. This was an actual error. Set the
* read and write closures to be ready.
*/
grpc_fd_set_readable(tcp->em_fd);
grpc_fd_set_writable(tcp->em_fd);
}
process_errors(tcp);
/* This might not a timestamps error. Set the read and write closures to be
* ready. */
grpc_fd_set_readable(tcp->em_fd);
grpc_fd_set_writable(tcp->em_fd);
GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure);

@ -175,8 +175,10 @@ void grpc_shutdown_internal(void* ignored) {
}
{
grpc_core::ExecCtx exec_ctx(0);
grpc_iomgr_shutdown_background_closure();
{
grpc_timer_manager_set_threading(false); // shutdown timer_manager thread
grpc_timer_manager_set_threading(
false); // shutdown timer_manager thread
grpc_executor_shutdown();
for (i = g_number_of_plugins; i >= 0; i--) {
if (g_all_of_the_plugins[i].destroy != nullptr) {

@ -27,6 +27,7 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include "src/core/lib/gpr/alloc.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/slice/slice_internal.h"
@ -149,7 +150,7 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from,
}
size_t grpc_transport_stream_size(grpc_transport* transport) {
return transport->vtable->sizeof_stream;
return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(transport->vtable->sizeof_stream);
}
void grpc_transport_destroy(grpc_transport* transport) {

@ -129,7 +129,8 @@ struct grpc_transport_stream_op_batch {
recv_initial_metadata(false),
recv_message(false),
recv_trailing_metadata(false),
cancel_stream(false) {}
cancel_stream(false),
is_traced(false) {}
/** Should be scheduled when all of the non-recv operations in the batch
are complete.
@ -167,6 +168,9 @@ struct grpc_transport_stream_op_batch {
/** Cancel this stream with the provided error */
bool cancel_stream : 1;
/** Is this stream traced */
bool is_traced : 1;
/***************************************************************************
* remaining fields are initialized and used at the discretion of the
* current handler of the op */

@ -171,11 +171,13 @@ void prefork() {
}
void postfork_child() {
TSRMLS_FETCH();
// loop through persistant list and destroy all underlying grpc_channel objs
destroy_grpc_channels();
// clear completion queue
grpc_php_shutdown_completion_queue();
grpc_php_shutdown_completion_queue(TSRMLS_C);
// clean-up grpc_core
grpc_shutdown();
@ -187,7 +189,7 @@ void postfork_child() {
// restart grpc_core
grpc_init();
grpc_php_init_completion_queue();
grpc_php_init_completion_queue(TSRMLS_C);
// re-create grpc_channel and point wrapped to it
// unlock wrapped grpc channel mutex

@ -1723,7 +1723,7 @@ def server(thread_pool,
handlers. The interceptors are given control in the order they are
specified. This is an EXPERIMENTAL API.
options: An optional list of key-value pairs (channel args in gRPC runtime)
to configure the channel.
to configure the channel.
maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server
will service before returning RESOURCE_EXHAUSTED status, or None to
indicate no limit.

@ -121,7 +121,6 @@ cdef extern from "grpc/grpc.h":
GRPC_STATUS_DATA_LOSS
GRPC_STATUS__DO_NOT_USE
const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING
const char *GRPC_ARG_ENABLE_CENSUS
const char *GRPC_ARG_MAX_CONCURRENT_STREAMS
const char *GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH
@ -190,12 +189,6 @@ cdef extern from "grpc/grpc.h":
size_t arguments_length "num_args"
grpc_arg *arguments "args"
ctypedef enum grpc_compression_level:
GRPC_COMPRESS_LEVEL_NONE
GRPC_COMPRESS_LEVEL_LOW
GRPC_COMPRESS_LEVEL_MED
GRPC_COMPRESS_LEVEL_HIGH
ctypedef enum grpc_stream_compression_level:
GRPC_STREAM_COMPRESS_LEVEL_NONE
GRPC_STREAM_COMPRESS_LEVEL_LOW

@ -232,8 +232,8 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
credentials=new_credentials,
wait_for_ready=new_wait_for_ready)
return _UnaryOutcome(response, call)
except grpc.RpcError:
raise
except grpc.RpcError as rpc_error:
return rpc_error
except Exception as exception: # pylint:disable=broad-except
return _FailureOutcome(exception, sys.exc_info()[2])
@ -354,8 +354,8 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
credentials=new_credentials,
wait_for_ready=new_wait_for_ready)
return _UnaryOutcome(response, call)
except grpc.RpcError:
raise
except grpc.RpcError as rpc_error:
return rpc_error
except Exception as exception: # pylint:disable=broad-except
return _FailureOutcome(exception, sys.exc_info()[2])

@ -95,7 +95,7 @@ module GRPC
rpc_descs[name] = RpcDesc.new(name, input, output,
marshal_class_method,
unmarshal_class_method)
define_method(GenericService.underscore(name.to_s).to_sym) do |_, _|
define_method(GenericService.underscore(name.to_s).to_sym) do |*|
fail GRPC::BadStatus.new_status_exception(
GRPC::Core::StatusCodes::UNIMPLEMENTED)
end

@ -342,6 +342,28 @@ describe GRPC::RpcServer do
t.join
end
it 'should return UNIMPLEMENTED on unimplemented ' \
'methods for client_streamer', server: true do
@srv.handle(EchoService)
t = Thread.new { @srv.run }
@srv.wait_till_running
blk = proc do
stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts)
requests = [EchoMsg.new, EchoMsg.new]
stub.a_client_streaming_rpc_unimplemented(requests)
end
begin
expect(&blk).to raise_error do |error|
expect(error).to be_a(GRPC::BadStatus)
expect(error.code).to eq(GRPC::Core::StatusCodes::UNIMPLEMENTED)
end
ensure
@srv.stop # should be call not to crash
t.join
end
end
it 'should handle multiple sequential requests', server: true do
@srv.handle(EchoService)
t = Thread.new { @srv.run }

@ -33,6 +33,7 @@ class EchoService
rpc :a_client_streaming_rpc, stream(EchoMsg), EchoMsg
rpc :a_server_streaming_rpc, EchoMsg, stream(EchoMsg)
rpc :a_bidi_rpc, stream(EchoMsg), stream(EchoMsg)
rpc :a_client_streaming_rpc_unimplemented, stream(EchoMsg), EchoMsg
attr_reader :received_md
def initialize(**kw)

@ -81,12 +81,12 @@ grpc_cc_test(
grpc_cc_test(
name = "mpscq_test",
srcs = ["mpscq_test.cc"],
exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
language = "C++",
deps = [
"//:gpr",
"//test/core/util:gpr_test_util",
],
data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
)
grpc_cc_test(

@ -116,7 +116,7 @@ typedef InlinedVector<int, kInlinedLength> IntVec8;
const size_t kInlinedFillSize = kInlinedLength - 1;
const size_t kAllocatedFillSize = kInlinedLength + 1;
TEST(InlinedVectorTest, CopyConstructerInlined) {
TEST(InlinedVectorTest, CopyConstructorInlined) {
IntVec8 original;
FillVector(&original, kInlinedFillSize);
IntVec8 copy_constructed(original);
@ -125,7 +125,7 @@ TEST(InlinedVectorTest, CopyConstructerInlined) {
}
}
TEST(InlinedVectorTest, CopyConstructerAllocated) {
TEST(InlinedVectorTest, CopyConstructorAllocated) {
IntVec8 original;
FillVector(&original, kAllocatedFillSize);
IntVec8 copy_constructed(original);
@ -264,6 +264,166 @@ TEST(InlinedVectorTest, MoveAssignmentAllocatedAllocated) {
EXPECT_EQ(move_assigned.data(), old_data);
}
// A copyable and movable value class, used to test that elements' copy
// and move methods are called correctly.
class Value {
public:
explicit Value(int v) : value_(MakeUnique<int>(v)) {}
// copyable
Value(const Value& v) {
value_ = MakeUnique<int>(*v.value_);
copied_ = true;
}
Value& operator=(const Value& v) {
value_ = MakeUnique<int>(*v.value_);
copied_ = true;
return *this;
}
// movable
Value(Value&& v) {
value_ = std::move(v.value_);
moved_ = true;
}
Value& operator=(Value&& v) {
value_ = std::move(v.value_);
moved_ = true;
return *this;
}
const UniquePtr<int>& value() const { return value_; }
bool copied() const { return copied_; }
bool moved() const { return moved_; }
private:
UniquePtr<int> value_;
bool copied_ = false;
bool moved_ = false;
};
TEST(InlinedVectorTest, CopyConstructorCopiesElementsInlined) {
InlinedVector<Value, 1> v1;
v1.emplace_back(3);
InlinedVector<Value, 1> v2(v1);
EXPECT_EQ(v2.size(), 1UL);
EXPECT_EQ(*v2[0].value(), 3);
// Addresses should differ.
EXPECT_NE(v1[0].value().get(), v2[0].value().get());
EXPECT_TRUE(v2[0].copied());
}
TEST(InlinedVectorTest, CopyConstructorCopiesElementsAllocated) {
InlinedVector<Value, 1> v1;
v1.reserve(2);
v1.emplace_back(3);
v1.emplace_back(5);
InlinedVector<Value, 1> v2(v1);
EXPECT_EQ(v2.size(), 2UL);
EXPECT_EQ(*v2[0].value(), 3);
EXPECT_EQ(*v2[1].value(), 5);
// Addresses should differ.
EXPECT_NE(v1[0].value().get(), v2[0].value().get());
EXPECT_NE(v1[1].value().get(), v2[1].value().get());
EXPECT_TRUE(v2[0].copied());
EXPECT_TRUE(v2[1].copied());
}
TEST(InlinedVectorTest, CopyAssignmentCopiesElementsInlined) {
InlinedVector<Value, 1> v1;
v1.emplace_back(3);
InlinedVector<Value, 1> v2;
EXPECT_EQ(v2.size(), 0UL);
v2 = v1;
EXPECT_EQ(v2.size(), 1UL);
EXPECT_EQ(*v2[0].value(), 3);
// Addresses should differ.
EXPECT_NE(v1[0].value().get(), v2[0].value().get());
EXPECT_TRUE(v2[0].copied());
}
TEST(InlinedVectorTest, CopyAssignmentCopiesElementsAllocated) {
InlinedVector<Value, 1> v1;
v1.reserve(2);
v1.emplace_back(3);
v1.emplace_back(5);
InlinedVector<Value, 1> v2;
EXPECT_EQ(v2.size(), 0UL);
v2 = v1;
EXPECT_EQ(v2.size(), 2UL);
EXPECT_EQ(*v2[0].value(), 3);
EXPECT_EQ(*v2[1].value(), 5);
// Addresses should differ.
EXPECT_NE(v1[0].value().get(), v2[0].value().get());
EXPECT_NE(v1[1].value().get(), v2[1].value().get());
EXPECT_TRUE(v2[0].copied());
EXPECT_TRUE(v2[1].copied());
}
TEST(InlinedVectorTest, MoveConstructorMovesElementsInlined) {
InlinedVector<Value, 1> v1;
v1.emplace_back(3);
int* addr = v1[0].value().get();
InlinedVector<Value, 1> v2(std::move(v1));
EXPECT_EQ(v2.size(), 1UL);
EXPECT_EQ(*v2[0].value(), 3);
EXPECT_EQ(addr, v2[0].value().get());
EXPECT_TRUE(v2[0].moved());
}
TEST(InlinedVectorTest, MoveConstructorMovesElementsAllocated) {
InlinedVector<Value, 1> v1;
v1.reserve(2);
v1.emplace_back(3);
v1.emplace_back(5);
int* addr1 = v1[0].value().get();
int* addr2 = v1[1].value().get();
Value* data1 = v1.data();
InlinedVector<Value, 1> v2(std::move(v1));
EXPECT_EQ(v2.size(), 2UL);
EXPECT_EQ(*v2[0].value(), 3);
EXPECT_EQ(*v2[1].value(), 5);
EXPECT_EQ(addr1, v2[0].value().get());
EXPECT_EQ(addr2, v2[1].value().get());
// In this case, elements won't be moved, because we have just stolen
// the underlying storage.
EXPECT_EQ(data1, v2.data());
}
TEST(InlinedVectorTest, MoveAssignmentMovesElementsInlined) {
InlinedVector<Value, 1> v1;
v1.emplace_back(3);
int* addr = v1[0].value().get();
InlinedVector<Value, 1> v2;
EXPECT_EQ(v2.size(), 0UL);
v2 = std::move(v1);
EXPECT_EQ(v2.size(), 1UL);
EXPECT_EQ(*v2[0].value(), 3);
EXPECT_EQ(addr, v2[0].value().get());
EXPECT_TRUE(v2[0].moved());
}
TEST(InlinedVectorTest, MoveAssignmentMovesElementsAllocated) {
InlinedVector<Value, 1> v1;
v1.reserve(2);
v1.emplace_back(3);
v1.emplace_back(5);
int* addr1 = v1[0].value().get();
int* addr2 = v1[1].value().get();
Value* data1 = v1.data();
InlinedVector<Value, 1> v2;
EXPECT_EQ(v2.size(), 0UL);
v2 = std::move(v1);
EXPECT_EQ(v2.size(), 2UL);
EXPECT_EQ(*v2[0].value(), 3);
EXPECT_EQ(*v2[1].value(), 5);
EXPECT_EQ(addr1, v2[0].value().get());
EXPECT_EQ(addr2, v2[1].value().get());
// In this case, elements won't be moved, because we have just stolen
// the underlying storage.
EXPECT_EQ(data1, v2.data());
}
TEST(InlinedVectorTest, PopBackInlined) {
InlinedVector<UniquePtr<int>, 2> v;
// Add two elements, pop one out

@ -40,7 +40,7 @@ grpc_cc_library(
grpc_cc_test(
name = "combiner_test",
srcs = ["combiner_test.cc"],
data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
language = "C++",
deps = [
"//:gpr",

@ -553,10 +553,11 @@ class GrpclbEnd2endTest : public ::testing::Test {
return status;
}
void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000) {
void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000,
bool wait_for_ready = false) {
for (size_t i = 0; i < times; ++i) {
EchoResponse response;
const Status status = SendRpc(&response, timeout_ms);
const Status status = SendRpc(&response, timeout_ms, wait_for_ready);
EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
<< " message=" << status.error_message();
EXPECT_EQ(response.message(), kRequestMessage_);
@ -717,10 +718,9 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
ScheduleResponseForBalancer(
0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}),
kServerlistDelayMs);
const auto t0 = system_clock::now();
// Client will block: LB will initially send empty serverlist.
CheckRpcSendOk(1, kCallDeadlineMs);
CheckRpcSendOk(1, kCallDeadlineMs, true /* wait_for_ready */);
const auto ellapsed_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(
system_clock::now() - t0);

@ -94,6 +94,7 @@ static const grpc_event_engine_vtable* init_engine_vtable(bool) {
g_vtable.pollset_destroy = pollset_destroy;
g_vtable.pollset_work = pollset_work;
g_vtable.pollset_kick = pollset_kick;
g_vtable.shutdown_background_closure = [] {};
g_vtable.shutdown_engine = [] {};
return &g_vtable;

@ -170,7 +170,7 @@ grpc_cc_test(
grpc_cc_test(
name = "qps_openloop_test",
srcs = ["qps_openloop_test.cc"],
data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
deps = [
":benchmark_config",
":driver_impl",

@ -16,37 +16,72 @@ licenses(["notice"]) # Apache v2
package(default_visibility = ["//visibility:public"])
exports_files(["RBE_USE_MACHINE_TYPE_LARGE",])
# Latest RBE Ubuntu16_04 container
# Update every time when a new container is released.
alias(
name = "rbe_ubuntu1604",
actual = ":rbe_ubuntu1604_r328903",
actual = ":rbe_ubuntu1604_r342117",
)
alias(
name = "rbe_ubuntu1604_large",
actual = ":rbe_ubuntu1604_r342117_large",
)
# RBE Ubuntu16_04 r328903
# RBE Ubuntu16_04 r342117
platform(
name = "rbe_ubuntu1604_r328903",
name = "rbe_ubuntu1604_r342117",
constraint_values = [
"@bazel_tools//platforms:x86_64",
"@bazel_tools//platforms:linux",
"@bazel_tools//tools/cpp:clang",
"@com_github_bazelbuild_bazeltoolchains//constraints:xenial",
"@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan",
"//third_party/toolchains/machine_size:standard",
],
remote_execution_properties = """
properties: {
name: "container-image"
value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:59bf0e191a6b5cc1ab62c2224c810681d1326bad5a27b1d36c9f40113e79da7f"
value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375"
}
properties: {
name: "gceMachineType" # Small machines for majority of tests.
value: "n1-highmem-2"
}
""",
)
# RBE Ubuntu16_04 r342117 large
platform(
name = "rbe_ubuntu1604_r342117_large",
constraint_values = [
"@bazel_tools//platforms:x86_64",
"@bazel_tools//platforms:linux",
"@bazel_tools//tools/cpp:clang",
"@com_github_bazelbuild_bazeltoolchains//constraints:xenial",
"@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan",
"//third_party/toolchains/machine_size:large",
],
remote_execution_properties = """
properties: {
name: "container-image"
value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375"
}
properties: {
name: "gceMachineType_LARGE" # Large machines for a small set of resource-consuming tests such as combiner_tests under TSAN.
name: "gceMachineType" # Large machines for some resource demanding tests (TSAN).
value: "n1-standard-8"
}
""",
""",
)
# This target is auto-generated from release/cpp.tpl and should not be
# modified directly.
toolchain(
name = "cc-toolchain-clang-x86_64-default",
exec_compatible_with = [
],
target_compatible_with = [
],
toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)

@ -1 +0,0 @@
# This file is a sentinel and is meant to be empty.

@ -0,0 +1,31 @@
# Copyright 2018 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"]) # Apache v2
package(default_visibility = ["//visibility:public"])
constraint_setting(name = "machine_size")
constraint_value(
name = "large",
constraint_setting = ":machine_size",
)
constraint_value(
name = "standard",
constraint_setting = ":machine_size",
)
# Add other constraint values as needed (tiny, huge, etc.) in the future.

1
third_party/upb vendored

@ -0,0 +1 @@
Subproject commit 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3

@ -777,6 +777,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \

@ -777,6 +777,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \

@ -784,6 +784,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \

@ -784,6 +784,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \

@ -18,10 +18,10 @@
startup --host_jvm_args=-Dbazel.DigestFunction=SHA256
build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain
build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default
build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain
build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-default
# Use custom execution platforms defined in third_party/toolchains
build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604
build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large
build --host_platform=//third_party/toolchains:rbe_ubuntu1604
build --platforms=//third_party/toolchains:rbe_ubuntu1604
@ -61,9 +61,9 @@ build:msan --cxxopt=--stdlib=libc++
# setting LD_LIBRARY_PATH is necessary
# to avoid "libc++.so.1: cannot open shared object file"
build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib
build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain
build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain
# override the config-agnostic crosstool_top
build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/msan:toolchain
build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain
# thread sanitizer: most settings are already in %workspace%/.bazelrc
# we only need a few additional ones that are Foundry specific
@ -71,6 +71,7 @@ build:tsan --copt=-gmlt
# TODO(jtattermusch): use more reasonable test timeout
build:tsan --test_timeout=3600
build:tsan --test_tag_filters=-qps_json_driver
build:tsan --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large
# undefined behavior sanitizer: most settings are already in %workspace%/.bazelrc
# we only need a few additional ones that are Foundry specific
@ -78,7 +79,7 @@ build:ubsan --copt=-gmlt
# TODO(jtattermusch): use more reasonable test timeout
build:ubsan --test_timeout=3600
# override the config-agnostic crosstool_top
--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.16.1/ubsan:toolchain
--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain
# TODO(jtattermusch): remove this once Foundry adds the env to the docker image.
# ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work
# and we get test failures.

@ -42,6 +42,7 @@ _ZOPEFOUNDATION_ZOPE_INTERFACE_DEP_NAME = 'com_github_zopefoundation_zope_interf
_TWISTED_CONSTANTLY_DEP_NAME = 'com_github_twisted_constantly'
_GRPC_DEP_NAMES = [
'upb',
'boringssl',
'com_github_madler_zlib',
'com_google_protobuf',

@ -40,6 +40,7 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules"
9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60)
48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 third_party/protobuf (v3.6.0.1-37-g48cb18e5)
e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10)
9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3 third_party/upb (heads/upbc-cpp)
cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
EOF

Loading…
Cancel
Save