diff options
author | Juergen Gehring <juergen.gehring@bmw.de> | 2017-02-28 03:42:58 -0800 |
---|---|---|
committer | Juergen Gehring <juergen.gehring@bmw.de> | 2017-02-28 03:42:58 -0800 |
commit | fad59c73675aea115d0c292b5743de2591bdf6b3 (patch) | |
tree | 76ce9670838f0edeb8d8777c1a9f4cc721d8fd16 | |
parent | 55559fa14073203f9efc53a6c20d0b92e9bb69e5 (diff) | |
download | genivi-common-api-dbus-runtime-fad59c73675aea115d0c292b5743de2591bdf6b3.tar.gz |
CommonAPI-D-Bus 3.1.113.1.11
76 files changed, 578 insertions, 413 deletions
@@ -1,6 +1,12 @@ Changes ======= +v3.1.11 +- Fixed availability problem of proxies that connect to legacy managed services by changing the way of resolving object paths and available interfaces +- Fixed several data races and potential deadlocks reported by the thread sanitizer +- Ensure proxy is not destroyed while callback function is invoked +- check for #define _WIN32 instead of (deprecated) WIN32 + v3.1.10.4 - Prevent crash (double free) on destruction of static objects - Fixed 'terminate called without an active exception' on verification test exit @@ -8,15 +14,6 @@ v3.1.10.4 v3.1.10.3 - Fixed crash on dlclose() -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. -- Avoid seg fault when creating a connection failed. - v3.1.10 - If an 'DBusInstanceAvailabilityStatusChangedEvent' occurs and the manager proxy was deleted, a bad_weak_ptr occurs. This is now avoided by introducing a weak_ptr. If the weak_ptr can be locked, the manager proxy was not deleted yet. - Moved mutex lock in 'DBusMainLoop::registerWatch' to avoid deadlock. @@ -29,3 +26,8 @@ v3.1.10 - Fixed THMainloopIndependence and THMainloopIntegration segfault. The problem is that a 'DBusQueueDispatchSource' has a pointer to its related 'DBusQueueWatch' as member variable and in the destructor of the dispatch source the watch is accessed. So a segfault can occur when the watch is deleted before the dispatch source. - Replaced polling mechanism in 'DBusMainLoop' from sockets to WSAEvents in combination with named pipes. - Added support for the DBus message type 'Error'. This needed the introduction of a new class ('DBusErrorEvent'), adaptions on proxy side ('DBusProxyHelper') and on stub side ('DBusStubAdapterHelper') and a libdbus patch that avoids the deletion of a message reply when an error occured / when an error reply was sent. This is necessary to deserialize the arguments of the error reply. + + + + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 9967698..350a1ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,7 +10,7 @@ PROJECT(libcommonapi-dbus) # version of CommonAPI-DBus SET( LIBCOMMONAPI_DBUS_MAJOR_VERSION 3 ) SET( LIBCOMMONAPI_DBUS_MINOR_VERSION 1 ) -SET( LIBCOMMONAPI_DBUS_PATCH_VERSION 10 ) +SET( LIBCOMMONAPI_DBUS_PATCH_VERSION 11 ) message(STATUS "Project name: ${PROJECT_NAME}") @@ -123,9 +123,9 @@ message(STATUS "CMAKE_FIND_ROOT_PATH: ${CMAKE_FIND_ROOT_PATH}") FIND_PACKAGE(PkgConfig) FIND_PACKAGE(Threads REQUIRED) if ("${USE_INSTALLED_COMMONAPI}" STREQUAL "ON") - FIND_PACKAGE(CommonAPI 3.1.10 REQUIRED CONFIG NO_CMAKE_PACKAGE_REGISTRY) + FIND_PACKAGE(CommonAPI 3.1.11 REQUIRED CONFIG NO_CMAKE_PACKAGE_REGISTRY) else() - FIND_PACKAGE(CommonAPI 3.1.10 REQUIRED CONFIG NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) + FIND_PACKAGE(CommonAPI 3.1.11 REQUIRED CONFIG NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) endif() message(STATUS "CommonAPI_CONSIDERED_CONFIGS: ${CommonAPI_CONSIDERED_CONFIGS}") @@ -1,8 +1,8 @@ ### CommonAPI C++ D-Bus Runtime ##### Copyright -Copyright (C) 2016, Bayerische Motoren Werke Aktiengesellschaft (BMW AG). -Copyright (C) 2016, GENIVI Alliance, Inc. +Copyright (C) 2016-2017, Bayerische Motoren Werke Aktiengesellschaft (BMW AG). +Copyright (C) 2016-2017, GENIVI Alliance, Inc. This file is part of GENIVI Project IPC Common API C++. Contributions are licensed to the GENIVI Alliance under one or more Contribution License Agreements or MPL 2.0. diff --git a/include/CommonAPI/DBus/CommonAPIDBus.hpp b/include/CommonAPI/DBus/CommonAPIDBus.hpp index 1be7770..3df526d 100644 --- a/include/CommonAPI/DBus/CommonAPIDBus.hpp +++ b/include/CommonAPI/DBus/CommonAPIDBus.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusAddress.hpp b/include/CommonAPI/DBus/DBusAddress.hpp index 448012c..171a482 100644 --- a/include/CommonAPI/DBus/DBusAddress.hpp +++ b/include/CommonAPI/DBus/DBusAddress.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusAddressTranslator.hpp b/include/CommonAPI/DBus/DBusAddressTranslator.hpp index b3b0dde..dd5cbef 100644 --- a/include/CommonAPI/DBus/DBusAddressTranslator.hpp +++ b/include/CommonAPI/DBus/DBusAddressTranslator.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusAttribute.hpp b/include/CommonAPI/DBus/DBusAttribute.hpp index 2fd5bd3..5db6b49 100644 --- a/include/CommonAPI/DBus/DBusAttribute.hpp +++ b/include/CommonAPI/DBus/DBusAttribute.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusClientId.hpp b/include/CommonAPI/DBus/DBusClientId.hpp index 982b4dd..f5f5e85 100644 --- a/include/CommonAPI/DBus/DBusClientId.hpp +++ b/include/CommonAPI/DBus/DBusClientId.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusConfig.hpp b/include/CommonAPI/DBus/DBusConfig.hpp index cb07461..3043c8e 100644 --- a/include/CommonAPI/DBus/DBusConfig.hpp +++ b/include/CommonAPI/DBus/DBusConfig.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusConnection.hpp b/include/CommonAPI/DBus/DBusConnection.hpp index 90a6cb6..e88eab6 100644 --- a/include/CommonAPI/DBus/DBusConnection.hpp +++ b/include/CommonAPI/DBus/DBusConnection.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -291,7 +291,7 @@ public: COMMONAPI_EXPORT static void onWakeupMainContext(void* data); - COMMONAPI_EXPORT void enforceAsynchronousTimeouts() const; + COMMONAPI_EXPORT void enforceAsynchronousTimeouts(); COMMONAPI_EXPORT static const DBusObjectPathVTable* getDBusObjectPathVTable(); COMMONAPI_EXPORT void sendPendingSelectiveSubscription(DBusProxy* proxy, @@ -300,6 +300,16 @@ public: uint32_t tag, std::string interfaceMemberSignature); + void notifyDBusSignalHandlers(DBusSignalHandlerPath handlerPath, + const DBusMessage& dbusMessage, + ::DBusHandlerResult& dbusHandlerResult); + + void notifyDBusOMSignalHandlers(const char* dbusSenderName, + const DBusMessage& dbusMessage, + ::DBusHandlerResult& dbusHandlerResult); + + void deleteAsyncHandlers(); + ::DBusConnection* connection_; mutable std::recursive_mutex connectionGuard_; @@ -387,8 +397,10 @@ public: std::set<std::thread::id> dispatchThreads_; std::condition_variable_any dispatchCondition_; -}; + std::vector<DBusMessageReplyAsyncHandler*> asyncHandlersToDelete_; + std::mutex asyncHandlersToDeleteMutex_; +}; template<class Function, class... Arguments> void FunctionQueueEntry<Function, Arguments ...>::process(std::shared_ptr<DBusConnection> _connection) { diff --git a/include/CommonAPI/DBus/DBusDaemonProxy.hpp b/include/CommonAPI/DBus/DBusDaemonProxy.hpp index 44b882b..22d461f 100644 --- a/include/CommonAPI/DBus/DBusDaemonProxy.hpp +++ b/include/CommonAPI/DBus/DBusDaemonProxy.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusDeployment.hpp b/include/CommonAPI/DBus/DBusDeployment.hpp index c6ce15c..b12d67c 100644 --- a/include/CommonAPI/DBus/DBusDeployment.hpp +++ b/include/CommonAPI/DBus/DBusDeployment.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusError.hpp b/include/CommonAPI/DBus/DBusError.hpp index bd3a636..25d7864 100644 --- a/include/CommonAPI/DBus/DBusError.hpp +++ b/include/CommonAPI/DBus/DBusError.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusErrorEvent.hpp b/include/CommonAPI/DBus/DBusErrorEvent.hpp index 2256d33..966f9e1 100644 --- a/include/CommonAPI/DBus/DBusErrorEvent.hpp +++ b/include/CommonAPI/DBus/DBusErrorEvent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusEvent.hpp b/include/CommonAPI/DBus/DBusEvent.hpp index 945988d..4d53d23 100644 --- a/include/CommonAPI/DBus/DBusEvent.hpp +++ b/include/CommonAPI/DBus/DBusEvent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusFactory.hpp b/include/CommonAPI/DBus/DBusFactory.hpp index 51ec476..157382d 100644 --- a/include/CommonAPI/DBus/DBusFactory.hpp +++ b/include/CommonAPI/DBus/DBusFactory.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,6 +18,9 @@ #include <CommonAPI/DBus/DBusTypes.hpp> namespace CommonAPI { + +class Runtime; + namespace DBus { class DBusAddress; @@ -95,6 +98,8 @@ public: // Initialization COMMONAPI_EXPORT void registerInterface(InterfaceInitFunction _function); + static std::weak_ptr<CommonAPI::Runtime> runtime_; + private: COMMONAPI_EXPORT void incrementConnection(std::shared_ptr<DBusProxyConnection>); COMMONAPI_EXPORT std::shared_ptr<DBusConnection> getConnection(const ConnectionId_t &); diff --git a/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp b/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp index 8f35928..28b41da 100644 --- a/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp +++ b/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp b/include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp index bc31a89..0a0914d 100644 --- a/include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp +++ b/include/CommonAPI/DBus/DBusFreedesktopPropertiesStub.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp b/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp index d5abcca..42b8f92 100644 --- a/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp +++ b/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusFreedesktopVariant.hpp b/include/CommonAPI/DBus/DBusFreedesktopVariant.hpp index 243604e..bd1fb58 100644 --- a/include/CommonAPI/DBus/DBusFreedesktopVariant.hpp +++ b/include/CommonAPI/DBus/DBusFreedesktopVariant.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -45,7 +45,7 @@ struct ApplyTypeCompareVisitor<Visitor_, Variant_, Deployment_, Type_, Types_... output.writeType(current, static_cast<CommonAPI::EmptyDeployment*>(nullptr)); } -#ifdef WIN32 +#ifdef _WIN32 if (_visitor.operator()<Type_>(output.getSignature())) { #else if (_visitor.template operator()<Type_>(output.getSignature())) { diff --git a/include/CommonAPI/DBus/DBusFunctionalHash.hpp b/include/CommonAPI/DBus/DBusFunctionalHash.hpp index 4903c21..fbc1ea3 100644 --- a/include/CommonAPI/DBus/DBusFunctionalHash.hpp +++ b/include/CommonAPI/DBus/DBusFunctionalHash.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusHelper.hpp b/include/CommonAPI/DBus/DBusHelper.hpp index 889cf53..ebde2b8 100644 --- a/include/CommonAPI/DBus/DBusHelper.hpp +++ b/include/CommonAPI/DBus/DBusHelper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusInputStream.hpp b/include/CommonAPI/DBus/DBusInputStream.hpp index 61e4133..fab82dd 100644 --- a/include/CommonAPI/DBus/DBusInputStream.hpp +++ b/include/CommonAPI/DBus/DBusInputStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp b/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp index 9be2e9a..91fa410 100644 --- a/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp +++ b/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusInterfaceHandler.hpp b/include/CommonAPI/DBus/DBusInterfaceHandler.hpp index fa6c0bb..9804aff 100644 --- a/include/CommonAPI/DBus/DBusInterfaceHandler.hpp +++ b/include/CommonAPI/DBus/DBusInterfaceHandler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusMainLoop.hpp b/include/CommonAPI/DBus/DBusMainLoop.hpp index b09a8f1..2ca7202 100755 --- a/include/CommonAPI/DBus/DBusMainLoop.hpp +++ b/include/CommonAPI/DBus/DBusMainLoop.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,6 +18,7 @@ #include <mutex> #include <set> #include <vector> +#include <atomic> namespace CommonAPI { namespace DBus { @@ -173,11 +174,11 @@ class DBusMainLoop { DBusMainLoopPollFd wakeFd_; -#ifdef WIN32 +#ifdef _WIN32 DBusMainLoopPollFd sendFd_; #endif - bool hasToStop_; + std::atomic<bool> hasToStop_; bool isBroken_; }; diff --git a/include/CommonAPI/DBus/DBusMainLoopContext.hpp b/include/CommonAPI/DBus/DBusMainLoopContext.hpp index 708cfa3..adf132f 100644 --- a/include/CommonAPI/DBus/DBusMainLoopContext.hpp +++ b/include/CommonAPI/DBus/DBusMainLoopContext.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -13,6 +13,7 @@ #include <list> #include <memory> #include <queue> +#include <atomic> #include <dbus/dbus.h> @@ -50,8 +51,6 @@ class DBusQueueDispatchSource: public DispatchSource { private: DBusQueueWatch* watch_; - - std::mutex watchMutex_; }; class DBusWatch: public Watch { @@ -67,7 +66,7 @@ class DBusWatch: public Watch { const pollfd& getAssociatedFileDescriptor(); -#ifdef WIN32 +#ifdef _WIN32 const HANDLE& getAssociatedEvent(); #endif @@ -79,11 +78,12 @@ class DBusWatch: public Watch { ::DBusWatch* libdbusWatch_; pollfd pollFileDescriptor_; std::vector<DispatchSource*> dependentDispatchSources_; + std::mutex dependentDispatchSourcesMutex_; std::weak_ptr<MainLoopContext> mainLoopContext_; std::weak_ptr<DBusConnection> dbusConnection_; -#ifdef WIN32 +#ifdef _WIN32 HANDLE wsaEvent_; #endif }; @@ -100,7 +100,7 @@ public: const pollfd& getAssociatedFileDescriptor(); -#ifdef WIN32 +#ifdef _WIN32 const HANDLE& getAssociatedEvent(); #endif @@ -129,11 +129,12 @@ private: std::queue<std::shared_ptr<QueueEntry>> queue_; std::mutex queueMutex_; + std::mutex dependentDispatchSourcesMutex_; std::weak_ptr<DBusConnection> connection_; const int pipeValue_; -#ifdef WIN32 +#ifdef _WIN32 HANDLE wsaEvent_; #endif @@ -157,7 +158,7 @@ class DBusTimeout: public Timeout { void setPendingCall(DBusPendingCall* _pendingCall); -#ifdef WIN32 +#ifdef _WIN32 __declspec(thread) static DBusTimeout *currentTimeout_; #else thread_local static DBusTimeout *currentTimeout_; @@ -166,7 +167,7 @@ class DBusTimeout: public Timeout { private: void recalculateDueTime(); - int64_t dueTimeInMs_; + std::atomic<int64_t> dueTimeInMs_; ::DBusTimeout* libdbusTimeout_; std::weak_ptr<MainLoopContext> mainLoopContext_; std::weak_ptr<DBusConnection> dbusConnection_; diff --git a/include/CommonAPI/DBus/DBusMessage.hpp b/include/CommonAPI/DBus/DBusMessage.hpp index ece0b21..98a668d 100644 --- a/include/CommonAPI/DBus/DBusMessage.hpp +++ b/include/CommonAPI/DBus/DBusMessage.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -14,7 +14,7 @@ #include <dbus/dbus.h> -#ifdef WIN32 +#ifdef _WIN32 #include <stdint.h> #endif diff --git a/include/CommonAPI/DBus/DBusMultiEvent.hpp b/include/CommonAPI/DBus/DBusMultiEvent.hpp index db0c1e5..cf18a48 100644 --- a/include/CommonAPI/DBus/DBusMultiEvent.hpp +++ b/include/CommonAPI/DBus/DBusMultiEvent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusObjectManager.hpp b/include/CommonAPI/DBus/DBusObjectManager.hpp index 2d36aaf..432e733 100644 --- a/include/CommonAPI/DBus/DBusObjectManager.hpp +++ b/include/CommonAPI/DBus/DBusObjectManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusObjectManagerStub.hpp b/include/CommonAPI/DBus/DBusObjectManagerStub.hpp index de8495d..d8de02d 100644 --- a/include/CommonAPI/DBus/DBusObjectManagerStub.hpp +++ b/include/CommonAPI/DBus/DBusObjectManagerStub.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusOutputStream.hpp b/include/CommonAPI/DBus/DBusOutputStream.hpp index 6814430..3cd9cb6 100644 --- a/include/CommonAPI/DBus/DBusOutputStream.hpp +++ b/include/CommonAPI/DBus/DBusOutputStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusProxy.hpp b/include/CommonAPI/DBus/DBusProxy.hpp index cc9bd06..feedb12 100644 --- a/include/CommonAPI/DBus/DBusProxy.hpp +++ b/include/CommonAPI/DBus/DBusProxy.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp b/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp index d21807d..25b2ecd 100644 --- a/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp +++ b/include/CommonAPI/DBus/DBusProxyAsyncCallbackHandler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -225,7 +225,7 @@ private: } } - //ensure that delegate object (e.g. Proxy) survives + //ensure that delegate object (i.e Proxy) is not destroyed while callback function is invoked if(auto itsDelegateObject = this->delegate_.object_.lock()) this->delegate_.function_(callStatus, std::move(std::get<ArgIndices_>(_argTuple))...); diff --git a/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp b/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp index 788c1ff..a768e45 100644 --- a/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp +++ b/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -105,9 +105,9 @@ class DBusProxyAsyncSignalMemberCallbackHandler: public DBusProxyConnection::DBu inline CallStatus handleDBusMessageReply(const CallStatus dbusMessageCallStatus, const DBusMessage& dbusMessage) const { CallStatus callStatus = dbusMessageCallStatus; - //check if object is expired - if(!delegate_.object_.expired()) - delegate_.function_(callStatus, dbusMessage, dbusSignalHandler_, tag_); + //ensure that delegate object (i.e Proxy) is not destroyed while callback function is invoked + if(auto itsDelegateObject = this->delegate_.object_.lock()) + this->delegate_.function_(callStatus, dbusMessage, dbusSignalHandler_, tag_); return callStatus; } diff --git a/include/CommonAPI/DBus/DBusProxyBase.hpp b/include/CommonAPI/DBus/DBusProxyBase.hpp index e0fbaec..5a24de4 100644 --- a/include/CommonAPI/DBus/DBusProxyBase.hpp +++ b/include/CommonAPI/DBus/DBusProxyBase.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusProxyConnection.hpp b/include/CommonAPI/DBus/DBusProxyConnection.hpp index d0db2ba..ec02082 100644 --- a/include/CommonAPI/DBus/DBusProxyConnection.hpp +++ b/include/CommonAPI/DBus/DBusProxyConnection.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusProxyHelper.hpp b/include/CommonAPI/DBus/DBusProxyHelper.hpp index 3f9e175..43655f4 100644 --- a/include/CommonAPI/DBus/DBusProxyHelper.hpp +++ b/include/CommonAPI/DBus/DBusProxyHelper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -31,7 +31,7 @@ class DBusProxy; template< class, class... > struct DBusProxyHelper; -#ifdef WIN32 +#ifdef _WIN32 // Visual Studio 2013 does not support 'magic statics' yet. // Change back when switched to Visual Studio 2015 or higher. static std::mutex callMethod_mutex_; @@ -51,7 +51,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>, const std::string &_signature, const InArgs_&... _in, CommonAPI::CallStatus &_status) { -#ifndef WIN32 +#ifndef _WIN32 static std::mutex callMethod_mutex_; #endif std::lock_guard<std::mutex> lock(callMethod_mutex_); @@ -119,7 +119,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>, const InArgs_&... _in, CommonAPI::CallStatus &_status, OutArgs_&... _out) { -#ifndef WIN32 +#ifndef _WIN32 static std::mutex callMethodWithReply_mutex_; #endif std::lock_guard<std::mutex> lock(callMethodWithReply_mutex_); @@ -160,7 +160,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>, const InArgs_&... _in, CommonAPI::CallStatus &_status, OutArgs_&... _out) { -#ifndef WIN32 +#ifndef _WIN32 static std::mutex callMethodWithReply_mutex_; #endif std::lock_guard<std::mutex> lock(callMethodWithReply_mutex_); @@ -269,7 +269,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>, const InArgs_&... _in, DelegateFunction_ _function, std::tuple<OutArgs_...> _out) { -#ifndef WIN32 +#ifndef _WIN32 static std::mutex callMethodAsync_mutex_; #endif std::lock_guard<std::mutex> lock(callMethodAsync_mutex_); @@ -307,7 +307,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>, const InArgs_&... _in, DelegateFunction_ _function, std::tuple<OutArgs_...> _out) { -#ifndef WIN32 +#ifndef _WIN32 static std::mutex callMethodAsync_mutex_; #endif std::lock_guard<std::mutex> lock(callMethodAsync_mutex_); @@ -384,7 +384,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>, CommonAPI::CallStatus &_status, OutArgs_&... _out, const std::tuple<ErrorEvents_*...> &_errorEvents){ -#ifndef WIN32 +#ifndef _WIN32 static std::mutex callMethodWithReply_mutex_; #endif std::lock_guard<std::mutex> lock(callMethodWithReply_mutex_); @@ -494,7 +494,7 @@ struct DBusProxyHelper<In_<DBusInputStream, DBusOutputStream, InArgs_...>, DelegateFunction_ _function, std::tuple<OutArgs_...> _out, const std::tuple<ErrorEvents_*...> &_errorEvents) { -#ifndef WIN32 +#ifndef _WIN32 static std::mutex callMethodAsync_mutex_; #endif std::lock_guard<std::mutex> lock(callMethodAsync_mutex_); diff --git a/include/CommonAPI/DBus/DBusProxyManager.hpp b/include/CommonAPI/DBus/DBusProxyManager.hpp index 1dd8dbe..f8829b4 100644 --- a/include/CommonAPI/DBus/DBusProxyManager.hpp +++ b/include/CommonAPI/DBus/DBusProxyManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusSelectiveEvent.hpp b/include/CommonAPI/DBus/DBusSelectiveEvent.hpp index 93bb5ea..075b819 100644 --- a/include/CommonAPI/DBus/DBusSelectiveEvent.hpp +++ b/include/CommonAPI/DBus/DBusSelectiveEvent.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusSerializableArguments.hpp b/include/CommonAPI/DBus/DBusSerializableArguments.hpp index 6b48eff..771de26 100644 --- a/include/CommonAPI/DBus/DBusSerializableArguments.hpp +++ b/include/CommonAPI/DBus/DBusSerializableArguments.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusServiceRegistry.hpp b/include/CommonAPI/DBus/DBusServiceRegistry.hpp index 497e909..3181226 100644 --- a/include/CommonAPI/DBus/DBusServiceRegistry.hpp +++ b/include/CommonAPI/DBus/DBusServiceRegistry.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusStubAdapter.hpp b/include/CommonAPI/DBus/DBusStubAdapter.hpp index 710277b..882ec8f 100644 --- a/include/CommonAPI/DBus/DBusStubAdapter.hpp +++ b/include/CommonAPI/DBus/DBusStubAdapter.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp b/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp index 3a9b7e8..50ba9ae 100644 --- a/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp +++ b/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusTypeOutputStream.hpp b/include/CommonAPI/DBus/DBusTypeOutputStream.hpp index a2e96e5..6cab51f 100644 --- a/include/CommonAPI/DBus/DBusTypeOutputStream.hpp +++ b/include/CommonAPI/DBus/DBusTypeOutputStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusTypes.hpp b/include/CommonAPI/DBus/DBusTypes.hpp index 86bed2d..ec7e092 100644 --- a/include/CommonAPI/DBus/DBusTypes.hpp +++ b/include/CommonAPI/DBus/DBusTypes.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/include/CommonAPI/DBus/DBusUtils.hpp b/include/CommonAPI/DBus/DBusUtils.hpp index d12e024..03fd401 100644 --- a/include/CommonAPI/DBus/DBusUtils.hpp +++ b/include/CommonAPI/DBus/DBusUtils.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusAddress.cpp b/src/CommonAPI/DBus/DBusAddress.cpp index d73cfc0..4819a40 100644 --- a/src/CommonAPI/DBus/DBusAddress.cpp +++ b/src/CommonAPI/DBus/DBusAddress.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusAddressTranslator.cpp b/src/CommonAPI/DBus/DBusAddressTranslator.cpp index 460ab16..49f42d4 100644 --- a/src/CommonAPI/DBus/DBusAddressTranslator.cpp +++ b/src/CommonAPI/DBus/DBusAddressTranslator.cpp @@ -1,9 +1,9 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifdef WIN32 +#ifdef _WIN32 #include <Windows.h> #else #include <unistd.h> @@ -223,7 +223,7 @@ DBusAddressTranslator::readConfiguration() { #define MAX_PATH_LEN 255 std::string config; char currentDirectory[MAX_PATH_LEN]; -#ifdef WIN32 +#ifdef _WIN32 if (GetCurrentDirectory(MAX_PATH_LEN, currentDirectory)) { #else if (getcwd(currentDirectory, MAX_PATH_LEN)) { diff --git a/src/CommonAPI/DBus/DBusClientId.cpp b/src/CommonAPI/DBus/DBusClientId.cpp index 7c9f195..12983b5 100644 --- a/src/CommonAPI/DBus/DBusClientId.cpp +++ b/src/CommonAPI/DBus/DBusClientId.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusConnection.cpp b/src/CommonAPI/DBus/DBusConnection.cpp index 3ed06a7..589b5f4 100644 --- a/src/CommonAPI/DBus/DBusConnection.cpp +++ b/src/CommonAPI/DBus/DBusConnection.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -498,11 +498,10 @@ DBusProxyConnection::ConnectionStatusEvent& DBusConnection::getConnectionStatusE //Does this need to be a weak pointer? const std::shared_ptr<DBusObjectManager> DBusConnection::getDBusObjectManager() { if (!dbusObjectManager_) { - objectManagerGuard_.lock(); + std::lock_guard<std::mutex> itsLock(objectManagerGuard_); if (!dbusObjectManager_) { dbusObjectManager_ = std::make_shared<DBusObjectManager>(shared_from_this()); } - objectManagerGuard_.unlock(); } return dbusObjectManager_; } @@ -656,140 +655,163 @@ 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::recursive_mutex> itsLock(enforcerThreadMutex_); - - while (!enforcerThreadCancelled_) { - enforceTimeoutMutex_.lock(); +void DBusConnection::enforceAsynchronousTimeouts() { + { + std::unique_lock<std::recursive_mutex> itsLock(enforcerThreadMutex_); - int timeout = std::numeric_limits<int>::max(); // not really, but nearly "forever" - if (timeoutMap_.size() > 0) { - auto minTimeoutElement = std::min_element(timeoutMap_.begin(), timeoutMap_.end(), - [] (const TimeoutMapElement& lhs, const TimeoutMapElement& rhs) { - return std::get<0>(lhs.second) < std::get<0>(rhs.second); - }); + while (!enforcerThreadCancelled_) { - auto minTimeout = std::get<0>(minTimeoutElement->second); + int timeout = std::numeric_limits<int>::max(); // not really, but nearly "forever" + { + std::lock_guard<std::mutex> itsLock(enforceTimeoutMutex_); + if (timeoutMap_.size() > 0) { + auto minTimeoutElement = std::min_element(timeoutMap_.begin(), timeoutMap_.end(), + [] (const TimeoutMapElement& lhs, const TimeoutMapElement& rhs) { + return std::get<0>(lhs.second) < std::get<0>(rhs.second); + }); - std::chrono::steady_clock::time_point now = (std::chrono::steady_clock::time_point) std::chrono::steady_clock::now(); + auto minTimeout = std::get<0>(minTimeoutElement->second); - timeout = (int)std::chrono::duration_cast<std::chrono::milliseconds>(minTimeout - now).count(); - } + std::chrono::steady_clock::time_point now = (std::chrono::steady_clock::time_point) std::chrono::steady_clock::now(); - enforceTimeoutMutex_.unlock(); + timeout = (int)std::chrono::duration_cast<std::chrono::milliseconds>(minTimeout - now).count(); + } + } - if (std::cv_status::timeout == - enforceTimeoutCondition_.wait_for(itsLock, std::chrono::milliseconds(timeout))) { + if (std::cv_status::timeout == + enforceTimeoutCondition_.wait_for(itsLock, std::chrono::milliseconds(timeout))) { - //Do not access members if the DBusConnection was destroyed during the unlocked phase. - enforceTimeoutMutex_.lock(); - auto it = timeoutMap_.begin(); - while (it != timeoutMap_.end()) { - std::chrono::steady_clock::time_point now = (std::chrono::steady_clock::time_point) std::chrono::steady_clock::now(); + //Do not access members if the DBusConnection was destroyed during the unlocked phase. + std::lock_guard<std::mutex> itsLock(enforceTimeoutMutex_); + auto it = timeoutMap_.begin(); + while (it != timeoutMap_.end()) { + std::chrono::steady_clock::time_point now = (std::chrono::steady_clock::time_point) std::chrono::steady_clock::now(); - DBusMessageReplyAsyncHandler* asyncHandler = std::get<1>(it->second); - DBusPendingCall* libdbusPendingCall = it->first; + DBusMessageReplyAsyncHandler* asyncHandler = std::get<1>(it->second); + DBusPendingCall* libdbusPendingCall = it->first; - if (now > std::get<0>(it->second)) { + if (now > std::get<0>(it->second)) { - asyncHandler->lock(); - bool executionStarted = asyncHandler->getExecutionStarted(); - bool executionFinished = asyncHandler->getExecutionFinished(); - if (!executionStarted && !executionFinished) { - asyncHandler->setTimeoutOccurred(); - if (!dbus_pending_call_get_completed(libdbusPendingCall)) { - dbus_pending_call_cancel(libdbusPendingCall); + asyncHandler->lock(); + bool executionStarted = asyncHandler->getExecutionStarted(); + bool executionFinished = asyncHandler->getExecutionFinished(); + if (!executionStarted && !executionFinished) { + asyncHandler->setTimeoutOccurred(); + if (!dbus_pending_call_get_completed(libdbusPendingCall)) { + dbus_pending_call_cancel(libdbusPendingCall); + } } - } - asyncHandler->unlock(); + asyncHandler->unlock(); - if (executionStarted && !executionFinished) { - // execution of asyncHandler is still running - // ==> add 100 ms for next timeout check - std::get<0>(it->second) = (std::chrono::steady_clock::time_point) std::chrono::steady_clock::now() + std::chrono::milliseconds(100); - } else { - if (!executionFinished) { - // execution of asyncHandler was not finished (and not started) - // => add asyncHandler to mainloopTimeouts list - DBusMessage& dbusMessageCall = std::get<2>(it->second); - - auto lockedContext = mainLoopContext_.lock(); - if (!lockedContext) { - COMMONAPI_ERROR(std::string(__FUNCTION__), "lockedContext == nullptr"); - } else { - { - std::lock_guard<std::mutex> itsLock(mainloopTimeoutsMutex_); - mainloopTimeouts_.push_back(std::make_tuple(asyncHandler, - dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT), - CallStatus::REMOTE_ERROR, - nullptr)); + if (executionStarted && !executionFinished) { + // execution of asyncHandler is still running + // ==> add 100 ms for next timeout check + std::get<0>(it->second) = (std::chrono::steady_clock::time_point) std::chrono::steady_clock::now() + std::chrono::milliseconds(100); + } else { + if (!executionFinished) { + // execution of asyncHandler was not finished (and not started) + // => add asyncHandler to mainloopTimeouts list + DBusMessage& dbusMessageCall = std::get<2>(it->second); + + auto lockedContext = mainLoopContext_.lock(); + if (!lockedContext) { + COMMONAPI_ERROR(std::string(__FUNCTION__), "lockedContext == nullptr"); + } else { + { + std::lock_guard<std::mutex> itsLock(mainloopTimeoutsMutex_); + mainloopTimeouts_.push_back(std::make_tuple(asyncHandler, + dbusMessageCall.createMethodError(DBUS_ERROR_TIMEOUT), + CallStatus::REMOTE_ERROR, + nullptr)); + } + lockedContext->wakeup(); } - lockedContext->wakeup(); + it = timeoutMap_.erase(it); + + //This unref MIGHT cause the destruction of the last callback object that references the DBusConnection. + //So after this unref has been called, it has to be ensured that continuation of the loop is an option. + dbus_pending_call_unref(libdbusPendingCall); + } else { + // execution of asyncHandler was finished + it = timeoutMap_.erase(it); + // The deletion of the async handler (which leads to destruction of the DBusProxy and DBusConnection) + // needs to be done asynchronously by the main loop + // because of a potential deadlock. + std::lock_guard<std::mutex> asyncHandlersLock(asyncHandlersToDeleteMutex_); + asyncHandlersToDelete_.push_back(asyncHandler); + proxyPushFunctionToMainLoop(std::bind(&DBusConnection::deleteAsyncHandlers, this)); } + } + } else { + asyncHandler->lock(); + bool executionFinished = asyncHandler->getExecutionFinished(); + asyncHandler->unlock(); + if (executionFinished) { + // execution of asyncHandler was finished but timeout is not expired it = timeoutMap_.erase(it); - - //This unref MIGHT cause the destruction of the last callback object that references the DBusConnection. - //So after this unref has been called, it has to be ensured that continuation of the loop is an option. - dbus_pending_call_unref(libdbusPendingCall); + // The deletion of the async handler (which leads to destruction of the DBusProxy and DBusConnection) + // needs to be done asynchronously by the main loop + // because of a potential deadlock. + std::lock_guard<std::mutex> asyncHandlersLock(asyncHandlersToDeleteMutex_); + asyncHandlersToDelete_.push_back(asyncHandler); + proxyPushFunctionToMainLoop(std::bind(&DBusConnection::deleteAsyncHandlers, this)); } else { - // execution of asyncHandler was finished - it = timeoutMap_.erase(it); - delete asyncHandler; + ++it; } } - } else { + } + } else { + + std::lock_guard<std::mutex> itsLock(enforceTimeoutMutex_); + + auto it = timeoutMap_.begin(); + while (it != timeoutMap_.end()) { + DBusMessageReplyAsyncHandler* asyncHandler = std::get<1>(it->second); asyncHandler->lock(); bool executionFinished = asyncHandler->getExecutionFinished(); asyncHandler->unlock(); if (executionFinished) { // execution of asyncHandler was finished but timeout is not expired it = timeoutMap_.erase(it); - delete asyncHandler; + // The deletion of the async handler (which leads to destruction of the DBusProxy and DBusConnection) + // needs to be done asynchronously by the main loop + // because of a potential deadlock. + std::lock_guard<std::mutex> asyncHandlersLock(asyncHandlersToDeleteMutex_); + asyncHandlersToDelete_.push_back(asyncHandler); + proxyPushFunctionToMainLoop(std::bind(&DBusConnection::deleteAsyncHandlers, this)); } else { ++it; } } } - enforceTimeoutMutex_.unlock(); - } else { - std::lock_guard<std::mutex> itsLock(enforceTimeoutMutex_); - - auto it = timeoutMap_.begin(); - while (it != timeoutMap_.end()) { - DBusMessageReplyAsyncHandler* asyncHandler = std::get<1>(it->second); - asyncHandler->lock(); - bool executionFinished = asyncHandler->getExecutionFinished(); - asyncHandler->unlock(); - if (executionFinished) { - // execution of asyncHandler was finished but timeout is not expired - it = timeoutMap_.erase(it); - delete asyncHandler; - } else { - ++it; - } - } - } - - { - std::lock_guard<std::mutex> itsLock(timeoutInfiniteAsyncHandlersMutex_); - // check for asyncHandler with infinite timeout whose execution is finished - auto it = timeoutInfiniteAsyncHandlers_.begin(); - while (it != timeoutInfiniteAsyncHandlers_.end()) { - DBusMessageReplyAsyncHandler* asyncHandler = (*it); - asyncHandler->lock(); - bool executionFinished = asyncHandler->getExecutionFinished(); - asyncHandler->unlock(); - if ( executionFinished ) { - it = timeoutInfiniteAsyncHandlers_.erase(it); - delete asyncHandler; - } else { - it++; + { + std::lock_guard<std::mutex> itsLock(timeoutInfiniteAsyncHandlersMutex_); + // check for asyncHandler with infinite timeout whose execution is finished + auto it = timeoutInfiniteAsyncHandlers_.begin(); + while (it != timeoutInfiniteAsyncHandlers_.end()) { + DBusMessageReplyAsyncHandler* asyncHandler = (*it); + asyncHandler->lock(); + bool executionFinished = asyncHandler->getExecutionFinished(); + asyncHandler->unlock(); + if ( executionFinished ) { + it = timeoutInfiniteAsyncHandlers_.erase(it); + // The deletion of the async handler (which leads to destruction of the DBusProxy and DBusConnection) + // needs to be done asynchronously by the main loop + // because of a potential deadlock. + std::lock_guard<std::mutex> asyncHandlersLock(asyncHandlersToDeleteMutex_); + asyncHandlersToDelete_.push_back(asyncHandler); + proxyPushFunctionToMainLoop(std::bind(&DBusConnection::deleteAsyncHandlers, this)); + } else { + it++; + } } } } - } + + // delete left async handlers that could not be deleted by the main loop + deleteAsyncHandlers(); } bool DBusConnection::sendDBusMessageWithReplyAsync( @@ -797,35 +819,37 @@ bool DBusConnection::sendDBusMessageWithReplyAsync( std::unique_ptr<DBusMessageReplyAsyncHandler> dbusMessageReplyAsyncHandler, const CommonAPI::CallInfo *_info) const { - std::lock_guard<std::recursive_mutex> dbusConnectionLock(connectionGuard_); - - if (!dbusMessage) { - COMMONAPI_ERROR(std::string(__FUNCTION__), "message == NULL"); - return false; - } - if (!isConnected()) { - COMMONAPI_ERROR(std::string(__FUNCTION__), "not connected"); - return false; - } - DBusPendingCall* libdbusPendingCall; dbus_bool_t libdbusSuccess; + DBusMessageReplyAsyncHandler* replyAsyncHandler = nullptr; + { + std::lock_guard<std::recursive_mutex> dbusConnectionLock(connectionGuard_); - DBusMessageReplyAsyncHandler* replyAsyncHandler = dbusMessageReplyAsyncHandler.release(); + if (!dbusMessage) { + COMMONAPI_ERROR(std::string(__FUNCTION__), "message == NULL"); + return false; + } + if (!isConnected()) { + COMMONAPI_ERROR(std::string(__FUNCTION__), "not connected"); + return false; + } - PendingCallNotificationData* userData = new PendingCallNotificationData(this, replyAsyncHandler); - DBusTimeout::currentTimeout_ = NULL; + replyAsyncHandler = dbusMessageReplyAsyncHandler.release(); - libdbusSuccess = dbus_connection_send_with_reply_set_notify(connection_, - dbusMessage.message_, - &libdbusPendingCall, - onLibdbusPendingCallNotifyThunk, - userData, - onLibdbusDataCleanup, - _info->timeout_); + PendingCallNotificationData* userData = new PendingCallNotificationData(this, replyAsyncHandler); + DBusTimeout::currentTimeout_ = NULL; - if (_info->sender_ != 0) { - COMMONAPI_DEBUG("Message sent: SenderID: ", _info->sender_, " - Serial number: ", dbusMessage.getSerial()); + libdbusSuccess = dbus_connection_send_with_reply_set_notify(connection_, + dbusMessage.message_, + &libdbusPendingCall, + onLibdbusPendingCallNotifyThunk, + userData, + onLibdbusDataCleanup, + _info->timeout_); + + if (_info->sender_ != 0) { + COMMONAPI_DEBUG("Message sent: SenderID: ", _info->sender_, " - Serial number: ", dbusMessage.getSerial()); + } } if (!libdbusSuccess || !libdbusPendingCall) { @@ -864,25 +888,28 @@ bool DBusConnection::sendDBusMessageWithReplyAsync( if(DBusTimeout::currentTimeout_) DBusTimeout::currentTimeout_->setPendingCall(libdbusPendingCall); - enforceTimeoutMutex_.lock(); - auto ret = timeoutMap_.insert( { libdbusPendingCall, toInsert } ); - if (ret.second == false) { - // key has been reused - // update the map value with the new info - DBusMessageReplyAsyncHandler* asyncHandler; - auto it = timeoutMap_.find(ret.first->first); - if(it != timeoutMap_.end()) { - asyncHandler = std::get<1>(it->second); - delete asyncHandler; + DBusMessageReplyAsyncHandler* asyncHandler = nullptr; + { + std::lock_guard<std::mutex> enforcerLock(enforceTimeoutMutex_); + auto ret = timeoutMap_.insert( { libdbusPendingCall, toInsert } ); + if (ret.second == false) { + // key has been reused + // update the map value with the new info + auto it = timeoutMap_.find(ret.first->first); + if(it != timeoutMap_.end()) { + asyncHandler = std::get<1>(it->second); + } + timeoutMap_.erase(ret.first); + timeoutMap_.insert( { libdbusPendingCall, toInsert } ); } - timeoutMap_.erase(ret.first); - timeoutMap_.insert( { libdbusPendingCall, toInsert } ); } - enforceTimeoutMutex_.unlock(); - enforcerThreadMutex_.lock(); + if(asyncHandler) { + delete asyncHandler; + } + + std::lock_guard<std::recursive_mutex> enforcerLock(enforcerThreadMutex_); enforceTimeoutCondition_.notify_one(); - enforcerThreadMutex_.unlock(); } else { // add asyncHandler with infinite timeout to corresponding list std::lock_guard<std::mutex> itsLock(timeoutInfiniteAsyncHandlersMutex_); @@ -928,12 +955,11 @@ void DBusConnection::dispatchDBusMessageReply(const DBusMessage& _reply, bool DBusConnection::singleDispatch() { std::list<MainloopTimeout_t> mainloopTimeouts; { - mainloopTimeoutsMutex_.lock(); + std::lock_guard<std::mutex> itsLock(mainloopTimeoutsMutex_); for (auto t : mainloopTimeouts_) { mainloopTimeouts.push_back(t); } mainloopTimeouts_.clear(); - mainloopTimeoutsMutex_.unlock(); } for (auto t : mainloopTimeouts) { @@ -1116,11 +1142,14 @@ DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandl interfaceName, interfaceMemberName, interfaceMemberSignature); - std::lock_guard < std::mutex > dbusSignalLock(signalGuard_); + + std::unique_lock<std::mutex> dbusSignalLock(signalGuard_); auto signalEntry = dbusSignalHandlerTable_.find(dbusSignalHandlerPath); const bool isFirstSignalMemberHandler = (signalEntry == dbusSignalHandlerTable_.end()); + auto itsHandler = dbusSignalHandler.lock(); + if (itsHandler && isFirstSignalMemberHandler) { addLibdbusSignalMatchRule(objectPath, interfaceName, interfaceMemberName, justAddFilter); @@ -1132,9 +1161,31 @@ DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandl std::make_pair(std::make_shared<std::recursive_mutex>(), std::move(handlerList)) } ); } else if (itsHandler && !isFirstSignalMemberHandler) { - signalEntry->second.first->lock(); - signalEntry->second.second[itsHandler.get()] = dbusSignalHandler; - signalEntry->second.first->unlock(); + + //get mutex for signal entry + auto signalEntryMutex = signalEntry->second.first; + + // mutex of signal entry must be locked first to avoid potential deadlock + dbusSignalLock.unlock(); + signalEntryMutex->lock(); + + dbusSignalLock.lock(); + signalEntry = dbusSignalHandlerTable_.find(dbusSignalHandlerPath); + if(signalEntry != dbusSignalHandlerTable_.end()) { + signalEntry->second.second[itsHandler.get()] = dbusSignalHandler; + } else { + //is first signal member handler again + addLibdbusSignalMatchRule(objectPath, interfaceName, interfaceMemberName, justAddFilter); + + std::map<DBusSignalHandler*, std::weak_ptr<DBusSignalHandler>> handlerList; + handlerList[itsHandler.get()] = dbusSignalHandler; + + dbusSignalHandlerTable_.insert( { + dbusSignalHandlerPath, + std::make_pair(std::make_shared<std::recursive_mutex>(), std::move(handlerList)) + } ); + } + signalEntryMutex->unlock(); } return dbusSignalHandlerPath; @@ -1143,18 +1194,27 @@ DBusProxyConnection::DBusSignalHandlerToken DBusConnection::addSignalMemberHandl bool DBusConnection::removeSignalMemberHandler(const DBusSignalHandlerToken &dbusSignalHandlerToken, const DBusSignalHandler* dbusSignalHandler) { bool lastHandlerRemoved = false; - std::lock_guard < std::mutex > dbusSignalLock(signalGuard_); + std::unique_lock<std::mutex> itsLock(signalGuard_); auto signalEntry = dbusSignalHandlerTable_.find(dbusSignalHandlerToken); if (signalEntry != dbusSignalHandlerTable_.end()) { - signalEntry->second.first->lock(); - auto selectedHandler = signalEntry->second.second.find(const_cast<DBusSignalHandler*>(dbusSignalHandler)); - if (selectedHandler != signalEntry->second.second.end()) { - signalEntry->second.second.erase(selectedHandler); - lastHandlerRemoved = (signalEntry->second.second.empty()); + auto signalEntryMutex = signalEntry->second.first; + + // mutex of signal entry must be locked first to avoid potential deadlock + itsLock.unlock(); + signalEntryMutex->lock(); + + itsLock.lock(); + signalEntry = dbusSignalHandlerTable_.find(dbusSignalHandlerToken); + if(signalEntry != dbusSignalHandlerTable_.end()) { + auto selectedHandler = signalEntry->second.second.find(const_cast<DBusSignalHandler*>(dbusSignalHandler)); + if (selectedHandler != signalEntry->second.second.end()) { + signalEntry->second.second.erase(selectedHandler); + lastHandlerRemoved = (signalEntry->second.second.empty()); + } } - signalEntry->second.first->unlock(); + signalEntryMutex->unlock(); } if (lastHandlerRemoved) { @@ -1571,42 +1631,72 @@ void DBusConnection::initLibdbusSignalFilterAfterConnect() { return isDBusMessageHandled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -template<typename DBusSignalHandlersTable> -void notifyDBusSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable, - typename DBusSignalHandlersTable::iterator& signalEntry, - const CommonAPI::DBus::DBusMessage& dbusMessage, - ::DBusHandlerResult& dbusHandlerResult) { - if (signalEntry == dbusSignalHandlerstable.end() || signalEntry->second.second.empty()) { - dbusHandlerResult = DBUS_HANDLER_RESULT_HANDLED; - return; +void DBusConnection::notifyDBusSignalHandlers(DBusSignalHandlerPath handlerPath, + const DBusMessage& dbusMessage, + ::DBusHandlerResult& dbusHandlerResult) { + + // mutex of signal entry must be locked first to avoid potential deadlock + DBusSignalHandlerTable::iterator signalEntry; + bool entryFound = false; + std::shared_ptr<std::recursive_mutex> signalEntryMutex; + { + std::lock_guard<std::mutex> itsLock(signalGuard_); + signalEntry = dbusSignalHandlerTable_.find(handlerPath); + + if(signalEntry != dbusSignalHandlerTable_.end()) { + signalEntryMutex = signalEntry->second.first; + entryFound = true; + } } - auto handlerEntry = signalEntry->second.second.begin(); - while (handlerEntry != signalEntry->second.second.end()) { - std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler = handlerEntry->second; - if(auto itsHandler = dbusSignalHandler.lock()) - itsHandler->onSignalDBusMessage(dbusMessage); - handlerEntry++; + if(entryFound) { + signalEntryMutex->lock(); + std::lock_guard<std::mutex> itsLock(signalGuard_); + signalEntry = dbusSignalHandlerTable_.find(handlerPath); + } + + // ensure, the registry survives + std::shared_ptr<DBusServiceRegistry> itsRegistry_ = DBusServiceRegistry::get(shared_from_this()); + + if(entryFound && + signalEntry != dbusSignalHandlerTable_.end() && + !signalEntry->second.second.empty()) { + + // copy signal handlers + auto dbusSignalhandlers = signalEntry->second.second; + signalEntryMutex->unlock(); + + auto handlerEntry = dbusSignalhandlers.begin(); + while (handlerEntry != dbusSignalhandlers.end()) { + std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler = handlerEntry->second; + if(auto itsHandler = dbusSignalHandler.lock()) + itsHandler->onSignalDBusMessage(dbusMessage); + handlerEntry++; + } } dbusHandlerResult = DBUS_HANDLER_RESULT_HANDLED; } -template<typename DBusSignalHandlersTable> -void notifyDBusOMSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable, - std::pair<typename DBusSignalHandlersTable::iterator, - typename DBusSignalHandlersTable::iterator>& equalRange, - const CommonAPI::DBus::DBusMessage &dbusMessage, - ::DBusHandlerResult &dbusHandlerResult) { - (void)dbusSignalHandlerstable; +void DBusConnection::notifyDBusOMSignalHandlers(const char* dbusSenderName, + const DBusMessage& dbusMessage, + ::DBusHandlerResult& dbusHandlerResult) { + std::vector<std::weak_ptr<DBusProxyConnection::DBusSignalHandler>> dbusOMSignalHandlers; + { + std::lock_guard<std::mutex> itsLock(dbusObjectManagerSignalGuard_); + auto equalRange = dbusObjectManagerSignalHandlerTable_.equal_range(dbusSenderName); - if (equalRange.first != equalRange.second) { - dbusHandlerResult = DBUS_HANDLER_RESULT_HANDLED; + if (equalRange.first != equalRange.second) { + dbusHandlerResult = DBUS_HANDLER_RESULT_HANDLED; + } + while (equalRange.first != equalRange.second) { + dbusOMSignalHandlers.push_back(equalRange.first->second.second); + equalRange.first++; + } } - while (equalRange.first != equalRange.second) { - std::weak_ptr<DBusProxyConnection::DBusSignalHandler> dbusSignalHandler = equalRange.first->second.second; - if(auto itsHandler = dbusSignalHandler.lock()) + + for(auto it = dbusOMSignalHandlers.begin(); it != dbusOMSignalHandlers.end(); ++it) { + if(auto itsHandler = it->lock()) itsHandler->onSignalDBusMessage(dbusMessage); - equalRange.first++; } } @@ -1636,40 +1726,23 @@ void notifyDBusOMSignalHandlers(DBusSignalHandlersTable& dbusSignalHandlerstable DBusMessage dbusMessage(libdbusMessage); ::DBusHandlerResult dbusHandlerResult = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - signalGuard_.lock(); - auto signalEntry = dbusSignalHandlerTable_.find(DBusSignalHandlerPath( - objectPath, - interfaceName, - interfaceMemberName, - interfaceMemberSignature)); - - if(signalEntry != dbusSignalHandlerTable_.end()) - signalEntry->second.first->lock(); - signalGuard_.unlock(); + DBusSignalHandlerPath handlerPath = DBusSignalHandlerPath( + objectPath, + interfaceName, + interfaceMemberName, + interfaceMemberSignature); - // ensure, the registry survives - std::shared_ptr<DBusServiceRegistry> itsRegistry_ = DBusServiceRegistry::get(shared_from_this()); - - notifyDBusSignalHandlers(dbusSignalHandlerTable_, - signalEntry, dbusMessage, dbusHandlerResult); - - if(signalEntry != dbusSignalHandlerTable_.end()) - signalEntry->second.first->unlock(); + notifyDBusSignalHandlers(handlerPath, dbusMessage, dbusHandlerResult); if (dbusMessage.hasInterfaceName("org.freedesktop.DBus.ObjectManager")) { + const char* dbusSenderName = dbusMessage.getSender(); if (NULL == dbusSenderName) { COMMONAPI_ERROR(std::string(__FUNCTION__), " dbusSenderName == NULL"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - dbusObjectManagerSignalGuard_.lock(); - auto dbusObjectManagerSignalHandlerIteratorPair = dbusObjectManagerSignalHandlerTable_.equal_range(dbusSenderName); - notifyDBusOMSignalHandlers(dbusObjectManagerSignalHandlerTable_, - dbusObjectManagerSignalHandlerIteratorPair, - dbusMessage, - dbusHandlerResult); - dbusObjectManagerSignalGuard_.unlock(); + notifyDBusOMSignalHandlers(dbusSenderName, dbusMessage, dbusHandlerResult); } return dbusHandlerResult; @@ -1756,5 +1829,20 @@ void DBusConnection::setPendingCallTimedOut(DBusPendingCall* _pendingCall, ::DBu } } +void DBusConnection::deleteAsyncHandlers() { + std::vector<DBusMessageReplyAsyncHandler*> asyncHandlers; + { + std::lock_guard<std::mutex> asyncHandlersLock(asyncHandlersToDeleteMutex_); + asyncHandlers = asyncHandlersToDelete_; + asyncHandlersToDelete_.clear(); + } + + auto it = asyncHandlers.begin(); + while(it != asyncHandlers.end()) { + delete *it; + it = asyncHandlers.erase(it); + } +} + } // namespace DBus } // namespace CommonAPI diff --git a/src/CommonAPI/DBus/DBusDaemonProxy.cpp b/src/CommonAPI/DBus/DBusDaemonProxy.cpp index 3b5b29f..7c2ce50 100644 --- a/src/CommonAPI/DBus/DBusDaemonProxy.cpp +++ b/src/CommonAPI/DBus/DBusDaemonProxy.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusError.cpp b/src/CommonAPI/DBus/DBusError.cpp index 884f23b..4b51318 100644 --- a/src/CommonAPI/DBus/DBusError.cpp +++ b/src/CommonAPI/DBus/DBusError.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusFactory.cpp b/src/CommonAPI/DBus/DBusFactory.cpp index 31a44c4..99f7e8e 100644 --- a/src/CommonAPI/DBus/DBusFactory.cpp +++ b/src/CommonAPI/DBus/DBusFactory.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,19 +17,19 @@ namespace CommonAPI { namespace DBus { -static std::weak_ptr<CommonAPI::Runtime> runtime__; - INITIALIZER(FactoryInit) { - runtime__ = Runtime::get(); - Runtime::get()->registerFactory("dbus", Factory::get()); + Factory::runtime_ = Runtime::get(); + Factory::runtime_.lock()->registerFactory("dbus", Factory::get()); } DEINITIALIZER(FactoryDeinit) { - if (auto rt = runtime__.lock()) { + if (auto rt = Factory::runtime_.lock()) { rt->unregisterFactory("dbus"); } } +std::weak_ptr<CommonAPI::Runtime> Factory::runtime_; + std::shared_ptr<CommonAPI::DBus::Factory> Factory::get() { static std::shared_ptr<Factory> theFactory = std::make_shared<Factory>(); @@ -44,7 +44,7 @@ Factory::~Factory() { void Factory::init() { -#ifndef WIN32 +#ifndef _WIN32 std::lock_guard<std::mutex> itsLock(initializerMutex_); #endif if (!isInitialized_) { @@ -56,7 +56,7 @@ Factory::init() { void Factory::registerInterface(InterfaceInitFunction _function) { -#ifndef WIN32 +#ifndef _WIN32 std::lock_guard<std::mutex> itsLock(initializerMutex_); #endif if (isInitialized_) { diff --git a/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp b/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp index f41b77e..d9c950f 100644 --- a/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp +++ b/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusFunctionalHash.cpp b/src/CommonAPI/DBus/DBusFunctionalHash.cpp index 5e11bfc..c02150a 100644 --- a/src/CommonAPI/DBus/DBusFunctionalHash.cpp +++ b/src/CommonAPI/DBus/DBusFunctionalHash.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusInputStream.cpp b/src/CommonAPI/DBus/DBusInputStream.cpp index 0c838a0..c13353e 100644 --- a/src/CommonAPI/DBus/DBusInputStream.cpp +++ b/src/CommonAPI/DBus/DBusInputStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp b/src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp index a8d538d..8b88753 100644 --- a/src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp +++ b/src/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusMainLoop.cpp b/src/CommonAPI/DBus/DBusMainLoop.cpp index 5bf27a2..6b3d5e6 100755 --- a/src/CommonAPI/DBus/DBusMainLoop.cpp +++ b/src/CommonAPI/DBus/DBusMainLoop.cpp @@ -1,9 +1,9 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifdef WIN32 +#ifdef _WIN32 #include <WinSock2.h> #include <ws2tcpip.h> #include <atomic> @@ -28,7 +28,7 @@ DBusMainLoop::DBusMainLoop(std::shared_ptr<MainLoopContext> context) currentMinimalTimeoutInterval_(TIMEOUT_INFINITE), hasToStop_(false), isBroken_(false) { -#ifdef WIN32 +#ifdef _WIN32 WSADATA wsaData; int iResult; @@ -188,7 +188,7 @@ DBusMainLoop::~DBusMainLoop() { context_->unsubscribeForTimeouts(timeoutSourceListenerSubscription_); context_->unsubscribeForWakeupEvents(wakeupListenerSubscription_); -#ifdef WIN32 +#ifdef _WIN32 // shutdown the connection since no more data will be sent int iResult = shutdown(wakeFd_.fd, SD_SEND); if (iResult == SOCKET_ERROR) { @@ -403,20 +403,44 @@ bool DBusMainLoop::prepare(const int64_t& timeout) { } void DBusMainLoop::poll() { - int managedFileDescriptorOffset = 0; + + // copy file descriptors + std::vector<DBusMainLoopPollFd> fileDescriptors; { std::lock_guard<std::mutex> itsLock(fileDescriptorsMutex_); - for (auto fileDescriptor = managedFileDescriptors_.begin() + managedFileDescriptorOffset; fileDescriptor != managedFileDescriptors_.end(); ++fileDescriptor) { + for (auto fileDescriptor = managedFileDescriptors_.begin(); + fileDescriptor != managedFileDescriptors_.end(); + ++fileDescriptor) { (*fileDescriptor).revents = 0; + fileDescriptors.push_back(*fileDescriptor); } } -#ifdef WIN32 - int numReadyFileDescriptors = WSAPoll(&managedFileDescriptors_[0], managedFileDescriptors_.size(), int(currentMinimalTimeoutInterval_)); +#ifdef _WIN32 + int numReadyFileDescriptors = WSAPoll(&fileDescriptors[0], fileDescriptors.size(), int(currentMinimalTimeoutInterval_)); #else - int numReadyFileDescriptors = ::poll(&(managedFileDescriptors_[0]), - managedFileDescriptors_.size(), int(currentMinimalTimeoutInterval_)); + int numReadyFileDescriptors = ::poll(&(fileDescriptors[0]), + fileDescriptors.size(), int(currentMinimalTimeoutInterval_)); #endif + + // update file descriptors + { + std::lock_guard<std::mutex> itsLock(fileDescriptorsMutex_); + for (auto itFds = fileDescriptors.begin(); + itFds != fileDescriptors.end(); + itFds++) { + for(auto itManagedFds = managedFileDescriptors_.begin(); + itManagedFds != managedFileDescriptors_.end(); + ++itManagedFds) { + if((*itFds).fd == (*itManagedFds).fd && + (*itFds).events == (*itManagedFds).events) { + (*itManagedFds).revents = (*itFds).revents; + continue; + } + } + } + } + if (!numReadyFileDescriptors) { int64_t currentContextTime = getCurrentTimeInMs(); @@ -449,6 +473,7 @@ void DBusMainLoop::poll() { } // If the wakeup descriptor woke us up, we must acknowledge + std::lock_guard<std::mutex> itsLock(fileDescriptorsMutex_); if (managedFileDescriptors_[0].revents) { wakeupAck(); } @@ -564,7 +589,7 @@ void DBusMainLoop::dispatch() { } void DBusMainLoop::wakeup() { -#ifdef WIN32 +#ifdef _WIN32 // Send an initial buffer char *sendbuf = "1"; @@ -585,7 +610,7 @@ void DBusMainLoop::wakeup() { } void DBusMainLoop::wakeupAck() { -#ifdef WIN32 +#ifdef _WIN32 // Receive until the peer closes the connection int iResult; char recvbuf[DEFAULT_BUFLEN]; @@ -704,7 +729,7 @@ void DBusMainLoop::registerWatch(Watch* watch, std::lock_guard<std::mutex> itsLock(watchesMutex_); std::mutex* mtx = new std::mutex; -#ifdef WIN32 +#ifdef _WIN32 std::atomic_signal_fence(std::memory_order_acq_rel); #else asm volatile ("":::"memory"); diff --git a/src/CommonAPI/DBus/DBusMainLoopContext.cpp b/src/CommonAPI/DBus/DBusMainLoopContext.cpp index 3124027..c44c16d 100644 --- a/src/CommonAPI/DBus/DBusMainLoopContext.cpp +++ b/src/CommonAPI/DBus/DBusMainLoopContext.cpp @@ -1,9 +1,9 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifdef WIN32 +#ifdef _WIN32 #include <WinSock2.h> #include <ws2tcpip.h> #else @@ -48,25 +48,20 @@ DBusQueueDispatchSource::DBusQueueDispatchSource(DBusQueueWatch* watch) : } DBusQueueDispatchSource::~DBusQueueDispatchSource() { - std::unique_lock<std::mutex> itsLock(watchMutex_); watch_->removeDependentDispatchSource(this); } bool DBusQueueDispatchSource::prepare(int64_t& timeout) { - std::unique_lock<std::mutex> itsLock(watchMutex_); timeout = -1; return !watch_->emptyQueue(); } bool DBusQueueDispatchSource::check() { - std::unique_lock<std::mutex> itsLock(watchMutex_); return !watch_->emptyQueue(); } bool DBusQueueDispatchSource::dispatch() { - std::unique_lock<std::mutex> itsLock(watchMutex_); - if (!watch_->emptyQueue()) { - auto queueEntry = watch_->frontQueue(); + if (auto queueEntry = watch_->frontQueue()) { watch_->popQueue(); watch_->processQueueEntry(queueEntry); } @@ -101,7 +96,7 @@ void DBusWatch::startWatching() { pollFlags |= POLLOUT; } -#ifdef WIN32 +#ifdef _WIN32 pollFileDescriptor_.fd = dbus_watch_get_socket(libdbusWatch_); wsaEvent_ = WSACreateEvent(); WSAEventSelect(pollFileDescriptor_.fd, wsaEvent_, FD_READ); @@ -131,14 +126,14 @@ const pollfd& DBusWatch::getAssociatedFileDescriptor() { return pollFileDescriptor_; } -#ifdef WIN32 +#ifdef _WIN32 const HANDLE& DBusWatch::getAssociatedEvent() { return wsaEvent_; } #endif void DBusWatch::dispatch(unsigned int eventFlags) { -#ifdef WIN32 +#ifdef _WIN32 unsigned int dbusWatchFlags = 0; if (eventFlags & (POLLRDBAND | POLLRDNORM)) { @@ -173,15 +168,17 @@ void DBusWatch::dispatch(unsigned int eventFlags) { } const std::vector<DispatchSource*>& DBusWatch::getDependentDispatchSources() { + std::lock_guard<std::mutex> itsLock(dependentDispatchSourcesMutex_); return dependentDispatchSources_; } void DBusWatch::addDependentDispatchSource(DispatchSource* dispatchSource) { + std::lock_guard<std::mutex> itsLock(dependentDispatchSourcesMutex_); dependentDispatchSources_.push_back(dispatchSource); } DBusQueueWatch::DBusQueueWatch(std::shared_ptr<DBusConnection> _connection) : pipeValue_(4) { -#ifdef WIN32 +#ifdef _WIN32 WSADATA wsaData; int iResult; @@ -316,7 +313,7 @@ DBusQueueWatch::DBusQueueWatch(std::shared_ptr<DBusConnection> _connection) : pi } DBusQueueWatch::~DBusQueueWatch() { -#ifdef WIN32 +#ifdef _WIN32 // shutdown the connection since no more data will be sent int iResult = shutdown(pipeFileDescriptors_[0], SD_SEND); if (iResult == SOCKET_ERROR) { @@ -348,21 +345,24 @@ const pollfd& DBusQueueWatch::getAssociatedFileDescriptor() { return pollFileDescriptor_; } -#ifdef WIN32 +#ifdef _WIN32 const HANDLE& DBusQueueWatch::getAssociatedEvent() { return wsaEvent_; } #endif const std::vector<DispatchSource*>& DBusQueueWatch::getDependentDispatchSources() { + std::lock_guard<std::mutex> itsLock(dependentDispatchSourcesMutex_); return dependentDispatchSources_; } void DBusQueueWatch::addDependentDispatchSource(CommonAPI::DispatchSource* _dispatchSource) { + std::lock_guard<std::mutex> itsLock(dependentDispatchSourcesMutex_); dependentDispatchSources_.push_back(_dispatchSource); } void DBusQueueWatch::removeDependentDispatchSource(CommonAPI::DispatchSource* _dispatchSource) { + std::lock_guard<std::mutex> itsLock(dependentDispatchSourcesMutex_); std::vector<CommonAPI::DispatchSource*>::iterator it; for (it = dependentDispatchSources_.begin(); it != dependentDispatchSources_.end(); it++) { @@ -377,7 +377,7 @@ void DBusQueueWatch::pushQueue(std::shared_ptr<QueueEntry> _queueEntry) { std::unique_lock<std::mutex> itsLock(queueMutex_); queue_.push(_queueEntry); -#ifdef WIN32 +#ifdef _WIN32 // Send an initial buffer char *sendbuf = "1"; @@ -399,7 +399,7 @@ void DBusQueueWatch::pushQueue(std::shared_ptr<QueueEntry> _queueEntry) { void DBusQueueWatch::popQueue() { std::unique_lock<std::mutex> itsLock(queueMutex_); -#ifdef WIN32 +#ifdef _WIN32 // Receive until the peer closes the connection int iResult; char recvbuf[1]; @@ -428,7 +428,11 @@ void DBusQueueWatch::popQueue() { std::shared_ptr<QueueEntry> DBusQueueWatch::frontQueue() { std::unique_lock<std::mutex> itsLock(queueMutex_); - return queue_.front(); + if(queue_.empty()) { + return NULL; + } else { + return queue_.front(); + } } bool DBusQueueWatch::emptyQueue() { @@ -444,7 +448,7 @@ void DBusQueueWatch::processQueueEntry(std::shared_ptr<QueueEntry> _queueEntry) } } -#ifdef WIN32 +#ifdef _WIN32 __declspec(thread) DBusTimeout* DBusTimeout::currentTimeout_ = NULL; #else thread_local DBusTimeout* DBusTimeout::currentTimeout_ = NULL; diff --git a/src/CommonAPI/DBus/DBusMessage.cpp b/src/CommonAPI/DBus/DBusMessage.cpp index 927624c..9321315 100644 --- a/src/CommonAPI/DBus/DBusMessage.cpp +++ b/src/CommonAPI/DBus/DBusMessage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusObjectManager.cpp b/src/CommonAPI/DBus/DBusObjectManager.cpp index c9484fd..85fdbf4 100644 --- a/src/CommonAPI/DBus/DBusObjectManager.cpp +++ b/src/CommonAPI/DBus/DBusObjectManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusObjectManagerStub.cpp b/src/CommonAPI/DBus/DBusObjectManagerStub.cpp index 20bbf1d..226c825 100644 --- a/src/CommonAPI/DBus/DBusObjectManagerStub.cpp +++ b/src/CommonAPI/DBus/DBusObjectManagerStub.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusOutputStream.cpp b/src/CommonAPI/DBus/DBusOutputStream.cpp index 564aa61..ae42e36 100644 --- a/src/CommonAPI/DBus/DBusOutputStream.cpp +++ b/src/CommonAPI/DBus/DBusOutputStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusProxy.cpp b/src/CommonAPI/DBus/DBusProxy.cpp index 2d19670..ef6388b 100644 --- a/src/CommonAPI/DBus/DBusProxy.cpp +++ b/src/CommonAPI/DBus/DBusProxy.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -93,7 +93,6 @@ void DBusProxy::availabilityTimeoutThreadHandler() const { if (now > std::get<0>(*it)) { //timeout - availabilityMutex_.lock(); std::chrono::steady_clock::time_point timepoint_; if(isAvailable()) callbacks.push_back(std::make_tuple(callback, std::move(std::get<2>(*it)), @@ -104,10 +103,8 @@ void DBusProxy::availabilityTimeoutThreadHandler() const { AvailabilityStatus::NOT_AVAILABLE, timepoint_)); it = timeouts_.erase(it); - availabilityMutex_.unlock(); } else { //timeout not expired - availabilityMutex_.lock(); if(isAvailable()) { callbacks.push_back(std::make_tuple(callback, std::move(std::get<2>(*it)), AvailabilityStatus::AVAILABLE, @@ -116,7 +113,6 @@ void DBusProxy::availabilityTimeoutThreadHandler() const { } else { ++it; } - availabilityMutex_.unlock(); } } @@ -134,7 +130,6 @@ void DBusProxy::availabilityTimeoutThreadHandler() const { while (it != timeouts_.end()) { isAvailableAsyncCallback callback = std::get<1>(*it); - availabilityMutex_.lock(); if(isAvailable()) { callbacks.push_back(std::make_tuple(callback, std::move(std::get<2>(*it)), AvailabilityStatus::AVAILABLE, @@ -143,7 +138,6 @@ void DBusProxy::availabilityTimeoutThreadHandler() const { } else { ++it; } - availabilityMutex_.unlock(); } timeoutsMutex_.unlock(); @@ -214,6 +208,7 @@ DBusProxy::~DBusProxy() { } bool DBusProxy::isAvailable() const { + std::lock_guard<std::mutex>itsLock(availabilityMutex_); return (availabilityStatus_ == AvailabilityStatus::AVAILABLE); } @@ -221,7 +216,7 @@ bool DBusProxy::isAvailableBlocking() const { std::unique_lock<std::mutex> lock(availabilityMutex_); if(!getDBusConnection()->hasDispatchThread()) { - return isAvailable(); + return (availabilityStatus_ == AvailabilityStatus::AVAILABLE); } while (availabilityStatus_ != AvailabilityStatus::AVAILABLE) { diff --git a/src/CommonAPI/DBus/DBusProxyBase.cpp b/src/CommonAPI/DBus/DBusProxyBase.cpp index 3052f9e..d24e58b 100644 --- a/src/CommonAPI/DBus/DBusProxyBase.cpp +++ b/src/CommonAPI/DBus/DBusProxyBase.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusProxyManager.cpp b/src/CommonAPI/DBus/DBusProxyManager.cpp index cedd58b..a522bf4 100644 --- a/src/CommonAPI/DBus/DBusProxyManager.cpp +++ b/src/CommonAPI/DBus/DBusProxyManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/CommonAPI/DBus/DBusServiceRegistry.cpp b/src/CommonAPI/DBus/DBusServiceRegistry.cpp index 7ad5987..4ef9fbc 100644 --- a/src/CommonAPI/DBus/DBusServiceRegistry.cpp +++ b/src/CommonAPI/DBus/DBusServiceRegistry.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -22,7 +22,7 @@ static CommonAPI::CallInfo serviceRegistryInfo(10000); std::shared_ptr<DBusServiceRegistry> DBusServiceRegistry::get(std::shared_ptr<DBusProxyConnection> _connection) { - std::lock_guard<std::mutex> itsGuard(registriesMutex_); + std::unique_lock<std::mutex> itsGuard(registriesMutex_); auto registries = getRegistryMap(); auto registryIterator = registries->find(_connection); if (registryIterator != registries->end()) @@ -31,8 +31,9 @@ DBusServiceRegistry::get(std::shared_ptr<DBusProxyConnection> _connection) { std::shared_ptr<DBusServiceRegistry> registry = std::make_shared<DBusServiceRegistry>(_connection); if (registry) { - registry->init(); registries->insert( { _connection, registry } ); + itsGuard.unlock(); + registry->init(); } return registry; } @@ -108,13 +109,13 @@ DBusServiceRegistry::subscribeAvailabilityListener( DBusAddress dbusAddress; translator_->translate(_address, dbusAddress); + dbusServicesMutex_.lock(); if (notificationThread_ == std::this_thread::get_id()) { COMMONAPI_ERROR( "You must not build proxies in callbacks of ProxyStatusEvent.", " Please refer to the documentation for suggestions how to avoid this."); } - dbusServicesMutex_.lock(); auto& dbusServiceListenersRecord = dbusServiceListenersMap[dbusAddress.getService()]; if (dbusServiceListenersRecord.uniqueBusNameState == DBusRecordState::AVAILABLE) { COMMONAPI_ERROR(std::string(__FUNCTION__), " uniqueBusName ", dbusServiceListenersRecord.uniqueBusName, " already AVAILABLE"); @@ -610,15 +611,6 @@ DBusServiceRegistry::getDBusObjectPathCacheReference( DBusUniqueNameRecord& dbusUniqueNameRecord) { const bool isFirstDBusObjectPathCache = dbusUniqueNameRecord.dbusObjectPathsCache.empty(); - auto dbusObjectPathCacheIterator = dbusUniqueNameRecord.dbusObjectPathsCache.find(dbusObjectPath); - if(dbusObjectPathCacheIterator == dbusUniqueNameRecord.dbusObjectPathsCache.end()) { - DBusObjectPathCache objectPathCache; - objectPathCache.serviceName = dbusServiceName; - std::unordered_map<std::string, DBusObjectPathCache>::value_type value (dbusObjectPath, std::move(objectPathCache)); - dbusUniqueNameRecord.dbusObjectPathsCache.insert(std::move(value)); - dbusObjectPathCacheIterator = dbusUniqueNameRecord.dbusObjectPathsCache.find(dbusObjectPath); - } - if (isFirstDBusObjectPathCache) { auto dbusProxyConnection = dbusDaemonProxy_->getDBusConnection(); const bool isSubscriptionSuccessful = dbusProxyConnection->addObjectManagerSignalMemberHandler( @@ -629,6 +621,15 @@ DBusServiceRegistry::getDBusObjectPathCacheReference( } } + auto dbusObjectPathCacheIterator = dbusUniqueNameRecord.dbusObjectPathsCache.find(dbusObjectPath); + if(dbusObjectPathCacheIterator == dbusUniqueNameRecord.dbusObjectPathsCache.end()) { + DBusObjectPathCache objectPathCache; + objectPathCache.serviceName = dbusServiceName; + std::unordered_map<std::string, DBusObjectPathCache>::value_type value (dbusObjectPath, std::move(objectPathCache)); + dbusUniqueNameRecord.dbusObjectPathsCache.insert(std::move(value)); + dbusObjectPathCacheIterator = dbusUniqueNameRecord.dbusObjectPathsCache.find(dbusObjectPath); + } + if (dbusObjectPathCacheIterator->second.state == DBusRecordState::UNKNOWN && resolveObjectPathWithObjectManager(dbusServiceUniqueName, dbusObjectPath)) { dbusObjectPathCacheIterator->second.state = DBusRecordState::RESOLVING; @@ -677,7 +678,6 @@ void DBusServiceRegistry::releaseDBusObjectPathCacheReference(const std::string& const bool isLastDBusObjectPathCache = dbusUniqueNameRecord.dbusObjectPathsCache.empty(); if (isLastDBusObjectPathCache) { - dbusServicesMutex_.unlock(); auto dbusProxyConnection = dbusDaemonProxy_->getDBusConnection(); const bool isSubscriptionCancelled = dbusProxyConnection->removeObjectManagerSignalMemberHandler( dbusServiceListenersRecord.uniqueBusName, @@ -685,7 +685,6 @@ void DBusServiceRegistry::releaseDBusObjectPathCacheReference(const std::string& if (!isSubscriptionCancelled) { COMMONAPI_ERROR(std::string(__FUNCTION__), ": still subscribed too ", dbusServiceListenersRecord.uniqueBusName); } - dbusServicesMutex_.lock(); } } } @@ -778,9 +777,9 @@ void DBusServiceRegistry::onGetManagedObjectsCallbackResolve(const CallStatus& c const std::string& dbusServiceUniqueName, const std::string& dbusObjectPath) { + dbusServicesMutex_.lock(); if(callStatus == CallStatus::SUCCESS) { //has object manager - bool objectPathFound = false; for(auto objectPathDict : availableServiceInstances) { std::string objectPath = objectPathDict.first; @@ -788,38 +787,36 @@ void DBusServiceRegistry::onGetManagedObjectsCallbackResolve(const CallStatus& c continue; // object path that should be resolved is found --> resolve - objectPathFound = true; CommonAPI::DBus::DBusObjectManagerStub::DBusInterfacesAndPropertiesDict interfacesAndPropertiesDict = objectPathDict.second; for(auto interfaceDict : interfacesAndPropertiesDict) { std::string interfaceName = interfaceDict.first; - dbusServicesMutex_.lock(); processManagedObject(dbusObjectPath, dbusServiceUniqueName, interfaceName); - dbusServicesMutex_.unlock(); } } - if(!objectPathFound) { + // resolve further interfaces with the help of the manager + bool managerFound = false; + std::string objectPathManager = dbusObjectPath.substr(0, dbusObjectPath.find_last_of("\\/")); + for(auto objectPathDict : availableServiceInstances) + { + // check if the main part of the object path is in the list. // if it is, the object path could be managed. // else, it maybe existed a while back but is now gone, in which case just ignore. + std::string objectPath = objectPathDict.first; + if (dbusObjectPath.substr(0, objectPath.size()) != objectPath) + continue; - std::string objectPathManager = dbusObjectPath.substr(0, dbusObjectPath.find_last_of("\\/")); - for(auto objectPathDict : availableServiceInstances) - { - - std::string objectPath = objectPathDict.first; - - if (dbusObjectPath.substr(0, objectPath.size()) != objectPath) - continue; - - // also check that the next character in dbusObject path is a slash or a backslash, - // so that we can make sure that we have compared against a full path element + // also check that the next character in dbusObject path is a slash or a backslash, + // so that we can make sure that we have compared against a full path element + if(dbusObjectPath != objectPath) { auto delimiter = dbusObjectPath.at(objectPath.size()); if (delimiter != '\\' && delimiter != '/') continue; - // object path is managed. Try to resolve object path with the help of the manager + managerFound = true; + auto getManagedObjectsCallback = std::bind( &DBusServiceRegistry::onGetManagedObjectsCallbackResolve, shared_from_this(), @@ -828,13 +825,41 @@ void DBusServiceRegistry::onGetManagedObjectsCallbackResolve(const CallStatus& c dbusServiceUniqueName, dbusObjectPath); getManagedObjectsAsync(dbusServiceUniqueName, objectPathManager, getManagedObjectsCallback); + } + } + + if(!managerFound) { + //mark object path as resolved + auto dbusServiceUniqueNameIterator = dbusUniqueNamesMap_.find(dbusServiceUniqueName); + const bool isDBusServiceUniqueNameFound = (dbusServiceUniqueNameIterator != dbusUniqueNamesMap_.end()); + + if (!isDBusServiceUniqueNameFound) { + dbusServicesMutex_.unlock(); + return; + } + + DBusUniqueNameRecord& dbusUniqueNameRecord = dbusServiceUniqueNameIterator->second; + auto dbusObjectPathIterator = dbusUniqueNameRecord.dbusObjectPathsCache.find(dbusObjectPath); + const bool isDBusObjectPathFound = (dbusObjectPathIterator != dbusUniqueNameRecord.dbusObjectPathsCache.end()); + + if (!isDBusObjectPathFound) { + dbusServicesMutex_.unlock(); + return; } + DBusObjectPathCache& dbusObjectPathRecord = dbusObjectPathIterator->second; + + dbusObjectPathRecord.state = DBusRecordState::RESOLVED; + if(dbusObjectPathRecord.futureOnResolve.valid()) + dbusObjectPathRecord.promiseOnResolve.set_value(dbusObjectPathRecord.state); + + dbusUniqueNameRecord.objectPathsState = DBusRecordState::RESOLVED; } } else { COMMONAPI_ERROR("There is no Object Manager that manages " + dbusObjectPath + ". Resolving failed!"); } + dbusServicesMutex_.unlock(); } void DBusServiceRegistry::processManagedObject(const std::string& dbusObjectPath, @@ -862,12 +887,6 @@ void DBusServiceRegistry::processManagedObject(const std::string& dbusObjectPath dbusObjectPathRecord.dbusInterfaceNamesCache.insert(interfaceName); } - dbusObjectPathRecord.state = DBusRecordState::RESOLVED; - if(dbusObjectPathRecord.futureOnResolve.valid()) - dbusObjectPathRecord.promiseOnResolve.set_value(dbusObjectPathRecord.state); - - dbusUniqueNameRecord.objectPathsState = DBusRecordState::RESOLVED; - notifyDBusServiceListeners( dbusUniqueNameRecord, dbusObjectPath, @@ -981,7 +1000,19 @@ void DBusServiceRegistry::onDBusServiceNotAvailable(DBusServiceListenersRecord& for (auto dbusObjectPathListenersIterator = dbusServiceListenersRecord.dbusObjectPathListenersMap.begin(); dbusObjectPathListenersIterator != dbusServiceListenersRecord.dbusObjectPathListenersMap.end(); ) { auto& dbusInterfaceNameListenersMap = dbusObjectPathListenersIterator->second; - notifyDBusObjectPathResolved(dbusInterfaceNameListenersMap, dbusInterfaceNamesCache); + + for (auto dbusInterfaceNameListenersIterator = dbusInterfaceNameListenersMap.begin(); + dbusInterfaceNameListenersIterator != dbusInterfaceNameListenersMap.end();) { + auto& dbusInterfaceNameListenersRecord = dbusInterfaceNameListenersIterator->second; + + notifyDBusInterfaceNameListeners(dbusInterfaceNameListenersRecord, false); + + if (dbusInterfaceNameListenersRecord.listenerList.empty()) { + dbusInterfaceNameListenersIterator = dbusInterfaceNameListenersMap.erase(dbusInterfaceNameListenersIterator); + } else { + dbusInterfaceNameListenersIterator++; + } + } if (dbusInterfaceNameListenersMap.empty()) { dbusObjectPathListenersIterator = dbusServiceListenersRecord.dbusObjectPathListenersMap.erase( @@ -1036,19 +1067,21 @@ void DBusServiceRegistry::notifyDBusServiceListeners(const DBusUniqueNameRecord& void DBusServiceRegistry::notifyDBusObjectPathResolved(DBusInterfaceNameListenersMap& dbusInterfaceNameListenersMap, const std::unordered_set<std::string>& dbusInterfaceNames) { - for (auto dbusObjectPathListenersIterator = dbusInterfaceNameListenersMap.begin(); - dbusObjectPathListenersIterator != dbusInterfaceNameListenersMap.end();) { - const auto& listenersDBusInterfaceName = dbusObjectPathListenersIterator->first; - auto& dbusInterfaceNameListenersRecord = dbusObjectPathListenersIterator->second; + for (auto dbusInterfaceNameListenersIterator = dbusInterfaceNameListenersMap.begin(); + dbusInterfaceNameListenersIterator != dbusInterfaceNameListenersMap.end();) { + const auto& listenersDBusInterfaceName = dbusInterfaceNameListenersIterator->first; + auto& dbusInterfaceNameListenersRecord = dbusInterfaceNameListenersIterator->second; const auto& dbusInterfaceNameIterator = dbusInterfaceNames.find(listenersDBusInterfaceName); - const bool isDBusInterfaceNameAvailable = (dbusInterfaceNameIterator != dbusInterfaceNames.end()); - notifyDBusInterfaceNameListeners(dbusInterfaceNameListenersRecord, isDBusInterfaceNameAvailable); + + if(dbusInterfaceNameIterator != dbusInterfaceNames.end()) { + notifyDBusInterfaceNameListeners(dbusInterfaceNameListenersRecord, true); + } if (dbusInterfaceNameListenersRecord.listenerList.empty()) { - dbusObjectPathListenersIterator = dbusInterfaceNameListenersMap.erase(dbusObjectPathListenersIterator); + dbusInterfaceNameListenersIterator = dbusInterfaceNameListenersMap.erase(dbusInterfaceNameListenersIterator); } else { - dbusObjectPathListenersIterator++; + dbusInterfaceNameListenersIterator++; } } } @@ -1100,8 +1133,9 @@ void DBusServiceRegistry::notifyDBusInterfaceNameListeners(DBusInterfaceNameList dbusInterfaceNameListenersRecord.listenersToRemove.remove(dbusServiceListenerIterator->first); dbusServiceListenerIterator = dbusInterfaceNameListenersRecord.listenerList.erase(dbusServiceListenerIterator); } else { - if(auto itsProxy = dbusServiceListenerIterator->second->proxy.lock()) + if(auto itsProxy = dbusServiceListenerIterator->second->proxy.lock()) { (dbusServiceListenerIterator->second->listener)(itsProxy, availabilityStatus); + } ++dbusServiceListenerIterator; } } @@ -1119,14 +1153,12 @@ void DBusServiceRegistry::removeUniqueName(const DBusUniqueNamesMapIterator& dbu if (dbusUniqueNamesIterator->second.ownedBusNames.size() == 0) { std::string dbusUniqueName = dbusUniqueNamesIterator->first; dbusUniqueNamesMap_.erase(dbusUniqueNamesIterator); - dbusServicesMutex_.unlock(); const bool isSubscriptionCancelled = dbusDaemonProxy_->getDBusConnection()->removeObjectManagerSignalMemberHandler( dbusUniqueName, this); if (!isSubscriptionCancelled) { COMMONAPI_ERROR(std::string(__FUNCTION__), ": still subscribed too ", dbusUniqueName); } - dbusServicesMutex_.lock(); } else { //delete object path cache entry of service auto& dbusObjectPathsCache = dbusUniqueNamesIterator->second.dbusObjectPathsCache; diff --git a/src/CommonAPI/DBus/DBusStubAdapter.cpp b/src/CommonAPI/DBus/DBusStubAdapter.cpp index 0f86cc1..44ed866 100644 --- a/src/CommonAPI/DBus/DBusStubAdapter.cpp +++ b/src/CommonAPI/DBus/DBusStubAdapter.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index be5aa1e..5ae19c9 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/test/DBusClientIdTest.cpp b/src/test/DBusClientIdTest.cpp index 1a75943..d94a4aa 100644 --- a/src/test/DBusClientIdTest.cpp +++ b/src/test/DBusClientIdTest.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/test/DBusConnectionTest.cpp b/src/test/DBusConnectionTest.cpp index 1e999f3..5f66707 100644 --- a/src/test/DBusConnectionTest.cpp +++ b/src/test/DBusConnectionTest.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/test/DBusDaemonProxyTest.cpp b/src/test/DBusDaemonProxyTest.cpp index b2a4364..4bb9d80 100644 --- a/src/test/DBusDaemonProxyTest.cpp +++ b/src/test/DBusDaemonProxyTest.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/test/DBusStubAdapterTest.cpp b/src/test/DBusStubAdapterTest.cpp index 5c1d742..387aec9 100644 --- a/src/test/DBusStubAdapterTest.cpp +++ b/src/test/DBusStubAdapterTest.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/test/DBusVariantOutputStreamTest.cpp b/src/test/DBusVariantOutputStreamTest.cpp index b23e12f..b68f3ac 100644 --- a/src/test/DBusVariantOutputStreamTest.cpp +++ b/src/test/DBusVariantOutputStreamTest.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/src/test/DBusVariantTest.cpp b/src/test/DBusVariantTest.cpp index b2b4b8b..88800cb 100644 --- a/src/test/DBusVariantTest.cpp +++ b/src/test/DBusVariantTest.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2013-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2013-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. |