diff options
author | Arnaud Fietzke <fietzke@itestra.de> | 2013-11-21 10:16:41 +0100 |
---|---|---|
committer | Philip Rauwolf <rauwolf@itestra.de> | 2013-11-27 10:21:45 +0100 |
commit | e6460a44e88ceb584d920e86550a725491965d7a (patch) | |
tree | bc24959c33e09678032707be2fce47a1743f325b | |
parent | f6eda262a1040205f7a6cbe6f9eac8b0f7cfa5fc (diff) | |
download | genivi-common-api-dbus-runtime-e6460a44e88ceb584d920e86550a725491965d7a.tar.gz |
Fix for GLIPCI-165.
Once resumeDispatching() is called,
readWriteDispatch() may dispatch the
reply, causing replyAsyncHandler to
be deleted.
Also added a test to check whether
sync and async calls may be mixed.
Change-Id: I15954e1e1190cbdea01aef871dac763cc06479ef
-rw-r--r-- | src/CommonAPI/DBus/DBusConnection.cpp | 9 | ||||
-rw-r--r-- | src/test/DBusCommunicationTest.cpp | 45 |
2 files changed, 53 insertions, 1 deletions
diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp index 0639305..6736834 100644 --- a/src/CommonAPI/DBus/DBusConnection.cpp +++ b/src/CommonAPI/DBus/DBusConnection.cpp @@ -553,6 +553,7 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync( DBusPendingCall* libdbusPendingCall; dbus_bool_t libdbusSuccess; + suspendDispatching(); libdbusSuccess = dbus_connection_send_with_reply(libdbusConnection_, dbusMessage.libdbusMessage_, &libdbusPendingCall, @@ -560,6 +561,7 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync( if (!libdbusSuccess || !libdbusPendingCall) { dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::CONNECTION_FAILED, dbusMessage.createMethodError(DBUS_ERROR_DISCONNECTED)); + resumeDispatching(); return dbusMessageReplyAsyncHandler->getFuture(); } @@ -572,6 +574,7 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync( if (!libdbusSuccess) { dbusMessageReplyAsyncHandler->onDBusMessageReply(CallStatus::OUT_OF_MEMORY, dbusMessage); dbus_pending_call_unref(libdbusPendingCall); + resumeDispatching(); return dbusMessageReplyAsyncHandler->getFuture(); } @@ -590,7 +593,11 @@ std::future<CallStatus> DBusConnection::sendDBusMessageWithReplyAsync( enforceTimeoutMutex_.unlock(); } - return replyAsyncHandler->getFuture(); + std::future<CallStatus> result = replyAsyncHandler->getFuture(); + + resumeDispatching(); + + return result; } diff --git a/src/test/DBusCommunicationTest.cpp b/src/test/DBusCommunicationTest.cpp index d27d82c..126422d 100644 --- a/src/test/DBusCommunicationTest.cpp +++ b/src/test/DBusCommunicationTest.cpp @@ -68,6 +68,7 @@ class DBusCommunicationTest: public ::testing::Test { static const std::string serviceAddress3_; static const std::string serviceAddress4_; static const std::string nonstandardAddress_; + static const std::string serviceAddress5_; }; const std::string DBusCommunicationTest::serviceAddress_ = "local:CommonAPI.DBus.tests.DBusProxyTestInterface:CommonAPI.DBus.tests.DBusProxyTestService"; @@ -75,6 +76,7 @@ const std::string DBusCommunicationTest::serviceAddress2_ = "local:CommonAPI.DBu const std::string DBusCommunicationTest::serviceAddress3_ = "local:CommonAPI.DBus.tests.DBusProxyTestInterface:CommonAPI.DBus.tests.DBusProxyTestService3"; const std::string DBusCommunicationTest::serviceAddress4_ = "local:CommonAPI.DBus.tests.DBusProxyTestInterface:CommonAPI.DBus.tests.DBusProxyTestService4"; const std::string DBusCommunicationTest::nonstandardAddress_ = "local:non.standard.ServiceName:non.standard.participand.ID"; +const std::string DBusCommunicationTest::serviceAddress5_ = "local:CommonAPI.DBus.tests.DBusProxyTestInterface:CommonAPI.DBus.tests.DBusProxyTestService5"; TEST_F(DBusCommunicationTest, RemoteMethodCallSucceeds) { @@ -185,6 +187,49 @@ TEST_F(DBusCommunicationTest, RemoteMethodCallWithNonstandardAddressSucceeds) { } +TEST_F(DBusCommunicationTest, MixedSyncAndAsyncCallsSucceed) { + auto defaultTestProxy = proxyFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(serviceAddress5_); + ASSERT_TRUE((bool)defaultTestProxy); + + auto stub = std::make_shared<commonapi::tests::TestInterfaceStubDefault>(); + + bool serviceRegistered = servicePublisher_->registerService(stub, serviceAddress5_, stubFactory_); + for(unsigned int i = 0; !serviceRegistered && i < 100; ++i) { + serviceRegistered = servicePublisher_->registerService(stub, serviceAddress5_, stubFactory_); + usleep(10000); + } + ASSERT_TRUE(serviceRegistered); + + for (unsigned int i = 0; !defaultTestProxy->isAvailable() && i < 100; ++i) { + usleep(10000); + } + ASSERT_TRUE(defaultTestProxy->isAvailable()); + + uint32_t v1 = 5; + std::string v2 = "Hai :)"; + CommonAPI::CallStatus stat; + unsigned int responseCounter = 0; + for (unsigned int i = 0; i < 10; i++) { + defaultTestProxy->testVoidPredefinedTypeMethodAsync(v1, v2, [&responseCounter](const CommonAPI::CallStatus& status) { + if(status == CommonAPI::CallStatus::SUCCESS) { + responseCounter++; + } + } + ); + + defaultTestProxy->testVoidPredefinedTypeMethod(v1, v2, stat); + EXPECT_EQ(stat, CommonAPI::CallStatus::SUCCESS); + } + + for (unsigned int i = 0; i < 500 && responseCounter < 10; i++) { + usleep(1000); + } + EXPECT_EQ(10, responseCounter); + + servicePublisher_->unregisterService(serviceAddress5_); +} + + TEST_F(DBusCommunicationTest, RemoteMethodCallHeavyLoad) { auto defaultTestProxy = proxyFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(serviceAddress4_); ASSERT_TRUE((bool)defaultTestProxy); |