Extend stress tests with dynamic object creation and destruction in multiple threads

This commit is contained in:
Stanislav Angelovic
2019-04-04 20:39:31 +02:00
parent 94fd3c88d8
commit d154022205
10 changed files with 165 additions and 41 deletions

View File

@ -1,6 +1,6 @@
/*
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__celsius_thermometer_adaptor_h__adaptor__H__
@ -12,7 +12,7 @@
namespace org {
namespace sdbuscpp {
namespace stresstest {
namespace stresstests {
namespace celsius {
class thermometer_adaptor

View File

@ -1,6 +1,6 @@
/*
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__celsius_thermometer_proxy_h__proxy__H__
@ -12,7 +12,7 @@
namespace org {
namespace sdbuscpp {
namespace stresstest {
namespace stresstests {
namespace celsius {
class thermometer_proxy

View File

@ -1,6 +1,6 @@
/*
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__concatenator_adaptor_h__adaptor__H__
@ -12,7 +12,7 @@
namespace org {
namespace sdbuscpp {
namespace stresstest {
namespace stresstests {
class concatenator_adaptor
{

View File

@ -1,6 +1,6 @@
/*
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__concatenator_proxy_h__proxy__H__
@ -12,7 +12,7 @@
namespace org {
namespace sdbuscpp {
namespace stresstest {
namespace stresstests {
class concatenator_proxy
{

View File

@ -1,6 +1,6 @@
/*
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__fahrenheit_thermometer_adaptor_h__adaptor__H__
@ -12,7 +12,7 @@
namespace org {
namespace sdbuscpp {
namespace stresstest {
namespace stresstests {
namespace fahrenheit {
class thermometer_adaptor
@ -36,4 +36,33 @@ private:
}}}} // namespaces
namespace org {
namespace sdbuscpp {
namespace stresstests {
namespace fahrenheit {
namespace thermometer {
class factory_adaptor
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory";
protected:
factory_adaptor(sdbus::IObject& object)
: object_(object)
{
object_.registerMethod("createDelegateObject").onInterface(interfaceName).implementedAs([this](sdbus::Result<sdbus::ObjectPath>&& result){ this->createDelegateObject(std::move(result)); });
object_.registerMethod("destroyDelegateObject").onInterface(interfaceName).implementedAs([this](sdbus::Result<>&& result, sdbus::ObjectPath delegate){ this->destroyDelegateObject(std::move(result), std::move(delegate)); }).withNoReply();
}
private:
virtual void createDelegateObject(sdbus::Result<sdbus::ObjectPath>&& result) = 0;
virtual void destroyDelegateObject(sdbus::Result<>&& result, sdbus::ObjectPath delegate) = 0;
private:
sdbus::IObject& object_;
};
}}}}} // namespaces
#endif

View File

@ -1,6 +1,6 @@
/*
* This file was automatically generated by sdbuscpp-xml2cpp; DO NOT EDIT!
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__fahrenheit_thermometer_proxy_h__proxy__H__
@ -12,7 +12,7 @@
namespace org {
namespace sdbuscpp {
namespace stresstest {
namespace stresstests {
namespace fahrenheit {
class thermometer_proxy
@ -40,4 +40,40 @@ private:
}}}} // namespaces
namespace org {
namespace sdbuscpp {
namespace stresstests {
namespace fahrenheit {
namespace thermometer {
class factory_proxy
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory";
protected:
factory_proxy(sdbus::IObjectProxy& object)
: object_(object)
{
}
public:
sdbus::ObjectPath createDelegateObject()
{
sdbus::ObjectPath result;
object_.callMethod("createDelegateObject").onInterface(interfaceName).storeResultsTo(result);
return result;
}
void destroyDelegateObject(const sdbus::ObjectPath& delegate)
{
object_.callMethod("destroyDelegateObject").onInterface(interfaceName).withArguments(delegate).dontExpectReply();
}
private:
sdbus::IObjectProxy& object_;
};
}}}}} // namespaces
#endif

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/org/sdbuscpp/stresstest/celsius/thermometer">
<interface name="org.sdbuscpp.stresstest.celsius.thermometer">
<node name="/org/sdbuscpp/stresstests/celsius/thermometer">
<interface name="org.sdbuscpp.stresstests.celsius.thermometer">
<method name="getCurrentTemperature">
<arg type="u" name="result" direction="out" />
</method>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/org/sdbuscpp/stresstest/concatenator">
<interface name="org.sdbuscpp.stresstest.concatenator">
<node name="/org/sdbuscpp/stresstests/concatenator">
<interface name="org.sdbuscpp.stresstests.concatenator">
<method name="concatenate">
<arg type="a{sv}" name="params" direction="in" />
<arg type="s" name="result" direction="out" />

View File

@ -1,9 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/org/sdbuscpp/stresstest/fahrenheit/thermometer">
<interface name="org.sdbuscpp.stresstest.fahrenheit.thermometer">
<node name="/org/sdbuscpp/stresstests/fahrenheit/thermometer">
<interface name="org.sdbuscpp.stresstests.fahrenheit.thermometer">
<method name="getCurrentTemperature">
<arg type="u" name="result" direction="out" />
</method>
</interface>
<interface name="org.sdbuscpp.stresstests.fahrenheit.thermometer.factory">
<method name="createDelegateObject">
<arg type="o" name="delegate" direction="out" />
<annotation name="org.freedesktop.DBus.Method.Async" value="server" />
</method>
<method name="destroyDelegateObject">
<arg type="o" name="delegate" direction="in" />
<annotation name="org.freedesktop.DBus.Method.Async" value="server" />
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true" />
</method>
</interface>
</node>

View File

@ -46,16 +46,16 @@
using namespace std::chrono_literals;
using namespace std::string_literals;
#define SERVICE_1_BUS_NAME "org.sdbuscpp.stresstests.service1"
#define SERVICE_2_BUS_NAME "org.sdbuscpp.stresstests.service2"
#define CELSIUS_THERMOMETER_OBJECT_PATH "/org/sdbuscpp/stresstests/celsius/thermometer"
#define FAHRENHEIT_THERMOMETER_OBJECT_PATH "/org/sdbuscpp/stresstests/fahrenheit/thermometer"
#define CONCATENATOR_OBJECT_PATH "/org/sdbuscpp/stresstests/concatenator"
#define SERVICE_1_BUS_NAME "org.sdbuscpp.stresstests.service1"s
#define SERVICE_2_BUS_NAME "org.sdbuscpp.stresstests.service2"s
#define CELSIUS_THERMOMETER_OBJECT_PATH "/org/sdbuscpp/stresstests/celsius/thermometer"s
#define FAHRENHEIT_THERMOMETER_OBJECT_PATH "/org/sdbuscpp/stresstests/fahrenheit/thermometer"s
#define CONCATENATOR_OBJECT_PATH "/org/sdbuscpp/stresstests/concatenator"s
class CelsiusThermometerAdaptor : public sdbus::Interfaces<org::sdbuscpp::stresstest::celsius::thermometer_adaptor>
class CelsiusThermometerAdaptor : public sdbus::Interfaces<org::sdbuscpp::stresstests::celsius::thermometer_adaptor>
{
public:
using sdbus::Interfaces<org::sdbuscpp::stresstest::celsius::thermometer_adaptor>::Interfaces;
using sdbus::Interfaces<org::sdbuscpp::stresstests::celsius::thermometer_adaptor>::Interfaces;
protected:
virtual uint32_t getCurrentTemperature() override
@ -67,17 +67,19 @@ private:
uint32_t m_currentTemperature{};
};
class CelsiusThermometerProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::celsius::thermometer_proxy>
class CelsiusThermometerProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstests::celsius::thermometer_proxy>
{
public:
using sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::celsius::thermometer_proxy>::ProxyInterfaces;
using sdbus::ProxyInterfaces<org::sdbuscpp::stresstests::celsius::thermometer_proxy>::ProxyInterfaces;
};
class FahrenheitThermometerAdaptor : public sdbus::Interfaces<org::sdbuscpp::stresstest::fahrenheit::thermometer_adaptor>
class FahrenheitThermometerAdaptor : public sdbus::Interfaces< org::sdbuscpp::stresstests::fahrenheit::thermometer_adaptor
, org::sdbuscpp::stresstests::fahrenheit::thermometer::factory_adaptor >
{
public:
FahrenheitThermometerAdaptor(sdbus::IConnection& connection, std::string objectPath)
: sdbus::Interfaces<org::sdbuscpp::stresstest::fahrenheit::thermometer_adaptor>(connection, std::move(objectPath))
: sdbus::Interfaces< org::sdbuscpp::stresstests::fahrenheit::thermometer_adaptor
, org::sdbuscpp::stresstests::fahrenheit::thermometer::factory_adaptor >(connection, std::move(objectPath))
, celsiusProxy_(connection, SERVICE_2_BUS_NAME, CELSIUS_THERMOMETER_OBJECT_PATH)
{
}
@ -89,21 +91,55 @@ protected:
return static_cast<uint32_t>(celsiusProxy_.getCurrentTemperature() * 1.8 + 32.);
}
virtual void createDelegateObject(sdbus::Result<sdbus::ObjectPath>&& result) override
{
static size_t objectCounter{};
objectCounter++;
std::thread([this, result = std::move(result), objectCounter = objectCounter]()
{
auto& connection = getObject().getConnection();
sdbus::ObjectPath newObjectPath = FAHRENHEIT_THERMOMETER_OBJECT_PATH + "/" + std::to_string(objectCounter);
// Here we are testing dynamic creation of a D-Bus object in an async way
auto adaptor = std::make_unique<FahrenheitThermometerAdaptor>(connection, newObjectPath);
std::lock_guard<std::mutex> lock{mutex_};
children_.emplace(newObjectPath, std::move(adaptor));
result.returnResults(newObjectPath);
}).detach();
}
virtual void destroyDelegateObject(sdbus::Result<>&& /*result*/, sdbus::ObjectPath delegate) override
{
std::thread([this, delegate = std::move(delegate)]()
{
// Here we are testing dynamic removal of a D-Bus object in an async way
std::lock_guard<std::mutex> lock{mutex_};
children_.erase(delegate);
}).detach();
}
private:
CelsiusThermometerProxy celsiusProxy_;
std::map<std::string, std::unique_ptr<FahrenheitThermometerAdaptor>> children_;
std::mutex mutex_;
};
class FahrenheitThermometerProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::fahrenheit::thermometer_proxy>
class FahrenheitThermometerProxy : public sdbus::ProxyInterfaces< org::sdbuscpp::stresstests::fahrenheit::thermometer_proxy
, org::sdbuscpp::stresstests::fahrenheit::thermometer::factory_proxy >
{
public:
using sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::fahrenheit::thermometer_proxy>::ProxyInterfaces;
using sdbus::ProxyInterfaces< org::sdbuscpp::stresstests::fahrenheit::thermometer_proxy
, org::sdbuscpp::stresstests::fahrenheit::thermometer::factory_proxy >::ProxyInterfaces;
};
class ConcatenatorAdaptor : public sdbus::Interfaces<org::sdbuscpp::stresstest::concatenator_adaptor>
class ConcatenatorAdaptor : public sdbus::Interfaces<org::sdbuscpp::stresstests::concatenator_adaptor>
{
public:
ConcatenatorAdaptor(sdbus::IConnection& connection, std::string objectPath)
: sdbus::Interfaces<org::sdbuscpp::stresstest::concatenator_adaptor>(connection, std::move(objectPath))
: sdbus::Interfaces<org::sdbuscpp::stresstests::concatenator_adaptor>(connection, std::move(objectPath))
{
unsigned int workers = std::thread::hardware_concurrency();
if (workers < 4)
@ -167,10 +203,10 @@ private:
std::atomic<bool> exit_{};
};
class ConcatenatorProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::concatenator_proxy>
class ConcatenatorProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::stresstests::concatenator_proxy>
{
public:
using sdbus::ProxyInterfaces<org::sdbuscpp::stresstest::concatenator_proxy>::ProxyInterfaces;
using sdbus::ProxyInterfaces<org::sdbuscpp::stresstests::concatenator_proxy>::ProxyInterfaces;
private:
virtual void onConcatenateReply(const std::string& result, const sdbus::Error* error) override
@ -204,8 +240,8 @@ private:
}
public:
std::atomic<uint32_t> repliesReceived_;
std::atomic<uint32_t> signalsReceived_;
std::atomic<uint32_t> repliesReceived_{};
std::atomic<uint32_t> signalsReceived_{};
};
//-----------------------------------------
@ -258,8 +294,8 @@ int main(int /*argc*/, char */*argv*/[])
// Make sure the system is catching up with our async requests,
// otherwise sleep a bit to slow down flooding the server.
assert(localCounter >= concatenator.repliesReceived_);
while ((localCounter - concatenator.repliesReceived_) > 20 && !stopClients)
std::this_thread::sleep_for(2ms);
while ((localCounter - concatenator.repliesReceived_) > 40 && !stopClients)
std::this_thread::sleep_for(1ms);
// Update statistics
concatenationCallsMade = localCounter;
@ -271,6 +307,11 @@ int main(int /*argc*/, char */*argv*/[])
std::thread thermometerThread([&]()
{
// Here we continuously remotely call getCurrentTemperature(). We have one proxy object,
// first we use it's factory interface to create another proxy object, call getCurrentTemperature()
// on that one, and then destroy that proxy object. All that continously in a loop.
// This tests dynamic creation and destruction of remote D-Bus objects and local object proxies.
FahrenheitThermometerProxy thermometer(con, SERVICE_1_BUS_NAME, FAHRENHEIT_THERMOMETER_OBJECT_PATH);
uint32_t localCounter{};
uint32_t previousTemperature{};
@ -278,13 +319,20 @@ int main(int /*argc*/, char */*argv*/[])
while (!stopClients)
{
localCounter++;
auto temperature = thermometer.getCurrentTemperature();
auto newObjectPath = thermometer.createDelegateObject();
FahrenheitThermometerProxy proxy{con, SERVICE_1_BUS_NAME, newObjectPath};
auto temperature = proxy.getCurrentTemperature();
assert(temperature >= previousTemperature); // The temperature shall rise continually
previousTemperature = temperature;
std::this_thread::sleep_for(5ms);
//std::this_thread::sleep_for(1ms);
if ((localCounter % 10) == 0)
thermometerCallsMade = localCounter;
proxy.~FahrenheitThermometerProxy();
thermometer.destroyDelegateObject(newObjectPath);
}
});