[event_engine] Add SliceCast (#31831)

* [event_engine] Add SliceCast

* Automated change: Fix sanity tests

* windows-fix

* comments

* comments

* comments

* build-fix

* fix

* Update port_platform.h

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
pull/31923/head
Craig Tiller 2 years ago committed by GitHub
parent 580569358f
commit 72c296a3c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      BUILD
  2. 3
      CMakeLists.txt
  3. 2
      Makefile
  4. 3
      build_autogenerated.yaml
  5. 1
      gRPC-Core.podspec
  6. 1
      grpc.gemspec
  7. 55
      include/grpc/event_engine/internal/slice_cast.h
  8. 13
      include/grpc/event_engine/slice.h
  9. 6
      include/grpc/event_engine/slice_buffer.h
  10. 13
      include/grpc/support/port_platform.h
  11. 1
      package.xml
  12. 9
      src/core/BUILD
  13. 24
      src/core/lib/slice/slice.h
  14. 5
      src/core/lib/slice/slice_buffer.h
  15. 9
      test/core/slice/slice_test.cc
  16. 2
      tools/buildgen/plugins/list_api.py
  17. 1
      tools/doxygen/Doxyfile.c++
  18. 1
      tools/doxygen/Doxyfile.c++.internal
  19. 1
      tools/doxygen/Doxyfile.core
  20. 1
      tools/doxygen/Doxyfile.core.internal

@ -229,6 +229,7 @@ GRPC_PUBLIC_EVENT_ENGINE_HDRS = [
"include/grpc/event_engine/internal/memory_allocator_impl.h", "include/grpc/event_engine/internal/memory_allocator_impl.h",
"include/grpc/event_engine/slice.h", "include/grpc/event_engine/slice.h",
"include/grpc/event_engine/slice_buffer.h", "include/grpc/event_engine/slice_buffer.h",
"include/grpc/event_engine/internal/slice_cast.h",
] ]
GRPCXX_SRCS = [ GRPCXX_SRCS = [
@ -1423,6 +1424,7 @@ grpc_cc_library(
"//src/core:resource_quota_trace", "//src/core:resource_quota_trace",
"//src/core:slice", "//src/core:slice",
"//src/core:slice_buffer", "//src/core:slice_buffer",
"//src/core:slice_cast",
"//src/core:slice_refcount", "//src/core:slice_refcount",
"//src/core:socket_mutator", "//src/core:socket_mutator",
"//src/core:stats_data", "//src/core:stats_data",

3
CMakeLists.txt generated

@ -2463,6 +2463,7 @@ foreach(_hdr
include/grpc/event_engine/endpoint_config.h include/grpc/event_engine/endpoint_config.h
include/grpc/event_engine/event_engine.h include/grpc/event_engine/event_engine.h
include/grpc/event_engine/internal/memory_allocator_impl.h include/grpc/event_engine/internal/memory_allocator_impl.h
include/grpc/event_engine/internal/slice_cast.h
include/grpc/event_engine/memory_allocator.h include/grpc/event_engine/memory_allocator.h
include/grpc/event_engine/memory_request.h include/grpc/event_engine/memory_request.h
include/grpc/event_engine/port.h include/grpc/event_engine/port.h
@ -3073,6 +3074,7 @@ foreach(_hdr
include/grpc/event_engine/endpoint_config.h include/grpc/event_engine/endpoint_config.h
include/grpc/event_engine/event_engine.h include/grpc/event_engine/event_engine.h
include/grpc/event_engine/internal/memory_allocator_impl.h include/grpc/event_engine/internal/memory_allocator_impl.h
include/grpc/event_engine/internal/slice_cast.h
include/grpc/event_engine/memory_allocator.h include/grpc/event_engine/memory_allocator.h
include/grpc/event_engine/memory_request.h include/grpc/event_engine/memory_request.h
include/grpc/event_engine/port.h include/grpc/event_engine/port.h
@ -4539,6 +4541,7 @@ foreach(_hdr
include/grpc/event_engine/endpoint_config.h include/grpc/event_engine/endpoint_config.h
include/grpc/event_engine/event_engine.h include/grpc/event_engine/event_engine.h
include/grpc/event_engine/internal/memory_allocator_impl.h include/grpc/event_engine/internal/memory_allocator_impl.h
include/grpc/event_engine/internal/slice_cast.h
include/grpc/event_engine/memory_allocator.h include/grpc/event_engine/memory_allocator.h
include/grpc/event_engine/memory_request.h include/grpc/event_engine/memory_request.h
include/grpc/event_engine/port.h include/grpc/event_engine/port.h

2
Makefile generated

@ -1680,6 +1680,7 @@ PUBLIC_HEADERS_C += \
include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/endpoint_config.h \
include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/event_engine.h \
include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \
include/grpc/event_engine/internal/slice_cast.h \
include/grpc/event_engine/memory_allocator.h \ include/grpc/event_engine/memory_allocator.h \
include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/memory_request.h \
include/grpc/event_engine/port.h \ include/grpc/event_engine/port.h \
@ -2150,6 +2151,7 @@ PUBLIC_HEADERS_C += \
include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/endpoint_config.h \
include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/event_engine.h \
include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \
include/grpc/event_engine/internal/slice_cast.h \
include/grpc/event_engine/memory_allocator.h \ include/grpc/event_engine/memory_allocator.h \
include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/memory_request.h \
include/grpc/event_engine/port.h \ include/grpc/event_engine/port.h \

@ -260,6 +260,7 @@ libs:
- include/grpc/event_engine/endpoint_config.h - include/grpc/event_engine/endpoint_config.h
- include/grpc/event_engine/event_engine.h - include/grpc/event_engine/event_engine.h
- include/grpc/event_engine/internal/memory_allocator_impl.h - include/grpc/event_engine/internal/memory_allocator_impl.h
- include/grpc/event_engine/internal/slice_cast.h
- include/grpc/event_engine/memory_allocator.h - include/grpc/event_engine/memory_allocator.h
- include/grpc/event_engine/memory_request.h - include/grpc/event_engine/memory_request.h
- include/grpc/event_engine/port.h - include/grpc/event_engine/port.h
@ -1859,6 +1860,7 @@ libs:
- include/grpc/event_engine/endpoint_config.h - include/grpc/event_engine/endpoint_config.h
- include/grpc/event_engine/event_engine.h - include/grpc/event_engine/event_engine.h
- include/grpc/event_engine/internal/memory_allocator_impl.h - include/grpc/event_engine/internal/memory_allocator_impl.h
- include/grpc/event_engine/internal/slice_cast.h
- include/grpc/event_engine/memory_allocator.h - include/grpc/event_engine/memory_allocator.h
- include/grpc/event_engine/memory_request.h - include/grpc/event_engine/memory_request.h
- include/grpc/event_engine/port.h - include/grpc/event_engine/port.h
@ -3383,6 +3385,7 @@ libs:
- include/grpc/event_engine/endpoint_config.h - include/grpc/event_engine/endpoint_config.h
- include/grpc/event_engine/event_engine.h - include/grpc/event_engine/event_engine.h
- include/grpc/event_engine/internal/memory_allocator_impl.h - include/grpc/event_engine/internal/memory_allocator_impl.h
- include/grpc/event_engine/internal/slice_cast.h
- include/grpc/event_engine/memory_allocator.h - include/grpc/event_engine/memory_allocator.h
- include/grpc/event_engine/memory_request.h - include/grpc/event_engine/memory_request.h
- include/grpc/event_engine/port.h - include/grpc/event_engine/port.h

1
gRPC-Core.podspec generated

@ -111,6 +111,7 @@ Pod::Spec.new do |s|
'include/grpc/event_engine/endpoint_config.h', 'include/grpc/event_engine/endpoint_config.h',
'include/grpc/event_engine/event_engine.h', 'include/grpc/event_engine/event_engine.h',
'include/grpc/event_engine/internal/memory_allocator_impl.h', 'include/grpc/event_engine/internal/memory_allocator_impl.h',
'include/grpc/event_engine/internal/slice_cast.h',
'include/grpc/event_engine/memory_allocator.h', 'include/grpc/event_engine/memory_allocator.h',
'include/grpc/event_engine/memory_request.h', 'include/grpc/event_engine/memory_request.h',
'include/grpc/event_engine/port.h', 'include/grpc/event_engine/port.h',

1
grpc.gemspec generated

@ -54,6 +54,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/event_engine/endpoint_config.h ) s.files += %w( include/grpc/event_engine/endpoint_config.h )
s.files += %w( include/grpc/event_engine/event_engine.h ) s.files += %w( include/grpc/event_engine/event_engine.h )
s.files += %w( include/grpc/event_engine/internal/memory_allocator_impl.h ) s.files += %w( include/grpc/event_engine/internal/memory_allocator_impl.h )
s.files += %w( include/grpc/event_engine/internal/slice_cast.h )
s.files += %w( include/grpc/event_engine/memory_allocator.h ) s.files += %w( include/grpc/event_engine/memory_allocator.h )
s.files += %w( include/grpc/event_engine/memory_request.h ) s.files += %w( include/grpc/event_engine/memory_request.h )
s.files += %w( include/grpc/event_engine/port.h ) s.files += %w( include/grpc/event_engine/port.h )

@ -0,0 +1,55 @@
// Copyright 2022 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.
#ifndef GRPC_EVENT_ENGINE_INTERNAL_SLICE_CAST_H
#define GRPC_EVENT_ENGINE_INTERNAL_SLICE_CAST_H
namespace grpc_event_engine {
namespace experimental {
namespace internal {
// Opt-in trait class for slice conversions.
// Declare a specialization of this class for any types that are compatible
// with `SliceCast`. Both ways need to be declared (i.e. if
// ConstRefSliceCastable<A,B> exists, you should declare
// ConstRefSliceCastable<B,A> too).
// The type has no members, it's just the existance of the specialization that
// unlocks SliceCast usage for a type pair.
template <typename Result, typename T>
struct ConstRefSliceCastable;
// This is strictly too wide, but consider all types to be SliceCast-able to
// themselves.
// Unfortunately this allows `const int& x = SliceCast<int>(x);` which is kind
// of bogus.
template <typename A>
struct ConstRefSliceCastable<A, A> {};
// Cast to `const Result&` from `const T&` without any runtime checks.
// This is only valid if `sizeof(Result) == sizeof(T)`, and if `Result`, `T` are
// opted in as compatible via `ConstRefSliceCastable`.
template <typename Result, typename T>
const Result& SliceCast(const T& value, ConstRefSliceCastable<Result, T> = {}) {
// Insist upon sizes being equal to catch mismatches.
// We assume if sizes are opted in and sizes are equal then yes, these two
// types are expected to be layout compatible and actually appear to be.
static_assert(sizeof(Result) == sizeof(T), "size mismatch");
return reinterpret_cast<const Result&>(value);
}
} // namespace internal
} // namespace experimental
} // namespace grpc_event_engine
#endif // GRPC_EVENT_ENGINE_INTERNAL_SLICE_CAST_H

@ -25,6 +25,7 @@
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include <grpc/event_engine/internal/slice_cast.h>
#include <grpc/slice.h> #include <grpc/slice.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
@ -212,8 +213,9 @@ class MutableSlice : public slice_detail::BaseSlice,
uint8_t& operator[](size_t i) { return mutable_data()[i]; } uint8_t& operator[](size_t i) { return mutable_data()[i]; }
}; };
class Slice : public slice_detail::BaseSlice, class GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND Slice
public slice_detail::CopyConstructors<Slice> { : public slice_detail::BaseSlice,
public slice_detail::CopyConstructors<Slice> {
public: public:
Slice() = default; Slice() = default;
~Slice(); ~Slice();
@ -280,6 +282,13 @@ class Slice : public slice_detail::BaseSlice,
const uint8_t* begin, const uint8_t* end); const uint8_t* begin, const uint8_t* end);
}; };
namespace internal {
template <>
struct ConstRefSliceCastable<Slice, grpc_slice> {};
template <>
struct ConstRefSliceCastable<grpc_slice, Slice> {};
} // namespace internal
} // namespace experimental } // namespace experimental
} // namespace grpc_event_engine } // namespace grpc_event_engine

@ -25,7 +25,9 @@
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/utility/utility.h" #include "absl/utility/utility.h"
#include <grpc/event_engine/internal/slice_cast.h>
#include <grpc/event_engine/slice.h> #include <grpc/event_engine/slice.h>
#include <grpc/impl/codegen/slice.h>
#include <grpc/slice.h> #include <grpc/slice.h>
#include <grpc/slice_buffer.h> #include <grpc/slice_buffer.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
@ -117,6 +119,10 @@ class SliceBuffer {
/// associated slice. /// associated slice.
Slice RefSlice(size_t index); Slice RefSlice(size_t index);
const Slice& operator[](size_t index) const {
return internal::SliceCast<Slice>(slice_buffer_.slices[index]);
}
/// The total number of bytes held by the SliceBuffer /// The total number of bytes held by the SliceBuffer
size_t Length() { return slice_buffer_.length; } size_t Length() { return slice_buffer_.length; }

@ -761,6 +761,19 @@ extern void gpr_unreachable_code(const char* reason, const char* file,
#define __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS
#endif #endif
/* MSVC doesn't do the empty base class optimization in debug builds by default,
* and because of ABI likely won't.
* This enables it for specific types, use as:
* class GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND Foo : public A, public B, public C
* {}; */
#ifndef GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND
#ifdef GPR_WINDOWS
#define GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND __declspec(empty_bases)
#else
#define GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND
#endif
#endif
#define GRPC_CALLBACK_API_NONEXPERIMENTAL #define GRPC_CALLBACK_API_NONEXPERIMENTAL
/* clang 11 with msan miscompiles destruction of [[no_unique_address]] members /* clang 11 with msan miscompiles destruction of [[no_unique_address]] members

1
package.xml generated

@ -36,6 +36,7 @@
<file baseinstalldir="/" name="include/grpc/event_engine/endpoint_config.h" role="src" /> <file baseinstalldir="/" name="include/grpc/event_engine/endpoint_config.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/event_engine.h" role="src" /> <file baseinstalldir="/" name="include/grpc/event_engine/event_engine.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/internal/memory_allocator_impl.h" role="src" /> <file baseinstalldir="/" name="include/grpc/event_engine/internal/memory_allocator_impl.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/internal/slice_cast.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/memory_allocator.h" role="src" /> <file baseinstalldir="/" name="include/grpc/event_engine/memory_allocator.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/memory_request.h" role="src" /> <file baseinstalldir="/" name="include/grpc/event_engine/memory_request.h" role="src" />
<file baseinstalldir="/" name="include/grpc/event_engine/port.h" role="src" /> <file baseinstalldir="/" name="include/grpc/event_engine/port.h" role="src" />

@ -44,6 +44,13 @@ grpc_cc_library(
language = "c++", language = "c++",
) )
grpc_cc_library(
name = "slice_cast",
hdrs = [
"//:include/grpc/event_engine/internal/slice_cast.h",
],
)
grpc_cc_library( grpc_cc_library(
name = "event_engine_common", name = "event_engine_common",
srcs = [ srcs = [
@ -65,6 +72,7 @@ grpc_cc_library(
deps = [ deps = [
"slice", "slice",
"slice_buffer", "slice_buffer",
"slice_cast",
"slice_refcount", "slice_refcount",
"//:event_engine_base_hdrs", "//:event_engine_base_hdrs",
"//:gpr", "//:gpr",
@ -1109,6 +1117,7 @@ grpc_cc_library(
], ],
visibility = ["@grpc:alt_grpc_base_legacy"], visibility = ["@grpc:alt_grpc_base_legacy"],
deps = [ deps = [
"slice_cast",
"slice_refcount", "slice_refcount",
"//:event_engine_base_hdrs", "//:event_engine_base_hdrs",
"//:gpr", "//:gpr",

@ -25,6 +25,8 @@
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include <grpc/event_engine/internal/slice_cast.h>
#include <grpc/event_engine/slice.h>
#include <grpc/slice.h> #include <grpc/slice.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
@ -295,9 +297,10 @@ class MutableSlice : public slice_detail::BaseSlice,
uint8_t& operator[](size_t i) { return mutable_data()[i]; } uint8_t& operator[](size_t i) { return mutable_data()[i]; }
}; };
class Slice : public slice_detail::BaseSlice, class GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND Slice
public slice_detail::CopyConstructors<Slice>, : public slice_detail::BaseSlice,
public slice_detail::StaticConstructors<Slice> { public slice_detail::CopyConstructors<Slice>,
public slice_detail::StaticConstructors<Slice> {
public: public:
Slice() = default; Slice() = default;
~Slice() { CSliceUnref(c_slice()); } ~Slice() { CSliceUnref(c_slice()); }
@ -403,4 +406,19 @@ class Slice : public slice_detail::BaseSlice,
} // namespace grpc_core } // namespace grpc_core
namespace grpc_event_engine {
namespace experimental {
namespace internal {
template <>
struct ConstRefSliceCastable<grpc_core::Slice, grpc_slice> {};
template <>
struct ConstRefSliceCastable<grpc_slice, grpc_core::Slice> {};
template <>
struct ConstRefSliceCastable<grpc_core::Slice, Slice> {};
template <>
struct ConstRefSliceCastable<Slice, grpc_core::Slice> {};
} // namespace internal
} // namespace experimental
} // namespace grpc_event_engine
#endif // GRPC_CORE_LIB_SLICE_SLICE_H #endif // GRPC_CORE_LIB_SLICE_SLICE_H

@ -108,6 +108,11 @@ class SliceBuffer {
/// associated slice. /// associated slice.
Slice RefSlice(size_t index) const; Slice RefSlice(size_t index) const;
const Slice& operator[](size_t index) const {
return grpc_event_engine::experimental::internal::SliceCast<Slice>(
slice_buffer_.slices[index]);
}
/// The total number of bytes held by the SliceBuffer /// The total number of bytes held by the SliceBuffer
size_t Length() const { return slice_buffer_.length; } size_t Length() const { return slice_buffer_.length; }

@ -432,6 +432,15 @@ TEST(SliceTest, LetsGetMutable) {
EXPECT_EQ(slice.as_string_view(), "ifnmp"); EXPECT_EQ(slice.as_string_view(), "ifnmp");
} }
TEST(SliceTest, SliceCastWorks) {
using ::grpc_event_engine::experimental::internal::SliceCast;
Slice test = Slice::FromCopiedString("hello world!");
const grpc_slice& slice = SliceCast<grpc_slice>(test);
EXPECT_EQ(&slice, &test.c_slice());
const Slice& other = SliceCast<Slice>(slice);
EXPECT_EQ(&other, &test);
}
} // namespace } // namespace
} // namespace grpc_core } // namespace grpc_core

@ -22,7 +22,7 @@ import sys
import yaml import yaml
_RE_API = r'(?:GPRAPI|GRPCAPI|CENSUSAPI)([^;]*);' _RE_API = r'(?:GPRAPI|GRPCAPI|CENSUSAPI)([^#;]*);'
def list_c_apis(filenames): def list_c_apis(filenames):

@ -882,6 +882,7 @@ include/grpc/compression.h \
include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/endpoint_config.h \
include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/event_engine.h \
include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \
include/grpc/event_engine/internal/slice_cast.h \
include/grpc/event_engine/memory_allocator.h \ include/grpc/event_engine/memory_allocator.h \
include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/memory_request.h \
include/grpc/event_engine/port.h \ include/grpc/event_engine/port.h \

@ -882,6 +882,7 @@ include/grpc/compression.h \
include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/endpoint_config.h \
include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/event_engine.h \
include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \
include/grpc/event_engine/internal/slice_cast.h \
include/grpc/event_engine/memory_allocator.h \ include/grpc/event_engine/memory_allocator.h \
include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/memory_request.h \
include/grpc/event_engine/port.h \ include/grpc/event_engine/port.h \

@ -814,6 +814,7 @@ include/grpc/compression.h \
include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/endpoint_config.h \
include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/event_engine.h \
include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \
include/grpc/event_engine/internal/slice_cast.h \
include/grpc/event_engine/memory_allocator.h \ include/grpc/event_engine/memory_allocator.h \
include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/memory_request.h \
include/grpc/event_engine/port.h \ include/grpc/event_engine/port.h \

@ -814,6 +814,7 @@ include/grpc/compression.h \
include/grpc/event_engine/endpoint_config.h \ include/grpc/event_engine/endpoint_config.h \
include/grpc/event_engine/event_engine.h \ include/grpc/event_engine/event_engine.h \
include/grpc/event_engine/internal/memory_allocator_impl.h \ include/grpc/event_engine/internal/memory_allocator_impl.h \
include/grpc/event_engine/internal/slice_cast.h \
include/grpc/event_engine/memory_allocator.h \ include/grpc/event_engine/memory_allocator.h \
include/grpc/event_engine/memory_request.h \ include/grpc/event_engine/memory_request.h \
include/grpc/event_engine/port.h \ include/grpc/event_engine/port.h \

Loading…
Cancel
Save