of a circular dependency between DBusConnection and DBusServiceRegistry.
Also removed bug that prevented ServiceRegistry-callbacks from being
deregistered correctly. Extended tests, some formatting issues, fixed
one spelling error.
Change-Id: I6cf2148375f4c086e60f0ad642415056bd808759
return (subscriptionToken);
}
-void DBusConnection::unsubsribeFromSelectiveBroadcast(const std::string& eventName,
+void DBusConnection::unsubscribeFromSelectiveBroadcast(const std::string& eventName,
DBusProxyConnection::DBusSignalHandlerToken subscription,
- DBusProxy* callingProxy) {
- bool lastListenerOnConnectionRemoved = removeSignalMemberHandler(subscription);
+ DBusProxy* callingProxy,
+ const DBusSignalHandler* dbusSignalHandler) {
+ bool lastListenerOnConnectionRemoved = removeSignalMemberHandler(subscription, dbusSignalHandler);
if (lastListenerOnConnectionRemoved) {
// send unsubscribe message to stub
return dbusSignalHandlerPath;
}
-bool DBusConnection::removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken) {
+bool DBusConnection::removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken,
+ const DBusSignalHandler* dbusSignalHandler) {
bool lastHandlerRemoved = false;
std::lock_guard<std::mutex> dbusSignalLock(signalGuard_);
auto equalRangeIteratorPair = dbusSignalHandlerTable_.equal_range(dbusSignalHandlerToken);
if (equalRangeIteratorPair.first != equalRangeIteratorPair.second) {
// advance to the next element
- equalRangeIteratorPair.first++;
+ auto iteratorToNextElement = equalRangeIteratorPair.first;
+ iteratorToNextElement++;
// check if the first element was the only element
- const bool isLastSignalMemberHandler = equalRangeIteratorPair.first == equalRangeIteratorPair.second;
+ const bool isLastSignalMemberHandler = iteratorToNextElement == equalRangeIteratorPair.second;
if (isLastSignalMemberHandler) {
const std::string& objectPath = std::get<0>(dbusSignalHandlerToken);
lastHandlerRemoved = true;
}
- dbusSignalHandlerTable_.erase(equalRangeIteratorPair.first, equalRangeIteratorPair.first);
+ if(dbusSignalHandler == NULL) {
+ // remove all handlers
+ dbusSignalHandlerTable_.erase(dbusSignalHandlerToken);
+ } else {
+ // just remove specific handler
+ while(equalRangeIteratorPair.first != equalRangeIteratorPair.second) {
+ if(equalRangeIteratorPair.first->second == dbusSignalHandler) {
+ equalRangeIteratorPair.first = dbusSignalHandlerTable_.erase(equalRangeIteratorPair.first);
+ }
+ else {
+ equalRangeIteratorPair.first++;
+ }
+ }
+ }
}
return lastHandlerRemoved;
DBusSignalHandler* dbusSignalHandler,
DBusProxy* callingProxy);
- void unsubsribeFromSelectiveBroadcast(const std::string& eventName,
+ void unsubscribeFromSelectiveBroadcast(const std::string& eventName,
DBusProxyConnection::DBusSignalHandlerToken subscription,
- DBusProxy* callingProxy);
+ DBusProxy* callingProxy,
+ const DBusSignalHandler* dbusSignalHandler);
void registerObjectPath(const std::string& objectPath);
void unregisterObjectPath(const std::string& objectPath);
- bool removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken);
+ bool removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken,
+ const DBusSignalHandler* dbusSignalHandler = NULL);
bool readWriteDispatch(int timeoutMilliseconds = -1);
virtual const std::shared_ptr<DBusServiceRegistry> getDBusServiceRegistry();
this);
}
-void DBusProxy::unsubsribeFromSelectiveBroadcast(const std::string& eventName,
- DBusProxyConnection::DBusSignalHandlerToken subscription) {
- getDBusConnection()->unsubsribeFromSelectiveBroadcast(eventName, subscription, this);
+void DBusProxy::unsubscribeFromSelectiveBroadcast(const std::string& eventName,
+ DBusProxyConnection::DBusSignalHandlerToken subscription,
+ const DBusProxyConnection::DBusSignalHandler* dbusSignalHandler) {
+ getDBusConnection()->unsubscribeFromSelectiveBroadcast(eventName, subscription, this, dbusSignalHandler);
}
} // namespace DBus
const std::string& interfaceMemberName,
const std::string& interfaceMemberSignature,
DBusProxyConnection::DBusSignalHandler* dbusSignalHandler);
- void unsubsribeFromSelectiveBroadcast(const std::string& eventName,
- DBusProxyConnection::DBusSignalHandlerToken subscription);
+ void unsubscribeFromSelectiveBroadcast(const std::string& eventName,
+ DBusProxyConnection::DBusSignalHandlerToken subscription,
+ const DBusProxyConnection::DBusSignalHandler* dbusSignalHandler);
void init();
private:
typedef Event<AvailabilityStatus> ConnectionStatusEvent;
- virtual ~DBusProxyConnection() {
- }
+ virtual ~DBusProxyConnection() { }
virtual bool isConnected() const = 0;
DBusSignalHandler* dbusSignalHandler,
DBusProxy* callingProxy) = 0;
- virtual void unsubsribeFromSelectiveBroadcast(const std::string& eventName,
+ virtual void unsubscribeFromSelectiveBroadcast(const std::string& eventName,
DBusProxyConnection::DBusSignalHandlerToken subscription,
- DBusProxy* callingProxy) = 0;
- virtual bool removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken) = 0;
+ DBusProxy* callingProxy,
+ const DBusSignalHandler* dbusSignalHandler) = 0;
+
+ virtual bool removeSignalMemberHandler(const DBusSignalHandlerToken& dbusSignalHandlerToken,
+ const DBusSignalHandler* dbusSignalHandler = NULL) = 0;
virtual bool addObjectManagerSignalMemberHandler(const std::string& dbusBusName,
DBusSignalHandler* dbusSignalHandler) = 0;
protected:
virtual void onLastListenerRemoved(const CancellableListener&) {
- associatedDbusProxy_.unsubsribeFromSelectiveBroadcast(DBusEventBase::eventName_, DBusEventBase::subscription_);
+ associatedDbusProxy_.unsubscribeFromSelectiveBroadcast(
+ DBusEventBase::eventName_,
+ DBusEventBase::subscription_,
+ this);
}
private:
#include "DBusProxyAsyncCallbackHandler.h"
#include "DBusUtils.h"
-#include <iostream>
#include <iterator>
namespace CommonAPI {
// fulfill all open promises
std::promise<DBusRecordState> promiseOnResolve = std::move(dbusServiceListenersRecord.promiseOnResolve);
- promiseOnResolve.set_value(DBusRecordState::NOT_AVAILABLE);
+
+ try {
+ std::future<DBusRecordState> futureOnResolve = promiseOnResolve.get_future();
+ if(!futureOnResolve.valid()) {
+ promiseOnResolve.set_value(DBusRecordState::NOT_AVAILABLE);
+ }
+ } catch (std::future_error& e) { }
if (dbusServiceListenersRecord.uniqueBusNameState == DBusRecordState::RESOLVED) {
onDBusServiceNotAvailable(dbusServiceListenersRecord);
void DBusServiceRegistry::init() {
dbusDaemonProxyStatusEventSubscription_ =
dbusDaemonProxy_->getProxyStatusEvent().subscribeCancellableListener(
- std::bind(&DBusServiceRegistry::onDBusDaemonProxyStatusEvent, shared_from_this(), std::placeholders::_1));
+ std::bind(&DBusServiceRegistry::onDBusDaemonProxyStatusEvent, this, std::placeholders::_1));
dbusDaemonProxyNameOwnerChangedEventSubscription_ =
dbusDaemonProxy_->getNameOwnerChangedEvent().subscribeCancellableListener(
}
}
-
if (availabilityStatus != AvailabilityStatus::UNKNOWN) {
notificationThread_ = std::this_thread::get_id();
SubscriptionStatus subscriptionStatus = serviceListener(availabilityStatus);
auto& dbusUniqueNameRecord = dbusServiceUniqueNameIterator->second;
- //auto dbusObjectPathIterator = dbusUniqueNameRecord.dbusObjectPathsCache.find(dbusObjectPath);
- //const bool isDBusObjectPathFound = (dbusObjectPathIterator != dbusUniqueNameRecord.dbusObjectPathsCache.end());
-
- /*
- if (!isDBusObjectPathFound) {
- return SubscriptionStatus::RETAIN;
- }
- */
-
DBusObjectPathCache& dbusObjectPathRecord = dbusUniqueNameRecord.dbusObjectPathsCache[dbusObjectPath];
-/*
- if (isDBusObjectPathFound) {
- dbusObjectPathRecord = &dbusObjectPathIterator->second;
- }
- else
- {
- DBusObjectPathCache dbusObjectPathRecord;
- auto insertionResult = dbusUniqueNameRecord.dbusObjectPathsCache.insert(std::make_pair(dbusObjectPath, std::move(dbusObjectPath)));
- auto objectPathCacheIterator = insertionResult.first;
- dbusObjectPathRecord = &(objectPathCacheIterator->second);
- }
-*/
if (dbusObjectPathRecord.state != DBusRecordState::RESOLVED) {
return SubscriptionStatus::RETAIN;
parseIntrospectionNode(rootNode, rootObjectPath, rootObjectPath, dbusServiceUniqueName);
- DBusUniqueNameRecord& dbusUniqueNameRecord = dbusUniqueNamesMap_[dbusServiceUniqueName];
+ dbusUniqueNamesMap_[dbusServiceUniqueName];
dbusServicesMutex_.unlock();
}
const DBusUniqueNamesMapIterator dbusUniqueNameRecordIterator = dbusUniqueNamesMap_.find(dbusServiceListenersRecord.uniqueBusName);
// fulfill all open promises on object path resolution
- if(dbusUniqueNameRecordIterator != dbusUniqueNamesMap_.end()) {
+ if (dbusUniqueNameRecordIterator != dbusUniqueNamesMap_.end()) {
DBusUniqueNameRecord& dbusUniqueNameRecord = dbusUniqueNameRecordIterator->second;
for (auto dbusObjectPathsCacheIterator = dbusUniqueNameRecord.dbusObjectPathsCache.begin();
dbusObjectPathsCacheIterator != dbusUniqueNameRecord.dbusObjectPathsCache.end();
promiseOnResolve.set_value(DBusRecordState::NOT_AVAILABLE);
}
} catch (std::future_error& e) { }
-
}
removeUniqueName(dbusUniqueNameRecordIterator);
}
void DBusServiceRegistry::removeUniqueName(const DBusUniqueNamesMapIterator& dbusUniqueNamesIterator) {
+ const bool isSubscriptionCancelled = dbusDaemonProxy_->getDBusConnection()->removeObjectManagerSignalMemberHandler(
+ dbusUniqueNamesIterator->first,
+ this);
+ assert(isSubscriptionCancelled);
+
for (auto dbusServiceNamesIterator = dbusUniqueNamesIterator->second.ownedBusNames.begin();
dbusServiceNamesIterator != dbusUniqueNamesIterator->second.ownedBusNames.end();
dbusServiceNamesIterator++) {
class ProxyTest: public ::testing::Test {
protected:
-
void SetUp() {
-
- isTestStubAdapterRegistered_ = false;
- isExtendedStubAdapterRegistered_ = false;
-
runtime_ = std::dynamic_pointer_cast<CommonAPI::DBus::DBusRuntime>(CommonAPI::Runtime::load());
serviceFactory_ = std::dynamic_pointer_cast<CommonAPI::DBus::DBusFactory>(runtime_->createFactory());
std::shared_ptr<CommonAPI::DBus::DBusFactory> serviceFactory_;
virtual void TearDown() {
- if(isTestStubAdapterRegistered_) {
- deregisterTestStub();
- }
- if(isExtendedStubAdapterRegistered_) {
- deregisterExtendedStub();
- }
usleep(300000);
}
void registerTestStub() {
stubDefault_ = std::make_shared<commonapi::tests::TestInterfaceStubDefault>();
- isTestStubAdapterRegistered_ = runtime_->getServicePublisher()->registerService<commonapi::tests::TestInterfaceStub>(stubDefault_, commonApiAddress, serviceFactory_);
+ bool isTestStubAdapterRegistered_ = runtime_->getServicePublisher()->registerService<commonapi::tests::TestInterfaceStub>(stubDefault_, commonApiAddress, serviceFactory_);
ASSERT_TRUE(isTestStubAdapterRegistered_);
usleep(500000);
void registerExtendedStub() {
stubExtended_ = std::make_shared<commonapi::tests::ExtendedInterfaceStubDefault>();
- isExtendedStubAdapterRegistered_ = runtime_->getServicePublisher()->registerService<commonapi::tests::ExtendedInterfaceStub>(stubExtended_, commonApiAddressExtended, serviceFactory_);
+ bool isExtendedStubAdapterRegistered_ = runtime_->getServicePublisher()->registerService<commonapi::tests::ExtendedInterfaceStub>(stubExtended_, commonApiAddressExtended, serviceFactory_);
ASSERT_TRUE(isExtendedStubAdapterRegistered_);
usleep(500000);
EXPECT_TRUE(isInstanceAlive);
- //deregisterTestStub();
+ deregisterTestStub();
}
TEST_F(ProxyTest, IsAvailableBlocking) {
EXPECT_TRUE(proxy_->isAvailableBlocking());
- //deregisterTestStub();
+ deregisterTestStub();
}
TEST_F(ProxyTest, HasNecessaryAttributesAndEvents) {
// give the proxy time to become available
for (uint32_t i = 0; !extendedProxy->isAvailable() && i < 500; ++i) {
- usleep(2 * 1000);
+ usleep(20 * 1000);
}
- ASSERT_TRUE(extendedProxy->isAvailable());
+ EXPECT_TRUE(extendedProxy->isAvailable());
uint32_t inInt;
bool wasCalled = false;
});
usleep(500000);
- ASSERT_TRUE(wasCalled);
- //deregisterExtendedStub();
- //usleep(500000);
+ EXPECT_TRUE(wasCalled);
+ deregisterExtendedStub();
}
TEST_F(ProxyTest, CallMethodFromParentInterface) {
auto extendedProxy = serviceFactory_->buildProxy<commonapi::tests::ExtendedInterfaceProxy>(commonApiAddressExtended);
for (uint32_t i = 0; !extendedProxy->isAvailable() && i < 500; ++i) {
- usleep(2 * 1000);
+ usleep(20 * 1000);
}
- ASSERT_TRUE(extendedProxy->isAvailable());
+ EXPECT_TRUE(extendedProxy->isAvailable());
bool wasCalled = false;
extendedProxy->testEmptyMethodAsync(
ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
wasCalled = true;
});
- for (uint32_t i = 0; !wasCalled && i < 500; ++i) {
- usleep(2 * 1000);
- }
- ASSERT_TRUE(wasCalled);
+ usleep(500000);
+ EXPECT_TRUE(wasCalled);
+
+ deregisterExtendedStub();
}
TEST_F(ProxyTest, ProxyCanFetchVersionAttributeFromInheritedInterfaceStub) {
auto extendedProxy = serviceFactory_->buildProxy<commonapi::tests::TestInterfaceProxy>(commonApiAddressExtended);
- for (uint32_t i = 0; !extendedProxy->isAvailable() && i < 500; ++i) {
- usleep(2 * 1000);
+ for (uint32_t i = 0; !extendedProxy->isAvailable() && i < 800; ++i) {
+ usleep(20 * 1000);
}
- ASSERT_TRUE(extendedProxy->isAvailable());
+ EXPECT_TRUE(extendedProxy->isAvailable());
CommonAPI::InterfaceVersionAttribute& versionAttribute = extendedProxy->getInterfaceVersionAttribute();
bool wasCalled = false;
std::future<CommonAPI::CallStatus> futureVersion = versionAttribute.getValueAsync([&](const CommonAPI::CallStatus& callStatus, CommonAPI::Version version) {
- ASSERT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
- ASSERT_TRUE(version.Major > 0 || version.Minor > 0);
+ EXPECT_EQ(callStatus, CommonAPI::CallStatus::SUCCESS);
+ EXPECT_TRUE(version.Major > 0 || version.Minor > 0);
wasCalled = true;
});
futureVersion.wait();
-// usleep(100000);
+ usleep(100000);
+
+ EXPECT_TRUE(wasCalled);
- ASSERT_TRUE(wasCalled);
+ deregisterExtendedStub();
}
int main(int argc, char** argv) {
/*
-* This file was generated by the CommonAPI Generators.
+* This file was generated by the CommonAPI Generators.
* Used org.genivi.commonapi.core 2.1.4.qualifier.
* Used org.franca.core 0.8.10.201309262002.
*
public:
LeafInterfaceProxy(std::shared_ptr<CommonAPI::Proxy> delegate);
~LeafInterfaceProxy();
-
+
typedef LeafInterface InterfaceType;
-
+
* It will provide the same value for CallStatus as will be handed to the callback.
*/
virtual std::future<CommonAPI::CallStatus> testLeafMethodAsync(const int32_t& inInt, const std::string& inString, TestLeafMethodAsyncCallback callback);
-
+
/**
* Returns the CommonAPI address of the remote partner this proxy communicates with.
return delegate_->getInterfaceVersionAttribute();
}
-
} // namespace managed
} // namespace tests
/*
-* This file was generated by the CommonAPI Generators.
+* This file was generated by the CommonAPI Generators.
* Used org.genivi.commonapi.core 2.1.4.qualifier.
* Used org.franca.core 0.8.10.201309262002.
*
-
#if !defined (COMMONAPI_INTERNAL_COMPILATION)
#define COMMONAPI_INTERNAL_COMPILATION
#endif
/*
-* This file was generated by the CommonAPI Generators.
+* This file was generated by the CommonAPI Generators.
* Used org.genivi.commonapi.core 2.1.4.qualifier.
* Used org.franca.core 0.8.10.201309262002.
*
class LeafInterfaceStubAdapter: virtual public CommonAPI::StubAdapter, public LeafInterface {
public:
-
-
+
+
virtual void deactivateManagedInstances() = 0;
-
protected:
/**
* Defines properties for storing the ClientIds of clients / proxies that have
/// This is the method that will be called on remote calls on the method testLeafMethod.
virtual void testLeafMethod(const std::shared_ptr<CommonAPI::ClientId> clientId, int32_t inInt, std::string inString, LeafInterface::testLeafMethodError& methodError, int32_t& outInt, std::string& outString) = 0;
-
+
using CommonAPI::Stub<LeafInterfaceStubAdapter, LeafInterfaceStubRemoteEvent>::initStubAdapter;
typedef CommonAPI::Stub<LeafInterfaceStubAdapter, LeafInterfaceStubRemoteEvent>::StubAdapterType StubAdapterType;
typedef CommonAPI::Stub<LeafInterfaceStubAdapter, LeafInterfaceStubRemoteEvent>::RemoteEventHandlerType RemoteEventHandlerType;
/*
-* This file was generated by the CommonAPI Generators.
+* This file was generated by the CommonAPI Generators.
* Used org.genivi.commonapi.core 2.1.4.qualifier.
* Used org.franca.core 0.8.10.201309262002.
*
/*
-* This file was generated by the CommonAPI Generators.
+* This file was generated by the CommonAPI Generators.
* Used org.genivi.commonapi.core 2.1.4.qualifier.
* Used org.franca.core 0.8.10.201309262002.
*
LeafInterfaceStubDefault();
LeafInterfaceStubRemoteEvent* initStubAdapter(const std::shared_ptr<LeafInterfaceStubAdapter>& stubAdapter);
-
+
const CommonAPI::Version& getInterfaceVersion(std::shared_ptr<CommonAPI::ClientId> clientId);
virtual void testLeafMethod(int32_t inInt, std::string inString, LeafInterface::testLeafMethodError& methodError, int32_t& outInt, std::string& outString);
-
+
protected:
private: