summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Fietzke <fietzke@itestra.de>2013-11-21 10:16:41 +0100
committerPhilip Rauwolf <rauwolf@itestra.de>2013-11-27 10:21:45 +0100
commite6460a44e88ceb584d920e86550a725491965d7a (patch)
treebc24959c33e09678032707be2fce47a1743f325b
parentf6eda262a1040205f7a6cbe6f9eac8b0f7cfa5fc (diff)
downloadgenivi-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.cpp9
-rw-r--r--src/test/DBusCommunicationTest.cpp45
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);