[promises] A few tweaks to poll (#32588)

Looking for something else I made some test additions, code tweaks to
make `Poll<>` better.

<!--

If you know who should review your pull request, please assign it to
that
person, otherwise the pull request would get assigned randomly.

If your pull request is for a specific language, please add the
appropriate
lang label.

-->
pull/32651/head
Craig Tiller 2 years ago committed by GitHub
parent 0011f7090f
commit ed0ebb837e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 48
      src/core/lib/promise/poll.h
  2. 22
      test/core/promise/poll_test.cc

@ -88,6 +88,8 @@ class Poll {
Poll(U value) : ready_(true) {
Construct(&value_, std::move(value));
}
// NOLINTNEXTLINE(google-explicit-constructor)
Poll(T&& value) : ready_(true) { Construct(&value_, std::forward<T>(value)); }
~Poll() {
if (ready_) Destruct(&value_);
}
@ -137,9 +139,55 @@ class Poll {
};
};
template <>
class Poll<Empty> {
public:
// NOLINTNEXTLINE(google-explicit-constructor)
Poll(Pending) : ready_(false) {}
Poll() : ready_(false) {}
Poll(const Poll& other) = default;
Poll(Poll&& other) noexcept = default;
Poll& operator=(const Poll& other) = default;
Poll& operator=(Poll&& other) = default;
// NOLINTNEXTLINE(google-explicit-constructor)
Poll(Empty) : ready_(true) {}
~Poll() = default;
bool pending() const { return !ready_; }
bool ready() const { return ready_; }
Empty value() const {
GPR_DEBUG_ASSERT(ready());
return Empty{};
}
Empty* value_if_ready() {
static Empty value;
if (ready()) return &value;
return nullptr;
}
const Empty* value_if_ready() const {
static Empty value;
if (ready()) return &value;
return nullptr;
}
private:
// Flag indicating readiness.
bool ready_;
};
// Ensure degenerate cases are not defined:
// Can't poll for a Pending
template <>
class Poll<Pending>;
// Can't poll for a poll
template <class T>
class Poll<Poll<T>>;
template <typename T>
bool operator==(const Poll<T>& a, const Poll<T>& b) {
if (a.pending() && b.pending()) return true;

@ -20,24 +20,46 @@
namespace grpc_core {
static_assert(sizeof(Poll<Empty>) == sizeof(bool),
"Poll<Empty> should be just a bool");
TEST(PollTest, IsItPoll) {
EXPECT_EQ(PollTraits<Poll<int>>::is_poll(), true);
EXPECT_EQ(PollTraits<Poll<bool>>::is_poll(), true);
EXPECT_EQ(PollTraits<Poll<Empty>>::is_poll(), true);
EXPECT_EQ(PollTraits<Poll<std::unique_ptr<int>>>::is_poll(), true);
EXPECT_EQ(PollTraits<int>::is_poll(), false);
EXPECT_EQ(PollTraits<bool>::is_poll(), false);
EXPECT_EQ(PollTraits<Empty>::is_poll(), false);
EXPECT_EQ(PollTraits<std::unique_ptr<int>>::is_poll(), false);
}
TEST(PollTest, Pending) {
Poll<int> i = Pending();
EXPECT_TRUE(i.pending());
Poll<Empty> j = Pending();
EXPECT_TRUE(j.pending());
}
TEST(PollTest, Ready) {
Poll<int> i = 1;
EXPECT_TRUE(i.ready());
EXPECT_EQ(i.value(), 1);
Poll<Empty> j = Empty();
EXPECT_TRUE(j.ready());
}
TEST(PollTest, CanMove) {
Poll<std::shared_ptr<int>> x = std::make_shared<int>(3);
Poll<std::shared_ptr<int>> y = std::make_shared<int>(4);
y = std::move(x);
Poll<std::shared_ptr<int>> z = std::move(y);
EXPECT_EQ(*z.value(), 3);
}
TEST(PollTest, ImplicitConstructor) {
Poll<std::shared_ptr<int>> x(std::make_unique<int>(3));
EXPECT_EQ(*x.value(), 3);
}
} // namespace grpc_core

Loading…
Cancel
Save