aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/grpc++/alarm.h21
-rw-r--r--test/cpp/common/alarm_cpp_test.cc19
2 files changed, 38 insertions, 2 deletions
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index bd000cf4f7..ed8dacbc94 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -52,8 +52,25 @@ class Alarm : private GrpcLibraryCodegen {
alarm_(grpc_alarm_create(cq->cq(), TimePoint<T>(deadline).raw_time(),
static_cast<void*>(&tag_))) {}
+ /// Alarms aren't copyable.
+ Alarm(const Alarm&) = delete;
+ Alarm& operator=(const Alarm&) = delete;
+
+ /// Alarms are movable.
+ Alarm(Alarm&& rhs) : tag_(rhs.tag_), alarm_(rhs.alarm_) {
+ rhs.alarm_ = nullptr;
+ }
+ Alarm& operator=(Alarm&& rhs) {
+ tag_ = rhs.tag_;
+ alarm_ = rhs.alarm_;
+ rhs.alarm_ = nullptr;
+ return *this;
+ }
+
/// Destroy the given completion queue alarm, cancelling it in the process.
- ~Alarm() { grpc_alarm_destroy(alarm_); }
+ ~Alarm() {
+ if (alarm_ != nullptr) grpc_alarm_destroy(alarm_);
+ }
/// Cancel a completion queue alarm. Calling this function over an alarm that
/// has already fired has no effect.
@@ -73,7 +90,7 @@ class Alarm : private GrpcLibraryCodegen {
};
AlarmEntry tag_;
- grpc_alarm* const alarm_; // owned
+ grpc_alarm* alarm_; // owned
};
} // namespace grpc
diff --git a/test/cpp/common/alarm_cpp_test.cc b/test/cpp/common/alarm_cpp_test.cc
index 3e4999994a..760dd7b956 100644
--- a/test/cpp/common/alarm_cpp_test.cc
+++ b/test/cpp/common/alarm_cpp_test.cc
@@ -40,6 +40,25 @@ TEST(AlarmTest, RegularExpiry) {
EXPECT_EQ(junk, output_tag);
}
+TEST(AlarmTest, Move) {
+ CompletionQueue cq;
+ void* junk = reinterpret_cast<void*>(1618033);
+ Alarm first(&cq, grpc_timeout_seconds_to_deadline(1), junk);
+ // Move constructor.
+ Alarm second(std::move(first));
+ // Moving assignment.
+ first = std::move(second);
+
+ void* output_tag;
+ bool ok;
+ const CompletionQueue::NextStatus status = cq.AsyncNext(
+ (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+
+ EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
+ EXPECT_TRUE(ok);
+ EXPECT_EQ(junk, output_tag);
+}
+
TEST(AlarmTest, RegularExpiryChrono) {
CompletionQueue cq;
void* junk = reinterpret_cast<void*>(1618033);