server/interface: simplify property_changed
The previous property_changed implementation created a dynamic vector to
hold two elements. Switch to std::array to simplify the code and
compiled function size.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ia2960fdd8b979ce9ccf661b013618de8d28f5e89
diff --git a/include/sdbusplus/sdbus.hpp b/include/sdbusplus/sdbus.hpp
index b30e989..25941da 100644
--- a/include/sdbusplus/sdbus.hpp
+++ b/include/sdbusplus/sdbus.hpp
@@ -46,7 +46,7 @@
virtual int sd_bus_emit_properties_changed_strv(sd_bus* bus,
const char* path,
const char* interface,
- char** names) = 0;
+ const char** names) = 0;
virtual int sd_bus_error_set(sd_bus_error* e, const char* name,
const char* message) = 0;
@@ -222,10 +222,19 @@
int sd_bus_emit_properties_changed_strv(sd_bus* bus, const char* path,
const char* interface,
- char** names) override
+ const char** names) override
{
return ::sd_bus_emit_properties_changed_strv(bus, path, interface,
- names);
+ const_cast<char**>(names));
+ // The const_cast above may seem unsafe, but it safe. sd_bus's manpage
+ // shows a 'const char*' but the header does not. I examined the code
+ // and no modification of the strings is done. I tried to change sdbus
+ // directly but due to quirks of C you cannot implicitly convert a
+ // 'char **' to a 'const char**', so changing the implementation causes
+ // lots of compile failures due to an incompatible API change.
+ //
+ // Performing a const_cast allows us to avoid a memory allocation of
+ // the contained strings in 'interface::property_changed'.
}
int sd_bus_error_set(sd_bus_error* e, const char* name,
diff --git a/include/sdbusplus/server/interface.hpp b/include/sdbusplus/server/interface.hpp
index acf4a09..eb55792 100644
--- a/include/sdbusplus/server/interface.hpp
+++ b/include/sdbusplus/server/interface.hpp
@@ -94,13 +94,12 @@
*/
void property_changed(const char* property)
{
- std::vector<std::string> values{property};
- sdbusplus::bus::details::Strv p(values);
+ std::array<const char*, 2> values = {property, nullptr};
// Note: Converting to use _strv version, could also mock two pointer
// use-case explicitly.
_intf->sd_bus_emit_properties_changed_strv(
- _bus.get(), _path.c_str(), _interf.c_str(), static_cast<char**>(p));
+ _bus.get(), _path.c_str(), _interf.c_str(), values.data());
}
/** @brief Emit the interface is added on D-Bus */
diff --git a/include/sdbusplus/test/sdbus_mock.hpp b/include/sdbusplus/test/sdbus_mock.hpp
index ff007a4..df312e2 100644
--- a/include/sdbusplus/test/sdbus_mock.hpp
+++ b/include/sdbusplus/test/sdbus_mock.hpp
@@ -30,7 +30,7 @@
MOCK_METHOD2(sd_bus_emit_object_added, int(sd_bus*, const char*));
MOCK_METHOD2(sd_bus_emit_object_removed, int(sd_bus*, const char*));
MOCK_METHOD4(sd_bus_emit_properties_changed_strv,
- int(sd_bus*, const char*, const char*, char**));
+ int(sd_bus*, const char*, const char*, const char**));
MOCK_METHOD3(sd_bus_error_set,
int(sd_bus_error*, const char*, const char*));