summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürgen Gehring <Juergen.Gehring@bmw.de>2016-12-12 02:23:28 -0800
committerJürgen Gehring <Juergen.Gehring@bmw.de>2016-12-12 02:23:28 -0800
commit01c9c4b3d8627a8eab95e3dcdb5f0f4f1331b004 (patch)
tree56f7e6a6657259ef5a99ed6ec812f5cb268addc1
parent08ee52a77e49afb2eae4ac9cb6d8698374a3d542 (diff)
downloadgenivi-common-api-dbus-runtime-01c9c4b3d8627a8eab95e3dcdb5f0f4f1331b004.tar.gz
CommonAPI-D-Bus 3.1.10.23.1.10.2
-rw-r--r--CHANGES4
-rw-r--r--include/CommonAPI/DBus/DBusConnection.hpp8
-rw-r--r--src/CommonAPI/DBus/DBusConnection.cpp23
3 files changed, 21 insertions, 14 deletions
diff --git a/CHANGES b/CHANGES
index cc589e1..dacec56 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
Changes
=======
+v3.1.10.2
+- Fix of calling unregisterStub() sometimes freezes
+- Fix deadlock by changing 'std::mutex connectionGuard_' to 'std::recursive_mutex' in D-Bus connection
+
v3.1.10.1
- Fix deadlock in connection: If data is currently dispatched and disconnecting tooks place it waits until disconnecting is finished. The problem is that the 'connectionGuard_' mutex is locked which is tried to be locked in 'sendDBusMessageWithReplyAsync' as well. This leads to deadlock and is fixed by removing the 'dispatchMutex' and instead of this the 'connectionGuard_' mutex is now used.
- Fix availability listeners: Use an incrementing index as an identifier for subscriptions instead of iterators to a list that will get modified. Store the receiver proxy with each listener, instead of assuming that all proxies that connect to an interface are the same.
diff --git a/include/CommonAPI/DBus/DBusConnection.hpp b/include/CommonAPI/DBus/DBusConnection.hpp
index b5ec156..90a6cb6 100644
--- a/include/CommonAPI/DBus/DBusConnection.hpp
+++ b/include/CommonAPI/DBus/DBusConnection.hpp
@@ -301,7 +301,7 @@ public:
std::string interfaceMemberSignature);
::DBusConnection* connection_;
- mutable std::mutex connectionGuard_;
+ mutable std::recursive_mutex connectionGuard_;
std::mutex signalGuard_;
std::mutex objectManagerGuard_;
@@ -365,10 +365,10 @@ public:
mutable std::mutex mainloopTimeoutsMutex_;
mutable std::mutex enforceTimeoutMutex_;
- mutable std::condition_variable enforceTimeoutCondition_;
+ mutable std::condition_variable_any enforceTimeoutCondition_;
mutable std::shared_ptr<std::thread> enforcerThread_;
- mutable std::mutex enforcerThreadMutex_;
+ mutable std::recursive_mutex enforcerThreadMutex_;
bool enforcerThreadCancelled_;
ConnectionId_t connectionId_;
@@ -386,7 +386,7 @@ public:
bool isWaitingOnFinishedDispatching_;
std::set<std::thread::id> dispatchThreads_;
- std::condition_variable dispatchCondition_;
+ std::condition_variable_any dispatchCondition_;
};
diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp
index d33847a..768f214 100644
--- a/src/CommonAPI/DBus/DBusConnection.cpp
+++ b/src/CommonAPI/DBus/DBusConnection.cpp
@@ -419,7 +419,7 @@ bool DBusConnection::connect(DBusError &dbusError, bool startDispatchThread) {
}
void DBusConnection::disconnect() {
- std::unique_lock<std::mutex> dbusConnectionLock(connectionGuard_);
+ std::unique_lock<std::recursive_mutex> dbusConnectionLock(connectionGuard_);
std::shared_ptr<DBusServiceRegistry> itsRegistry = DBusServiceRegistry::get(shared_from_this());
@@ -465,13 +465,16 @@ void DBusConnection::disconnect() {
dispatchThread_ = NULL;
}
- enforcerThreadCancelled_ = true;
- enforceTimeoutCondition_.notify_one();
+ {
+ std::lock_guard<std::recursive_mutex> enforcerLock(enforcerThreadMutex_);
+ enforcerThreadCancelled_ = true;
+ enforceTimeoutCondition_.notify_one();
+ }
+
if (enforcerThread_->joinable() &&
std::this_thread::get_id() != enforcerThread_->get_id()) {
enforcerThread_->join();
}
- enforcerThreadCancelled_ = false;
// remote mainloop watchers
dbus_connection_set_watch_functions(connection_, NULL, NULL, NULL, NULL, NULL);
@@ -506,7 +509,7 @@ bool DBusConnection::requestServiceNameAndBlock(const std::string& serviceName)
DBusError dbusError;
bool isServiceNameAcquired = false;
- std::lock_guard<std::mutex> dbusConnectionLock(connectionGuard_);
+ std::lock_guard<std::recursive_mutex> dbusConnectionLock(connectionGuard_);
auto conIter = connectionNameCount_.find(serviceName);
if (conIter == connectionNameCount_.end()) {
const int libdbusStatus = dbus_bus_request_name(connection_,
@@ -542,7 +545,7 @@ bool DBusConnection::requestServiceNameAndBlock(const std::string& serviceName)
bool DBusConnection::releaseServiceName(const std::string& serviceName) const {
DBusError dbusError;
bool isServiceNameReleased = false;
- std::lock_guard<std::mutex> dbusConnectionLock(connectionGuard_);
+ std::lock_guard<std::recursive_mutex> dbusConnectionLock(connectionGuard_);
auto conIter = connectionNameCount_.find(serviceName);
if (conIter != connectionNameCount_.end()) {
if (conIter->second == 1) {
@@ -652,7 +655,7 @@ void DBusConnection::onLibdbusDataCleanup(void *_data) {
//Would not be needed if libdbus would actually handle its timeouts for pending calls.
void DBusConnection::enforceAsynchronousTimeouts() const {
- std::unique_lock<std::mutex> itsLock(enforcerThreadMutex_);
+ std::unique_lock<std::recursive_mutex> itsLock(enforcerThreadMutex_);
while (!enforcerThreadCancelled_) {
enforceTimeoutMutex_.lock();
@@ -792,7 +795,7 @@ bool DBusConnection::sendDBusMessageWithReplyAsync(
std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler,
const CommonAPI::CallInfo *_info) const {
- std::lock_guard<std::mutex> dbusConnectionLock(connectionGuard_);
+ std::lock_guard<std::recursive_mutex> dbusConnectionLock(connectionGuard_);
if (!dbusMessage) {
COMMONAPI_ERROR(std::string(__FUNCTION__), "message == NULL");
@@ -876,7 +879,7 @@ bool DBusConnection::sendDBusMessageWithReplyAsync(
enforceTimeoutMutex_.unlock();
enforcerThreadMutex_.lock();
- enforceTimeoutCondition_.notify_all();
+ enforceTimeoutCondition_.notify_one();
enforcerThreadMutex_.unlock();
} else {
// add asyncHandler with infinite timeout to corresponding list
@@ -986,7 +989,7 @@ void DBusConnection::decrementConnection() {
}
bool DBusConnection::setDispatching(bool _isDispatching) {
- std::lock_guard<std::mutex> dispatchLock(connectionGuard_);
+ std::lock_guard<std::recursive_mutex> dispatchLock(connectionGuard_);
if(isDispatching_ == _isDispatching)
return true;