diff options
author | Jürgen Gehring <Juergen.Gehring@bmw.de> | 2016-12-12 02:23:28 -0800 |
---|---|---|
committer | Jürgen Gehring <Juergen.Gehring@bmw.de> | 2016-12-12 02:23:28 -0800 |
commit | 01c9c4b3d8627a8eab95e3dcdb5f0f4f1331b004 (patch) | |
tree | 56f7e6a6657259ef5a99ed6ec812f5cb268addc1 | |
parent | 08ee52a77e49afb2eae4ac9cb6d8698374a3d542 (diff) | |
download | genivi-common-api-dbus-runtime-01c9c4b3d8627a8eab95e3dcdb5f0f4f1331b004.tar.gz |
CommonAPI-D-Bus 3.1.10.23.1.10.2
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | include/CommonAPI/DBus/DBusConnection.hpp | 8 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusConnection.cpp | 23 |
3 files changed, 21 insertions, 14 deletions
@@ -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; |