summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam A. Kennington III <wak@google.com>2018-07-17 14:40:14 -0700
committerWilliam A. Kennington III <wak@google.com>2018-07-17 14:40:14 -0700
commit1744c165f01a5a3861312abe9267c3156c9db71e (patch)
treeb0c5b0d7ad143625a7c286a41d1f4bf6eb749243
parente3de31b984401336a8ec02aba83a0fece7d79a60 (diff)
downloadsdeventplus-1744c165f01a5a3861312abe9267c3156c9db71e.tar.gz
sdeventplus-1744c165f01a5a3861312abe9267c3156c9db71e.zip
sdref: Moves should actually invalidate the reference
This also makes it possible to use in boolean expressions to check validity.
-rw-r--r--src/sdeventplus/internal/sdref.cpp15
-rw-r--r--src/sdeventplus/internal/sdref.hpp3
-rw-r--r--test/internal/sdref.cpp41
3 files changed, 58 insertions, 1 deletions
diff --git a/src/sdeventplus/internal/sdref.cpp b/src/sdeventplus/internal/sdref.cpp
index 47faa87..add6b90 100644
--- a/src/sdeventplus/internal/sdref.cpp
+++ b/src/sdeventplus/internal/sdref.cpp
@@ -49,6 +49,14 @@ SdRef<T>& SdRef<T>::operator=(const SdRef& other)
}
template <typename T>
+SdRef<T>::SdRef(SdRef&& other) :
+ sdevent(std::move(other.sdevent)), take_ref(std::move(other.take_ref)),
+ release_ref(std::move(other.release_ref)), ref(std::move(other.ref))
+{
+ other.ref = nullptr;
+}
+
+template <typename T>
SdRef<T>& SdRef<T>::operator=(SdRef&& other)
{
if (this != &other)
@@ -63,6 +71,7 @@ SdRef<T>& SdRef<T>::operator=(SdRef&& other)
take_ref = std::move(other.take_ref);
release_ref = std::move(other.release_ref);
ref = std::move(other.ref);
+ other.ref = nullptr;
}
return *this;
}
@@ -76,6 +85,12 @@ SdRef<T>::~SdRef()
}
template <typename T>
+SdRef<T>::operator bool() const
+{
+ return ref != nullptr;
+}
+
+template <typename T>
T* SdRef<T>::get() const
{
return ref;
diff --git a/src/sdeventplus/internal/sdref.hpp b/src/sdeventplus/internal/sdref.hpp
index c0c77fc..12e395f 100644
--- a/src/sdeventplus/internal/sdref.hpp
+++ b/src/sdeventplus/internal/sdref.hpp
@@ -23,9 +23,10 @@ class SdRef
SdRef(const SdRef& other);
SdRef& operator=(const SdRef& other);
- SdRef(SdRef&& other) = default;
+ SdRef(SdRef&& other);
SdRef& operator=(SdRef&& other);
+ explicit operator bool() const;
T* get() const;
private:
diff --git a/test/internal/sdref.cpp b/test/internal/sdref.cpp
index 190d388..3b261d5 100644
--- a/test/internal/sdref.cpp
+++ b/test/internal/sdref.cpp
@@ -28,6 +28,7 @@ TEST_F(SdRefTest, ConstructRef)
.WillOnce(testing::Return(expected_event));
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
@@ -38,6 +39,7 @@ TEST_F(SdRefTest, ConstructNoRef)
{
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
@@ -48,11 +50,15 @@ TEST_F(SdRefTest, CopyConstruct)
{
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
EXPECT_CALL(mock, sd_event_ref(expected_event))
.WillOnce(testing::Return(expected_event));
SdRef<sd_event> event2(event);
+ EXPECT_TRUE(event);
+ EXPECT_EQ(expected_event, event.get());
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event, event2.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
@@ -64,9 +70,13 @@ TEST_F(SdRefTest, MoveConstruct)
{
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
SdRef<sd_event> event2(std::move(event));
+ EXPECT_FALSE(event);
+ EXPECT_EQ(nullptr, event.get());
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event, event2.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
@@ -77,9 +87,11 @@ TEST_F(SdRefTest, CopyAssignOverValid)
{
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock2);
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event2, event2.get());
EXPECT_CALL(mock2, sd_event_unref(expected_event2))
@@ -87,6 +99,9 @@ TEST_F(SdRefTest, CopyAssignOverValid)
EXPECT_CALL(mock, sd_event_ref(expected_event))
.WillOnce(testing::Return(expected_event));
event2 = event;
+ EXPECT_TRUE(event);
+ EXPECT_EQ(expected_event, event.get());
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event, event2.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
@@ -98,12 +113,17 @@ TEST_F(SdRefTest, CopyAssignOverMoved)
{
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock2);
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event2, event2.get());
{
SdRef<sd_event> event_mover(std::move(event2));
+ EXPECT_FALSE(event2);
+ EXPECT_EQ(nullptr, event2.get());
+ EXPECT_TRUE(event_mover);
EXPECT_EQ(expected_event2, event_mover.get());
EXPECT_CALL(mock2, sd_event_unref(expected_event2))
@@ -113,6 +133,9 @@ TEST_F(SdRefTest, CopyAssignOverMoved)
EXPECT_CALL(mock, sd_event_ref(expected_event))
.WillOnce(testing::Return(expected_event));
event2 = event;
+ EXPECT_TRUE(event);
+ EXPECT_EQ(expected_event, event.get());
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event, event2.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
@@ -124,9 +147,12 @@ TEST_F(SdRefTest, CopySelf)
{
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
event = event;
+ EXPECT_TRUE(event);
+ EXPECT_EQ(expected_event, event.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
.WillOnce(testing::Return(nullptr));
}
@@ -135,14 +161,19 @@ TEST_F(SdRefTest, MoveAssignOverValid)
{
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock2);
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event2, event2.get());
EXPECT_CALL(mock2, sd_event_unref(expected_event2))
.WillOnce(testing::Return(nullptr));
event2 = std::move(event);
+ EXPECT_FALSE(event);
+ EXPECT_EQ(nullptr, event.get());
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event, event2.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
@@ -159,6 +190,9 @@ TEST_F(SdRefTest, MoveAssignOverMoved)
EXPECT_EQ(expected_event2, event2.get());
{
SdRef<sd_event> event_mover(std::move(event2));
+ EXPECT_FALSE(event2);
+ EXPECT_EQ(nullptr, event2.get());
+ EXPECT_TRUE(event_mover);
EXPECT_EQ(expected_event2, event_mover.get());
EXPECT_CALL(mock2, sd_event_unref(expected_event2))
@@ -166,6 +200,9 @@ TEST_F(SdRefTest, MoveAssignOverMoved)
}
event2 = std::move(event);
+ EXPECT_FALSE(event);
+ EXPECT_EQ(nullptr, event.get());
+ EXPECT_TRUE(event2);
EXPECT_EQ(expected_event, event2.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
@@ -176,8 +213,12 @@ TEST_F(SdRefTest, MoveSelf)
{
SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref,
&SdEvent::sd_event_unref, std::false_type(), &mock);
+ EXPECT_TRUE(event);
EXPECT_EQ(expected_event, event.get());
+
event = std::move(event);
+ EXPECT_TRUE(event);
+ EXPECT_EQ(expected_event, event.get());
EXPECT_CALL(mock, sd_event_unref(expected_event))
.WillOnce(testing::Return(nullptr));
}
OpenPOWER on IntegriCloud