source/base: Support floating sources
This allows the source to stay attached to the event loop even if all of
the source handles are unreferenced.
Change-Id: I81e97674869ceba3e71479efa6ce38a67c0ba5c7
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/sdeventplus/source/base.cpp b/src/sdeventplus/source/base.cpp
index 6b80430..f4ed15b 100644
--- a/src/sdeventplus/source/base.cpp
+++ b/src/sdeventplus/source/base.cpp
@@ -92,6 +92,20 @@
event.getSdEvent(), get(), static_cast<int>(enabled));
}
+bool Base::get_floating() const
+{
+ return internal::callCheck("sd_event_source_get_floating",
+ &internal::SdEvent::sd_event_source_get_floating,
+ event.getSdEvent(), get());
+}
+
+void Base::set_floating(bool b) const
+{
+ internal::callCheck("sd_event_source_set_floating",
+ &internal::SdEvent::sd_event_source_set_floating,
+ event.getSdEvent(), get(), static_cast<int>(b));
+}
+
Base::Base(const Event& event, sd_event_source* source, std::false_type) :
event(event), source(std::move(source), event.getSdEvent(), true)
{
diff --git a/src/sdeventplus/source/base.hpp b/src/sdeventplus/source/base.hpp
index 2e4f48a..0807fb1 100644
--- a/src/sdeventplus/source/base.hpp
+++ b/src/sdeventplus/source/base.hpp
@@ -123,6 +123,22 @@
*/
void set_enabled(Enabled enabled) const;
+ /** @brief Determines the floating nature of the source
+ *
+ * @throws SdEventError for underlying sd_event errors
+ * @return The enabled status of the source
+ */
+ bool get_floating() const;
+
+ /** @brief Sets the floating nature of the source
+ * If set to true, the source will continue to run after the
+ * destruction of this handle.
+ *
+ * @param[in] b - Whether or not the source should float
+ * @throws SdEventError for underlying sd_event errors
+ */
+ void set_floating(bool b) const;
+
protected:
Event event;
diff --git a/test/source/base.cpp b/test/source/base.cpp
index 43e70ff..1b2ed1e 100644
--- a/test/source/base.cpp
+++ b/test/source/base.cpp
@@ -426,6 +426,37 @@
EXPECT_THROW(base->set_enabled(Enabled::OneShot), SdEventError);
}
+TEST_F(BaseMethodTest, GetFloatingSuccess)
+{
+ EXPECT_CALL(mock, sd_event_source_get_floating(expected_source))
+ .WillOnce(Return(2));
+ EXPECT_TRUE(base->get_floating());
+ EXPECT_CALL(mock, sd_event_source_get_floating(expected_source))
+ .WillOnce(Return(0));
+ EXPECT_FALSE(base->get_floating());
+}
+
+TEST_F(BaseMethodTest, GetFloatingError)
+{
+ EXPECT_CALL(mock, sd_event_source_get_floating(expected_source))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->get_floating(), SdEventError);
+}
+
+TEST_F(BaseMethodTest, SetFloatingSuccess)
+{
+ EXPECT_CALL(mock, sd_event_source_set_floating(expected_source, 1))
+ .WillOnce(Return(0));
+ base->set_floating(true);
+}
+
+TEST_F(BaseMethodTest, SetFloatingError)
+{
+ EXPECT_CALL(mock, sd_event_source_set_floating(expected_source, 1))
+ .WillOnce(Return(-EINVAL));
+ EXPECT_THROW(base->set_floating(true), SdEventError);
+}
+
} // namespace
} // namespace source
} // namespace sdeventplus