Emulate sync D-Bus method call with async implementation underneath to avoid poll race condition

This commit is contained in:
sangelovic
2020-01-12 23:10:19 +01:00
parent cb118f95b7
commit 4688e81534
14 changed files with 760 additions and 592 deletions
File diff suppressed because it is too large Load Diff
+7 -14
View File
@@ -50,20 +50,6 @@ public:
protected:
int32_t doSignalEmission() override
{
static int32_t counter = 0;
emitSimpleSignal();
printf("First simple signal thrown\n");
counter++;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
//emitSimpleSignal();
//printf("Second simple signal thrown\n");
counter++;
return counter;
}
void noArgNoReturn() const
{
}
@@ -211,6 +197,13 @@ protected:
throw sdbus::createError(1, "A test error occurred");
}
void emitTwoSimpleSignals() override
{
emitSimpleSignal();
emitSignalWithMap({});
}
std::string state()
{
return m_state;
+1 -1
View File
@@ -61,7 +61,6 @@ protected:
void onSimpleSignal() override
{
m_gotSimpleSignal = true;
printf("Thread %d: Got simple signal\n", gettid());
}
void onSignalWithMap(const std::map<int32_t, std::string>& m) override
@@ -113,6 +112,7 @@ protected:
//private:
public: // for tests
int m_SimpleSignals = 0;
std::atomic<bool> m_gotSimpleSignal{false};
std::atomic<bool> m_gotSignalWithMap{false};
std::map<int32_t, std::string> m_mapFromSignal;
+3 -3
View File
@@ -59,8 +59,6 @@ protected:
{
object_.setInterfaceFlags(INTERFACE_NAME).markAsDeprecated().withPropertyUpdateBehavior(sdbus::Flags::EMITS_NO_SIGNAL);
object_.registerMethod("doSignalEmission").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->doSignalEmission(); });
object_.registerMethod("noArgNoReturn").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->noArgNoReturn(); });
object_.registerMethod("getInt").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getInt(); });
object_.registerMethod("getTuple").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getTuple(); });
@@ -108,6 +106,8 @@ protected:
object_.registerMethod("doPrivilegedStuff").onInterface(INTERFACE_NAME).implementedAs([](){}).markAsPrivileged();
object_.registerMethod("emitTwoSimpleSignals").onInterface(INTERFACE_NAME).implementedAs([this](){ this->emitTwoSimpleSignals(); });
// registration of signals is optional, it is useful because of introspection
object_.registerSignal("simpleSignal").onInterface(INTERFACE_NAME).markAsDeprecated();
object_.registerSignal("signalWithMap").onInterface(INTERFACE_NAME).withParameters<std::map<int32_t, std::string>>();
@@ -152,7 +152,6 @@ private:
protected:
virtual int32_t doSignalEmission() = 0;
virtual void noArgNoReturn() const = 0;
virtual int32_t getInt() const = 0;
virtual std::tuple<uint32_t, std::string> getTuple() const = 0;
@@ -171,6 +170,7 @@ protected:
virtual sdbus::UnixFd getUnixFd() const = 0;
virtual ComplexType getComplex() const = 0;
virtual void throwError() const = 0;
virtual void emitTwoSimpleSignals() = 0;
virtual std::string state() = 0;
virtual uint32_t action() = 0;
+15 -5
View File
@@ -56,12 +56,9 @@ protected:
virtual void onDoOperationReply(uint32_t returnValue, const sdbus::Error* error) = 0;
public:
int32_t doSignalEmission()
void emitTwoSimpleSignals()
{
int32_t result;
object_.callMethod("doSignalEmission").onInterface(INTERFACE_NAME).storeResultsTo(result);
//object_.callMethodAsync("doSignalEmission").onInterface(INTERFACE_NAME).uponReplyInvoke([this](const sdbus::Error* error, int32_t returnValue){ printf("Async reply handler\n"); });
return result;
object_.callMethod("emitTwoSimpleSignals").onInterface(INTERFACE_NAME);
}
void noArgNoReturn()
@@ -180,6 +177,19 @@ public:
});
}
void doOperationClientSideAsyncWith500msTimeout(uint32_t param)
{
using namespace std::chrono_literals;
object_.callMethodAsync("doOperation")
.onInterface(INTERFACE_NAME)
.withTimeout(500000us)
.withArguments(param)
.uponReplyInvoke([this](const sdbus::Error* error, uint32_t returnValue)
{
this->onDoOperationReply(returnValue, error);
});
}
sdbus::Signature getSignature()
{
sdbus::Signature result;
+25 -3
View File
@@ -37,6 +37,8 @@
using namespace std::chrono_literals;
uint64_t totalDuration = 0;
class PerftestProxy : public sdbus::ProxyInterfaces<org::sdbuscpp::perftests_proxy>
{
public:
@@ -66,7 +68,9 @@ protected:
else if (counter == m_msgCount)
{
auto stopTime = std::chrono::steady_clock::now();
std::cout << "Received " << m_msgCount << " signals in: " << std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime).count() << " ms" << std::endl;
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime).count();
totalDuration += duration;
std::cout << "Received " << m_msgCount << " signals in: " << duration << " ms" << std::endl;
counter = 0;
}
}
@@ -104,6 +108,7 @@ int main(int /*argc*/, char */*argv*/[])
unsigned int msgCount = 1000;
unsigned int msgSize{};
/*
msgSize = 20;
std::cout << "** Measuring signals of size " << msgSize << " bytes (" << repetitions << " repetitions)..." << std::endl << std::endl;
client.m_msgCount = msgCount; client.m_msgSize = msgSize;
@@ -114,6 +119,9 @@ int main(int /*argc*/, char */*argv*/[])
std::this_thread::sleep_for(1000ms);
}
std::cout << "AVERAGE: " << (totalDuration/repetitions) << " ms" << std::endl;
totalDuration = 0;
msgSize = 1000;
std::cout << std::endl << "** Measuring signals of size " << msgSize << " bytes (" << repetitions << " repetitions)..." << std::endl << std::endl;
client.m_msgCount = msgCount; client.m_msgSize = msgSize;
@@ -124,6 +132,10 @@ int main(int /*argc*/, char */*argv*/[])
std::this_thread::sleep_for(1000ms);
}
std::cout << "AVERAGE: " << (totalDuration/repetitions) << " ms" << std::endl;
totalDuration = 0;
*/
msgSize = 20;
std::cout << std::endl << "** Measuring method calls of size " << msgSize << " bytes (" << repetitions << " repetitions)..." << std::endl << std::endl;
for (unsigned int r = 0; r < repetitions; ++r)
@@ -140,11 +152,16 @@ int main(int /*argc*/, char */*argv*/[])
assert(result.size() == msgSize);
}
auto stopTime = std::chrono::steady_clock::now();
std::cout << "Called " << msgCount << " methods in: " << std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime).count() << " ms" << std::endl;
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime).count();
totalDuration += duration;
std::cout << "Called " << msgCount << " methods in: " << duration << " ms" << std::endl;
std::this_thread::sleep_for(1000ms);
}
std::cout << "AVERAGE: " << (totalDuration/repetitions) << " ms" << std::endl;
totalDuration = 0;
msgSize = 1000;
std::cout << std::endl << "** Measuring method calls of size " << msgSize << " bytes (" << repetitions << " repetitions)..." << std::endl << std::endl;
for (unsigned int r = 0; r < repetitions; ++r)
@@ -161,10 +178,15 @@ int main(int /*argc*/, char */*argv*/[])
assert(result.size() == msgSize);
}
auto stopTime = std::chrono::steady_clock::now();
std::cout << "Called " << msgCount << " methods in: " << std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime).count() << " ms" << std::endl;
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime).count();
totalDuration += duration;
std::cout << "Called " << msgCount << " methods in: " << duration << " ms" << std::endl;
std::this_thread::sleep_for(1000ms);
}
std::cout << "AVERAGE: " << (totalDuration/repetitions) << " ms" << std::endl;
totalDuration = 0;
return 0;
}