From e3818cb0ad5b9c734cca361edccb16ca93081728 Mon Sep 17 00:00:00 2001 From: dibpinto <131255173+dibpinto@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:08:07 +0100 Subject: [PATCH] capicxx-core-runtime 3.2.3-r7 (#45) * capicxx-core-runtime 3.2.3-r7 - Fixed warnings with gcc11 for Wextra-extra-semi flag - Fix capi-core-runtime Runtime::loadLibrary - vSomeIP Security: Update vsomeip_sec - Fixed commonapi-core-runtime windows build - Fix race condition. - Remove mutex and add exception handling to RuntimeDeinit. - Fix double initialization of loggerImpl. - Linux: avoid static initialization of std::mutex - Replace deprecated std::ptr_fun - Properly initialize Runtime::defaultCallTimeout_ - Removed GENIVI copyright line - Fix bug in assignment operator of Variant in case of self-assignment - Ensure to stop struct deserialization on error - Implement "no_timeout" in method responses - Use COMMONAPI_EXPORT_CLASS_EXPLICIT to export classes - Removed libdlt dependency from android - Add support to logs in Android - Update android build files - Support retrieval of environment (hostname) from client identifier. - Use lock objects and remove self assignment. * Fix Copyright field and github link in README file --------- Co-authored-by: Diana Pinto --- Android.bp | 56 +++++++---- Android.mk | 44 +++++++++ CHANGES | 35 ++++++- CMakeLists.txt | 24 +++-- README.md | 10 +- cmake/CommonAPIConfig.cmake.in | 10 +- include/CommonAPI/Address.hpp | 36 +++---- include/CommonAPI/Event.hpp | 129 ++++++++++++-------------- include/CommonAPI/Export.hpp | 5 + include/CommonAPI/Factory.hpp | 6 +- include/CommonAPI/IniFileReader.hpp | 12 +-- include/CommonAPI/Logger.hpp | 30 +++--- include/CommonAPI/MainLoopContext.hpp | 46 ++++----- include/CommonAPI/Proxy.hpp | 1 - include/CommonAPI/ProxyManager.hpp | 6 +- include/CommonAPI/Runtime.hpp | 64 ++++++------- include/CommonAPI/Struct.hpp | 21 ++++- include/CommonAPI/Types.hpp | 7 ++ include/CommonAPI/Variant.hpp | 20 ++-- libcommonapi.yaml | 6 ++ src/CommonAPI/CallInfo.cpp | 5 + src/CommonAPI/Logger.cpp | 107 +++++++++++++++++++-- src/CommonAPI/Runtime.cpp | 39 ++++++-- src/CommonAPI/Utils.cpp | 5 +- 24 files changed, 486 insertions(+), 238 deletions(-) create mode 100644 Android.mk create mode 100644 libcommonapi.yaml diff --git a/Android.bp b/Android.bp index e368e33..93dc072 100644 --- a/Android.bp +++ b/Android.bp @@ -1,38 +1,54 @@ -capi_srcs = [ - "src/CommonAPI/**/*.cpp" -] - cc_defaults { - name: "capi_defaults", + name: "libcommonapi_defaults", + + rtti: true, + cppflags: [ - "-std=c++11", + "-std=c++11", "-Wall", "-Wextra", "-Wformat", "-Wformat-security", "-Wconversion", - "-Wno-attributes", + "-Wno-attributes", "-fexceptions", "-fstrict-aliasing", "-fstack-protector", "-fasynchronous-unwind-tables", "-fno-omit-frame-pointer", - "-Werror", - "-fvisibility=hidden", - "-DCOMMONAPI_INTERNAL_COMPILATION" - ] + "-fvisibility=hidden", + "-Wno-ignored-attributes", + "-Wno-unused-private-field", + "-D_CRT_SECURE_NO_WARNINGS", + "-DCOMMONAPI_INTERNAL_COMPILATION", + "-DCOMMONAPI_LOGLEVEL=COMMONAPI_LOGLEVEL_VERBOSE", + "-DUSE_DLT", + ], + + proprietary: true, } cc_library_shared { - name: "libCommonAPI", - vendor: true, - srcs: capi_srcs, - defaults: [ - "capi_defaults" - ], + name: "libcommonapi", + defaults: ["libcommonapi_defaults"], local_include_dirs: [ - "include" + "include", + ], + + shared_libs: [ + "liblog", + "libutils", + "libboost_log", + "libboost_system", + "libboost_thread", + ], + + export_include_dirs: [ + "include", + ], + srcs: [ + "src/CommonAPI/**/*.cpp" ], - export_include_dirs: ["include"], - rtti: true } + + diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..fff5540 --- /dev/null +++ b/Android.mk @@ -0,0 +1,44 @@ +# Cannot convert to Android.bp as resource copying has not +# yet implemented for soong as of 12/16/2016 + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libcommonapi_dlt +LOCAL_MODULE_TAGS := optional +LOCAL_CLANG := true +LOCAL_PROPRIETARY_MODULE := true +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include \ + +LOCAL_SRC_FILES += \ + src/CommonAPI/Address.cpp \ + src/CommonAPI/ContainerUtils.cpp \ + src/CommonAPI/IniFileReader.cpp \ + src/CommonAPI/Logger.cpp \ + src/CommonAPI/LoggerImpl.cpp \ + src/CommonAPI/MainLoopContext.cpp \ + src/CommonAPI/Proxy.cpp \ + src/CommonAPI/ProxyManager.cpp \ + src/CommonAPI/Runtime.cpp \ + src/CommonAPI/Utils.cpp \ + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include + +LOCAL_SHARED_LIBRARIES := \ + libboost_log \ + libboost_system \ + libboost_thread \ + +LOCAL_CFLAGS := \ + -frtti -fexceptions \ + -Wno-ignored-attributes \ + -D_CRT_SECURE_NO_WARNINGS \ + -DCOMMONAPI_INTERNAL_COMPILATION \ + -DCOMMONAPI_LOGLEVEL=COMMONAPI_LOGLEVEL_VERBOSE \ + +include $(BUILD_SHARED_LIBRARY) + + + diff --git a/CHANGES b/CHANGES index b520b72..87db39e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,8 +1,40 @@ Changes ======= +v3.2.3-r7 +- Fixed warnings with gcc11 for Wextra-extra-semi flag +- Fix capi-core-runtime Runtime::loadLibrary +- vSomeIP Security: Update vsomeip_sec +- Fixed commonapi-core-runtime windows build + +v3.2.3-r6 +- Fix race condition. +- Remove mutex and add exception handling to RuntimeDeinit. +- Fix double initialization of loggerImpl. + +v3.2.3-r5 +- Linux: avoid static initialization of std::mutex +- Replace deprecated std::ptr_fun + +v3.2.3 +- Properly initialize Runtime::defaultCallTimeout_ +- Removed GENIVI copyright line +- Fix bug in assignment operator of Variant in case of self-assignment +- Ensure to stop struct deserialization on error +- Implement "no_timeout" in method responses +- Use COMMONAPI_EXPORT_CLASS_EXPLICIT to export classes +- Removed libdlt dependency from android +- Add support to logs in Android +- Update android build files + +v3.2.2 +- Support retrieval of environment (hostname) from client identifier. + +v3.2.1 +- Use lock objects and remove self assignment. + v3.2.0 -- Support ABI compatible changes (additional attributes, broadcast and methods added to the end of +- Support ABI compatible changes (additional attributes, broadcast and methods added to the end of the interface specification) v3.1.12.6 @@ -47,4 +79,3 @@ v3.1.9 - Added subscription parameter to 'Event::onListenerRemoved' function. This is needed for managing the added and removed listeners respectively for mapping the listeners on the subscription. - Replaced variadic macros with variadic templates for CommonAPI logger. - Removed obsolete usleep() macro. - diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d7b654..1cade2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ PROJECT(libcommonapi) # version of CommonAPI SET( LIBCOMMONAPI_MAJOR_VERSION 3 ) SET( LIBCOMMONAPI_MINOR_VERSION 2 ) -SET( LIBCOMMONAPI_PATCH_VERSION 0 ) +SET( LIBCOMMONAPI_PATCH_VERSION 3 ) message(STATUS "Project name: ${PROJECT_NAME}") @@ -24,6 +24,10 @@ message(STATUS "This is CMake for Common API C++ Version ${COMPONENT_VERSION}.") set(DL_LIBRARY "") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(DL_LIBRARY "dl") + + # force all use of std::mutx and std::recursive_mutex to use runtime init + # instead of static initialization so mutexes can be hooked to enable PI as needed + add_definitions(-D_GTHREAD_USE_MUTEX_INIT_FUNC -D_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") ############################################################################## @@ -102,7 +106,8 @@ IF(MSVC) add_definitions(-DCOMMONAPI_INTERNAL_COMPILATION -DCOMMONAPI_DLL_COMPILATION) add_compile_options(/EHsc /wd4996) ELSE () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wformat -Wformat-security -Wconversion -fexceptions -fstrict-aliasing -fstack-protector -fasynchronous-unwind-tables -fno-omit-frame-pointer -Werror -DCOMMONAPI_INTERNAL_COMPILATION -fvisibility=hidden") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Werror=extra-semi -Wformat -Wformat-security -Wconversion -fexceptions -fstrict-aliasing -fstack-protector-strong -fasynchronous-unwind-tables -fno-omit-frame-pointer -Werror -DCOMMONAPI_INTERNAL_COMPILATION -fvisibility=hidden") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wformat-security -fstack-protector-strong") ENDIF(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCOMMONAPI_LOGLEVEL=COMMONAPI_LOGLEVEL_${MAX_LOG_LEVEL}") @@ -129,6 +134,9 @@ list(SORT CAPI_SRCS) add_library(CommonAPI SHARED ${CAPI_SRCS}) target_link_libraries(CommonAPI PRIVATE ${DL_LIBRARY} ${DLT_LIBRARIES}) set_target_properties(CommonAPI PROPERTIES VERSION ${LIBCOMMONAPI_MAJOR_VERSION}.${LIBCOMMONAPI_MINOR_VERSION}.${LIBCOMMONAPI_PATCH_VERSION} SOVERSION ${LIBCOMMONAPI_MAJOR_VERSION}.${LIBCOMMONAPI_MINOR_VERSION}.${LIBCOMMONAPI_PATCH_VERSION} LINKER_LANGUAGE C) +target_include_directories(CommonAPI INTERFACE + $ + $) set_target_properties (CommonAPI PROPERTIES INTERFACE_LINK_LIBRARY "") ############################################################################## @@ -167,23 +175,14 @@ export(PACKAGE CommonAPI) # Create the CommonAPIConfig.cmake and CommonAPIConfigVersion files ... file(RELATIVE_PATH REL_INCLUDE_DIR "${ABSOLUTE_INSTALL_CMAKE_DIR}" "${ABSOLUTE_INSTALL_INCLUDE_DIR}") -# ... for the build tree -set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include" ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CommonAPIConfig.cmake.in "${PROJECT_BINARY_DIR}/CommonAPIConfig.cmake" @ONLY) - -# ... for the install tree -set(CONF_INCLUDE_DIRS "\${COMMONAPI_CMAKE_DIR}/${REL_INCLUDE_DIR}") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CommonAPIConfig.cmake.in - "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CommonAPIConfig.cmake" @ONLY) - -# ... for both configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CommonAPIConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/CommonAPIConfigVersion.cmake" @ONLY) # Install the CommonAPIConfig.cmake and CommonAPIConfigVersion.cmake install(FILES - "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CommonAPIConfig.cmake" + "${PROJECT_BINARY_DIR}/CommonAPIConfig.cmake" "${PROJECT_BINARY_DIR}/CommonAPIConfigVersion.cmake" DESTINATION "${INSTALL_CMAKE_DIR}") @@ -255,4 +254,3 @@ if(NOT WIN32 AND PKG_CONFIG_FOUND) endif() ############################################################################## - diff --git a/README.md b/README.md index fa0b061..68d8c0e 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ ### CommonAPI C++ Core Runtime ##### Copyright -Copyright (C) 2016-2020, Bayerische Motoren Werke Aktiengesellschaft (BMW AG). -Copyright (C) 2016-2020, GENIVI Alliance, Inc. +Copyright (C) 2016-2023, Bayerische Motoren Werke Aktiengesellschaft (BMW AG). +Copyright (C) 2016-2023, COVESA -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. +This file is part of COVESA Project IPC Common API C++. +Contributions are licensed to the COVESA under one or more Contribution License Agreements or MPL 2.0. ##### License 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 @@ This Source Code Form is subject to the terms of the Mozilla Public License, v. The specification document and the user guide can be found in the CommonAPI documentation directory of the CommonAPI-Tools project as AsciiDoc document. A pdf version can be found at https://github.com/GENIVI/capicxx-core-tools/releases. ##### Further information -https://genivi.github.io/capicxx-core-tools/ +https://covesa.github.io/capicxx-core-tools/ ##### Build Instructions for Linux diff --git a/cmake/CommonAPIConfig.cmake.in b/cmake/CommonAPIConfig.cmake.in index 2c4fea4..7ccbbbc 100644 --- a/cmake/CommonAPIConfig.cmake.in +++ b/cmake/CommonAPIConfig.cmake.in @@ -1,13 +1,17 @@ # Config file for the CommonAPI package -# It defines the following variables -# COMMONAPI_INCLUDE_DIRS - include directories for CommonAPI +# Exports the follwing targets: +# CommonAPI - CMake target for CommonAPI SomeIP +# Additionally, the following variables are defined: +# COMMONAPI_VERSION - The CommonAPI version number # Compute paths get_filename_component(COMMONAPI_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -set(COMMONAPI_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") # Our library dependencies (contains definitions for IMPORTED targets) include("${COMMONAPI_CMAKE_DIR}/CommonAPITargets.cmake") +# Legacy variable, kept for compatibility +get_target_property(COMMONAPI_INCLUDE_DIRS CommonAPI INTERFACE_INCLUDE_DIRECTORIES) + set(COMMONAPI_VERSION @PACKAGE_VERSION@) set(COMMONAPI_VERSION_STRING "@PACKAGE_VERSION@") diff --git a/include/CommonAPI/Address.hpp b/include/CommonAPI/Address.hpp index 767fca4..953513e 100644 --- a/include/CommonAPI/Address.hpp +++ b/include/CommonAPI/Address.hpp @@ -17,33 +17,33 @@ namespace CommonAPI { -class Address { +class COMMONAPI_EXPORT_CLASS_EXPLICIT Address { public: - COMMONAPI_EXPORT Address(); - COMMONAPI_EXPORT Address(const std::string &_address); - COMMONAPI_EXPORT Address(const std::string &_domain, + COMMONAPI_METHOD_EXPORT Address(); + COMMONAPI_METHOD_EXPORT Address(const std::string &_address); + COMMONAPI_METHOD_EXPORT Address(const std::string &_domain, const std::string &_interface, const std::string &_instance); - COMMONAPI_EXPORT Address(const Address &_source); - COMMONAPI_EXPORT virtual ~Address() = default; + COMMONAPI_METHOD_EXPORT Address(const Address &_source); + COMMONAPI_METHOD_EXPORT virtual ~Address() = default; - COMMONAPI_EXPORT Address &operator=(const Address &_other); + COMMONAPI_METHOD_EXPORT Address &operator=(const Address &_other); - COMMONAPI_EXPORT bool operator==(const Address &_other) const; - COMMONAPI_EXPORT bool operator!=(const Address &_other) const; - COMMONAPI_EXPORT bool operator<(const Address &_other) const; + COMMONAPI_METHOD_EXPORT bool operator==(const Address &_other) const; + COMMONAPI_METHOD_EXPORT bool operator!=(const Address &_other) const; + COMMONAPI_METHOD_EXPORT bool operator<(const Address &_other) const; - COMMONAPI_EXPORT std::string getAddress() const; - COMMONAPI_EXPORT void setAddress(const std::string &_address); + COMMONAPI_METHOD_EXPORT std::string getAddress() const; + COMMONAPI_METHOD_EXPORT void setAddress(const std::string &_address); - COMMONAPI_EXPORT const std::string &getDomain() const; - COMMONAPI_EXPORT void setDomain(const std::string &_domain); + COMMONAPI_METHOD_EXPORT const std::string &getDomain() const; + COMMONAPI_METHOD_EXPORT void setDomain(const std::string &_domain); - COMMONAPI_EXPORT const std::string &getInterface() const; - COMMONAPI_EXPORT void setInterface(const std::string &_interface); + COMMONAPI_METHOD_EXPORT const std::string &getInterface() const; + COMMONAPI_METHOD_EXPORT void setInterface(const std::string &_interface); - COMMONAPI_EXPORT const std::string &getInstance() const; - COMMONAPI_EXPORT void setInstance(const std::string &_instance); + COMMONAPI_METHOD_EXPORT const std::string &getInstance() const; + COMMONAPI_METHOD_EXPORT void setInstance(const std::string &_instance); private: std::string domain_; diff --git a/include/CommonAPI/Event.hpp b/include/CommonAPI/Event.hpp index 1d638e6..116d6b3 100644 --- a/include/CommonAPI/Event.hpp +++ b/include/CommonAPI/Event.hpp @@ -39,7 +39,7 @@ class Event { /** * \brief Constructor */ - Event() : nextSubscription_(0) {}; + Event() : nextSubscription_(0) {} /** * \brief Subscribe a listener to this event @@ -107,12 +107,13 @@ typename Event::Subscription Event::subscribe(List bool isFirstListener; Listeners listeners; - subscriptionMutex_.lock(); - subscription = nextSubscription_++; - isFirstListener = (0 == pendingSubscriptions_.size()) && (pendingUnsubscriptions_.size() == subscriptions_.size()); - listeners = std::make_tuple(listener, std::move(errorListener)); - pendingSubscriptions_[subscription] = std::move(listeners); - subscriptionMutex_.unlock(); + { + std::lock_guard itsSubscriptionLock(subscriptionMutex_); + subscription = nextSubscription_++; + isFirstListener = (0 == pendingSubscriptions_.size()) && (pendingUnsubscriptions_.size() == subscriptions_.size()); + listeners = std::make_tuple(listener, std::move(errorListener)); + pendingSubscriptions_[subscription] = std::move(listeners); + } if (isFirstListener) { if (!pendingUnsubscriptions_.empty()) @@ -130,30 +131,31 @@ void Event::unsubscribe(const Subscription subscription) { bool hasUnsubscribed(false); Listener listener; - subscriptionMutex_.lock(); - auto listenerIterator = subscriptions_.find(subscription); - if (subscriptions_.end() != listenerIterator) { - if (pendingUnsubscriptions_.end() == pendingUnsubscriptions_.find(subscription)) { - if (0 == pendingSubscriptions_.erase(subscription)) { - pendingUnsubscriptions_.insert(subscription); - listener = std::get<0>(listenerIterator->second); - hasUnsubscribed = true; + { + std::lock_guard itsSubscriptionLock(subscriptionMutex_); + auto listenerIterator = subscriptions_.find(subscription); + if (subscriptions_.end() != listenerIterator) { + if (pendingUnsubscriptions_.end() == pendingUnsubscriptions_.find(subscription)) { + if (0 == pendingSubscriptions_.erase(subscription)) { + pendingUnsubscriptions_.insert(subscription); + listener = std::get<0>(listenerIterator->second); + hasUnsubscribed = true; + } + isLastListener = (pendingUnsubscriptions_.size() == subscriptions_.size()); } - isLastListener = (pendingUnsubscriptions_.size() == subscriptions_.size()); } - } - else { - listenerIterator = pendingSubscriptions_.find(subscription); - if (pendingSubscriptions_.end() != listenerIterator) { - listener = std::get<0>(listenerIterator->second); - if (0 != pendingSubscriptions_.erase(subscription)) { - isLastListener = (pendingUnsubscriptions_.size() == subscriptions_.size()); - hasUnsubscribed = true; + else { + listenerIterator = pendingSubscriptions_.find(subscription); + if (pendingSubscriptions_.end() != listenerIterator) { + listener = std::get<0>(listenerIterator->second); + if (0 != pendingSubscriptions_.erase(subscription)) { + isLastListener = (pendingUnsubscriptions_.size() == subscriptions_.size()); + hasUnsubscribed = true; + } } } + isLastListener = isLastListener && (0 == pendingSubscriptions_.size()); } - isLastListener = isLastListener && (0 == pendingSubscriptions_.size()); - subscriptionMutex_.unlock(); if (hasUnsubscribed) { onListenerRemoved(listener, subscription); @@ -166,8 +168,8 @@ void Event::unsubscribe(const Subscription subscription) { template void Event::notifyListeners(const Arguments_&... eventArguments) { - notificationMutex_.lock(); - subscriptionMutex_.lock(); + std::lock_guard itsNotificationLock(notificationMutex_); + std::unique_lock itsSubscriptionLock(subscriptionMutex_); for (auto iterator = pendingUnsubscriptions_.begin(); iterator != pendingUnsubscriptions_.end(); iterator++) { @@ -182,19 +184,17 @@ void Event::notifyListeners(const Arguments_&... eventArguments) } pendingSubscriptions_.clear(); - subscriptionMutex_.unlock(); + itsSubscriptionLock.unlock(); for (auto iterator = subscriptions_.begin(); iterator != subscriptions_.end(); iterator++) { (std::get<0>(iterator->second))(eventArguments...); } - - notificationMutex_.unlock(); } template void Event::notifySpecificListener(const Subscription subscription, const Arguments_&... eventArguments) { - notificationMutex_.lock(); - subscriptionMutex_.lock(); + std::lock_guard itsNotificationLock(notificationMutex_); + std::unique_lock itsSubscriptionLock(subscriptionMutex_); for (auto iterator = pendingUnsubscriptions_.begin(); iterator != pendingUnsubscriptions_.end(); iterator++) { @@ -210,50 +210,47 @@ void Event::notifySpecificListener(const Subscription subscriptio } pendingSubscriptions_.clear(); - - subscriptionMutex_.unlock(); + itsSubscriptionLock.unlock(); for (auto iterator = subscriptions_.begin(); iterator != subscriptions_.end(); iterator++) { if (subscription == iterator->first) { (std::get<0>(iterator->second))(eventArguments...); } } - - notificationMutex_.unlock(); } template void Event::notifySpecificError(const Subscription subscription, const CallStatus status) { - notificationMutex_.lock(); - subscriptionMutex_.lock(); - for (auto iterator = pendingUnsubscriptions_.begin(); - iterator != pendingUnsubscriptions_.end(); - iterator++) { - subscriptions_.erase(*iterator); - } - pendingUnsubscriptions_.clear(); - - for (auto iterator = pendingSubscriptions_.begin(); - iterator != pendingSubscriptions_.end(); - iterator++) { - subscriptions_.insert(*iterator); - } - pendingSubscriptions_.clear(); + { + std::lock_guard itsNotificationLock(notificationMutex_); + std::unique_lock itsSubscriptionLock(subscriptionMutex_); + for (auto iterator = pendingUnsubscriptions_.begin(); + iterator != pendingUnsubscriptions_.end(); + iterator++) { + subscriptions_.erase(*iterator); + } + pendingUnsubscriptions_.clear(); - subscriptionMutex_.unlock(); - for (auto iterator = subscriptions_.begin(); iterator != subscriptions_.end(); iterator++) { - if (subscription == iterator->first) { - ErrorListener listener = std::get<1>(iterator->second); - if (listener) { - listener(status); + for (auto iterator = pendingSubscriptions_.begin(); + iterator != pendingSubscriptions_.end(); + iterator++) { + subscriptions_.insert(*iterator); + } + pendingSubscriptions_.clear(); + + itsSubscriptionLock.unlock(); + for (auto iterator = subscriptions_.begin(); iterator != subscriptions_.end(); iterator++) { + if (subscription == iterator->first) { + ErrorListener listener = std::get<1>(iterator->second); + if (listener) { + listener(status); + } } } } - notificationMutex_.unlock(); - if (status != CommonAPI::CallStatus::SUCCESS) { - subscriptionMutex_.lock(); + std::lock_guard itsSubscriptionLock(subscriptionMutex_); auto listenerIterator = subscriptions_.find(subscription); if (subscriptions_.end() != listenerIterator) { if (pendingUnsubscriptions_.end() == pendingUnsubscriptions_.find(subscription)) { @@ -268,15 +265,14 @@ void Event::notifySpecificError(const Subscription subscription, pendingSubscriptions_.erase(subscription); } } - subscriptionMutex_.unlock(); } } template void Event::notifyErrorListeners(const CallStatus status) { - notificationMutex_.lock(); - subscriptionMutex_.lock(); + std::lock_guard itsNotificationLock(notificationMutex_); + std::unique_lock itsSubscriptionLock(subscriptionMutex_); for (auto iterator = pendingUnsubscriptions_.begin(); iterator != pendingUnsubscriptions_.end(); iterator++) { @@ -291,16 +287,13 @@ void Event::notifyErrorListeners(const CallStatus status) { } pendingSubscriptions_.clear(); - subscriptionMutex_.unlock(); - + itsSubscriptionLock.unlock(); for (auto iterator = subscriptions_.begin(); iterator != subscriptions_.end(); iterator++) { ErrorListener listener = std::get<1>(iterator->second); if (listener) { listener(status); } } - - notificationMutex_.unlock(); } diff --git a/include/CommonAPI/Export.hpp b/include/CommonAPI/Export.hpp index 7ac00ac..f954cc1 100644 --- a/include/CommonAPI/Export.hpp +++ b/include/CommonAPI/Export.hpp @@ -10,6 +10,8 @@ #define COMMONAPI_EXPORT __declspec(dllexport) #define COMMONAPI_EXPORT_CLASS_EXPLICIT + #define COMMONAPI_METHOD_EXPORT COMMONAPI_EXPORT + #if COMMONAPI_DLL_COMPILATION #define COMMONAPI_IMPORT_EXPORT __declspec(dllexport) #else @@ -19,6 +21,9 @@ #define COMMONAPI_EXPORT __attribute__ ((visibility ("default"))) #define COMMONAPI_EXPORT_CLASS_EXPLICIT COMMONAPI_EXPORT #define COMMONAPI_IMPORT_EXPORT + + #define COMMONAPI_METHOD_EXPORT + #endif #endif // COMMONAPI_EXPORT_HPP_ diff --git a/include/CommonAPI/Factory.hpp b/include/CommonAPI/Factory.hpp index d27b518..5167265 100644 --- a/include/CommonAPI/Factory.hpp +++ b/include/CommonAPI/Factory.hpp @@ -28,7 +28,7 @@ class COMMONAPI_EXPORT Factory { typedef std::function &)> AvailableInstancesCbk_t; typedef std::function InstanceAliveCbk_t; - virtual ~Factory() {}; + virtual ~Factory() {} virtual void init() = 0; @@ -54,8 +54,8 @@ class COMMONAPI_EXPORT Factory { std::shared_ptr _stub, std::shared_ptr mainLoopContext) = 0; - virtual bool unregisterStub(const std::string &_domain, - const std::string &_interface, + virtual bool unregisterStub(const std::string &_domain, + const std::string &_interface, const std::string &_instance) = 0; }; diff --git a/include/CommonAPI/IniFileReader.hpp b/include/CommonAPI/IniFileReader.hpp index 0ae6e01..7f6a3ca 100644 --- a/include/CommonAPI/IniFileReader.hpp +++ b/include/CommonAPI/IniFileReader.hpp @@ -18,22 +18,22 @@ namespace CommonAPI { -class IniFileReader { +class COMMONAPI_EXPORT_CLASS_EXPLICIT IniFileReader { public: class Section { public: - COMMONAPI_EXPORT const std::map &getMappings() const; - COMMONAPI_EXPORT std::string getValue(const std::string &_key) const; + COMMONAPI_METHOD_EXPORT const std::map &getMappings() const; + COMMONAPI_METHOD_EXPORT std::string getValue(const std::string &_key) const; private: std::map mappings_; friend class IniFileReader; }; - COMMONAPI_EXPORT bool load(const std::string &_path); + COMMONAPI_METHOD_EXPORT bool load(const std::string &_path); - COMMONAPI_EXPORT const std::map> &getSections() const; - COMMONAPI_EXPORT std::shared_ptr
getSection(const std::string &_name) const; + COMMONAPI_METHOD_EXPORT const std::map> &getSections() const; + COMMONAPI_METHOD_EXPORT std::shared_ptr
getSection(const std::string &_name) const; private: std::map> sections_; diff --git a/include/CommonAPI/Logger.hpp b/include/CommonAPI/Logger.hpp index 0658be8..4a1ad62 100644 --- a/include/CommonAPI/Logger.hpp +++ b/include/CommonAPI/Logger.hpp @@ -26,9 +26,9 @@ namespace CommonAPI { -class Logger { +class COMMONAPI_EXPORT_CLASS_EXPLICIT Logger { public: - enum class Level : std::uint8_t COMMONAPI_EXPORT { + enum class Level : std::uint8_t COMMONAPI_METHOD_EXPORT { CAPI_LOG_NONE = 0, CAPI_LOG_FATAL = 1, CAPI_LOG_ERROR = 2, @@ -41,37 +41,37 @@ class Logger { ~Logger(); template - COMMONAPI_EXPORT static void fatal(LogEntries_&&... _entries) { + COMMONAPI_METHOD_EXPORT static void fatal(LogEntries_&&... _entries) { log(Logger::Level::CAPI_LOG_FATAL, std::forward(_entries)...); } template - COMMONAPI_EXPORT static void error(LogEntries_&&... _entries) { + COMMONAPI_METHOD_EXPORT static void error(LogEntries_&&... _entries) { log(Logger::Level::CAPI_LOG_ERROR, std::forward(_entries)...); } template - COMMONAPI_EXPORT static void warning(LogEntries_&&... _entries) { + COMMONAPI_METHOD_EXPORT static void warning(LogEntries_&&... _entries) { log(Logger::Level::CAPI_LOG_WARNING, std::forward(_entries)...); } template - COMMONAPI_EXPORT static void info(LogEntries_&&... _entries) { + COMMONAPI_METHOD_EXPORT static void info(LogEntries_&&... _entries) { log(Logger::Level::CAPI_LOG_INFO, std::forward(_entries)...); } template - COMMONAPI_EXPORT static void debug(LogEntries_&&... _entries) { + COMMONAPI_METHOD_EXPORT static void debug(LogEntries_&&... _entries) { log(Logger::Level::CAPI_LOG_DEBUG, std::forward(_entries)...); } template - COMMONAPI_EXPORT static void verbose(LogEntries_&&... _entries) { + COMMONAPI_METHOD_EXPORT static void verbose(LogEntries_&&... _entries) { log(Logger::Level::CAPI_LOG_VERBOSE, std::forward(_entries)...); } template - COMMONAPI_EXPORT static void log(Logger::Level _level, LogEntries_&&... _entries) { + COMMONAPI_METHOD_EXPORT static void log(Logger::Level _level, LogEntries_&&... _entries) { if (isLogged(_level)) { std::stringstream buffer; logIntern(buffer, std::forward(_entries)...); @@ -79,22 +79,22 @@ class Logger { } } - static void init(bool _useConsole, const std::string &_fileName, + COMMONAPI_METHOD_EXPORT static void init(bool _useConsole, const std::string &_fileName, bool _useDlt, const std::string& _level); private: class LoggerImpl; - static std::unique_ptr loggerImpl_; + COMMONAPI_METHOD_EXPORT static std::shared_ptr getLoggerImpl(); - COMMONAPI_EXPORT static bool isLogged(Level _level); - COMMONAPI_EXPORT static void doLog(Level _level, const std::string& _message); + COMMONAPI_METHOD_EXPORT static bool isLogged(Level _level); + COMMONAPI_METHOD_EXPORT static void doLog(Level _level, const std::string& _message); - COMMONAPI_EXPORT static void logIntern(std::stringstream &_buffer) { + COMMONAPI_METHOD_EXPORT static void logIntern(std::stringstream &_buffer) { (void)_buffer; } template - COMMONAPI_EXPORT static void logIntern(std::stringstream &_buffer, LogEntry_&& _entry, + COMMONAPI_METHOD_EXPORT static void logIntern(std::stringstream &_buffer, LogEntry_&& _entry, MoreLogEntries_&& ... _moreEntries) { _buffer << _entry; logIntern(_buffer, std::forward(_moreEntries)...); diff --git a/include/CommonAPI/MainLoopContext.hpp b/include/CommonAPI/MainLoopContext.hpp index e0e53bd..9361356 100644 --- a/include/CommonAPI/MainLoopContext.hpp +++ b/include/CommonAPI/MainLoopContext.hpp @@ -198,93 +198,93 @@ typedef WakeupListenerList::iterator WakeupListenerSubscription; * Watches, Timeouts and Wakeup-Events that need to be handled by your Main Loop implementation. * */ -class MainLoopContext { +class COMMONAPI_EXPORT_CLASS_EXPLICIT MainLoopContext { public: - COMMONAPI_EXPORT MainLoopContext(const std::string &_name = "COMMONAPI_DEFAULT_MAINLOOP_CONTEXT") + COMMONAPI_METHOD_EXPORT MainLoopContext(const std::string &_name = "COMMONAPI_DEFAULT_MAINLOOP_CONTEXT") : name_(_name){ } - COMMONAPI_EXPORT MainLoopContext(const MainLoopContext&) = delete; - COMMONAPI_EXPORT MainLoopContext& operator=(const MainLoopContext&) = delete; - COMMONAPI_EXPORT MainLoopContext(MainLoopContext&&) = delete; - COMMONAPI_EXPORT MainLoopContext& operator=(MainLoopContext&&) = delete; + COMMONAPI_METHOD_EXPORT MainLoopContext(const MainLoopContext&) = delete; + COMMONAPI_METHOD_EXPORT MainLoopContext& operator=(const MainLoopContext&) = delete; + COMMONAPI_METHOD_EXPORT MainLoopContext(MainLoopContext&&) = delete; + COMMONAPI_METHOD_EXPORT MainLoopContext& operator=(MainLoopContext&&) = delete; - COMMONAPI_EXPORT const std::string &getName() const; + COMMONAPI_METHOD_EXPORT const std::string &getName() const; /** * \brief Registers for all DispatchSources that are added or removed. */ - COMMONAPI_EXPORT DispatchSourceListenerSubscription subscribeForDispatchSources(DispatchSourceAddedCallback dispatchAddedCallback, DispatchSourceRemovedCallback dispatchRemovedCallback); + COMMONAPI_METHOD_EXPORT DispatchSourceListenerSubscription subscribeForDispatchSources(DispatchSourceAddedCallback dispatchAddedCallback, DispatchSourceRemovedCallback dispatchRemovedCallback); /** * \brief Registers for all Watches that are added or removed. */ - COMMONAPI_EXPORT WatchListenerSubscription subscribeForWatches(WatchAddedCallback watchAddedCallback, WatchRemovedCallback watchRemovedCallback); + COMMONAPI_METHOD_EXPORT WatchListenerSubscription subscribeForWatches(WatchAddedCallback watchAddedCallback, WatchRemovedCallback watchRemovedCallback); /** * \brief Registers for all Timeouts that are added or removed. */ - COMMONAPI_EXPORT TimeoutSourceListenerSubscription subscribeForTimeouts(TimeoutSourceAddedCallback timeoutAddedCallback, TimeoutSourceRemovedCallback timeoutRemovedCallback); + COMMONAPI_METHOD_EXPORT TimeoutSourceListenerSubscription subscribeForTimeouts(TimeoutSourceAddedCallback timeoutAddedCallback, TimeoutSourceRemovedCallback timeoutRemovedCallback); /** * \brief Registers for all Wakeup-Events that need to interrupt a call to "poll". */ - COMMONAPI_EXPORT WakeupListenerSubscription subscribeForWakeupEvents(WakeupCallback wakeupCallback); + COMMONAPI_METHOD_EXPORT WakeupListenerSubscription subscribeForWakeupEvents(WakeupCallback wakeupCallback); /** * \brief Unsubscribes your listeners for DispatchSources. */ - COMMONAPI_EXPORT void unsubscribeForDispatchSources(DispatchSourceListenerSubscription subscription); + COMMONAPI_METHOD_EXPORT void unsubscribeForDispatchSources(DispatchSourceListenerSubscription subscription); /** * \brief Unsubscribes your listeners for Watches. */ - COMMONAPI_EXPORT void unsubscribeForWatches(WatchListenerSubscription subscription); + COMMONAPI_METHOD_EXPORT void unsubscribeForWatches(WatchListenerSubscription subscription); /** * \brief Unsubscribes your listeners for Timeouts. */ - COMMONAPI_EXPORT void unsubscribeForTimeouts(TimeoutSourceListenerSubscription subscription); + COMMONAPI_METHOD_EXPORT void unsubscribeForTimeouts(TimeoutSourceListenerSubscription subscription); /** * \brief Unsubscribes your listeners for Wakeup-Events. */ - COMMONAPI_EXPORT void unsubscribeForWakeupEvents(WakeupListenerSubscription subscription); + COMMONAPI_METHOD_EXPORT void unsubscribeForWakeupEvents(WakeupListenerSubscription subscription); /** * \brief Notifies all listeners about a new DispatchSource. */ - COMMONAPI_EXPORT void registerDispatchSource(DispatchSource* dispatchSource, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT); + COMMONAPI_METHOD_EXPORT void registerDispatchSource(DispatchSource* dispatchSource, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT); /** * \brief Notifies all listeners about the removal of a DispatchSource. */ - COMMONAPI_EXPORT void deregisterDispatchSource(DispatchSource* dispatchSource); + COMMONAPI_METHOD_EXPORT void deregisterDispatchSource(DispatchSource* dispatchSource); /** * \brief Notifies all listeners about a new Watch. */ - COMMONAPI_EXPORT void registerWatch(Watch* watch, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT); + COMMONAPI_METHOD_EXPORT void registerWatch(Watch* watch, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT); /** * \brief Notifies all listeners about the removal of a Watch. */ - COMMONAPI_EXPORT void deregisterWatch(Watch* watch); + COMMONAPI_METHOD_EXPORT void deregisterWatch(Watch* watch); /** * \brief Notifies all listeners about a new Timeout. */ - COMMONAPI_EXPORT void registerTimeoutSource(Timeout* timeoutEvent, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT); + COMMONAPI_METHOD_EXPORT void registerTimeoutSource(Timeout* timeoutEvent, const DispatchPriority dispatchPriority = DispatchPriority::DEFAULT); /** * \brief Notifies all listeners about the removal of a Timeout. */ - COMMONAPI_EXPORT void deregisterTimeoutSource(Timeout* timeoutEvent); + COMMONAPI_METHOD_EXPORT void deregisterTimeoutSource(Timeout* timeoutEvent); /** * \brief Notifies all listeners about a wakeup event that just happened. */ - COMMONAPI_EXPORT void wakeup(); + COMMONAPI_METHOD_EXPORT void wakeup(); /** * \brief Will return true if at least one subscribe for DispatchSources or Watches has been called. @@ -292,7 +292,7 @@ class MainLoopContext { * This function will be used to prevent creation of a factory if a mainloop context is given, but * no listeners have been registered. This is done in order to ensure correct use of the mainloop context. */ - COMMONAPI_EXPORT bool isInitialized(); + COMMONAPI_METHOD_EXPORT bool isInitialized(); private: DispatchSourceListenerList dispatchSourceListeners_; diff --git a/include/CommonAPI/Proxy.hpp b/include/CommonAPI/Proxy.hpp index 4d27dd2..b7a759d 100644 --- a/include/CommonAPI/Proxy.hpp +++ b/include/CommonAPI/Proxy.hpp @@ -49,4 +49,3 @@ class COMMONAPI_EXPORT Proxy { } // namespace CommonAPI #endif // COMMONAPI_PROXY_HPP_ - diff --git a/include/CommonAPI/ProxyManager.hpp b/include/CommonAPI/ProxyManager.hpp index 6246b91..e9478e2 100644 --- a/include/CommonAPI/ProxyManager.hpp +++ b/include/CommonAPI/ProxyManager.hpp @@ -22,7 +22,7 @@ namespace CommonAPI { -class ProxyManager { +class COMMONAPI_EXPORT_CLASS_EXPLICIT ProxyManager { public: typedef std::function &)> GetAvailableInstancesCallback; typedef std::function GetInstanceAvailabilityStatusCallback; @@ -72,12 +72,12 @@ class ProxyManager { } protected: - COMMONAPI_EXPORT std::shared_ptr createProxy(const std::string &, + COMMONAPI_METHOD_EXPORT std::shared_ptr createProxy(const std::string &, const std::string &, const std::string &, const ConnectionId_t &_connection) const; - COMMONAPI_EXPORT std::shared_ptr createProxy(const std::string &, + COMMONAPI_METHOD_EXPORT std::shared_ptr createProxy(const std::string &, const std::string &, const std::string &, std::shared_ptr _context) const; diff --git a/include/CommonAPI/Runtime.hpp b/include/CommonAPI/Runtime.hpp index 61bd5fe..088d36e 100644 --- a/include/CommonAPI/Runtime.hpp +++ b/include/CommonAPI/Runtime.hpp @@ -29,18 +29,18 @@ class Proxy; class ProxyManager; class StubBase; -class Runtime { +class COMMONAPI_EXPORT_CLASS_EXPLICIT Runtime { public: - COMMONAPI_EXPORT static std::string getProperty(const std::string &_name); - COMMONAPI_EXPORT static void setProperty(const std::string &_name, const std::string &_value); + COMMONAPI_METHOD_EXPORT static std::string getProperty(const std::string &_name); + COMMONAPI_METHOD_EXPORT static void setProperty(const std::string &_name, const std::string &_value); - COMMONAPI_EXPORT static std::shared_ptr get(); + COMMONAPI_METHOD_EXPORT static std::shared_ptr get(); - COMMONAPI_EXPORT Runtime(); - COMMONAPI_EXPORT virtual ~Runtime(); + COMMONAPI_METHOD_EXPORT Runtime(); + COMMONAPI_METHOD_EXPORT virtual ~Runtime(); template class ProxyClass_, typename ... AttributeExtensions_> - COMMONAPI_EXPORT std::shared_ptr< + COMMONAPI_METHOD_EXPORT std::shared_ptr< ProxyClass_ > buildProxy(const std::string &_domain, @@ -59,7 +59,7 @@ class Runtime { } template class ProxyClass_, typename ... AttributeExtensions_> - COMMONAPI_EXPORT std::shared_ptr< + COMMONAPI_METHOD_EXPORT std::shared_ptr< ProxyClass_ > buildProxy(const std::string &_domain, @@ -77,7 +77,7 @@ class Runtime { } template class ProxyClass_, template class AttributeExtension_> - COMMONAPI_EXPORT std::shared_ptr::class_t> + COMMONAPI_METHOD_EXPORT std::shared_ptr::class_t> buildProxyWithDefaultAttributeExtension(const std::string &_domain, const std::string &_instance, const ConnectionId_t &_connectionId = DEFAULT_CONNECTION_ID) { @@ -93,7 +93,7 @@ class Runtime { } template class ProxyClass_, template class AttributeExtension_> - COMMONAPI_EXPORT std::shared_ptr::class_t> + COMMONAPI_METHOD_EXPORT std::shared_ptr::class_t> buildProxyWithDefaultAttributeExtension(const std::string &_domain, const std::string &_instance, std::shared_ptr _context) { @@ -109,7 +109,7 @@ class Runtime { } template - COMMONAPI_EXPORT bool registerService(const std::string &_domain, + COMMONAPI_METHOD_EXPORT bool registerService(const std::string &_domain, const std::string &_instance, std::shared_ptr _service, const ConnectionId_t &_connectionId = DEFAULT_CONNECTION_ID) { @@ -117,56 +117,56 @@ class Runtime { } template - COMMONAPI_EXPORT bool registerService(const std::string &_domain, + COMMONAPI_METHOD_EXPORT bool registerService(const std::string &_domain, const std::string &_instance, std::shared_ptr _service, std::shared_ptr _context) { return registerStub(_domain, Stub_::StubInterface::getInterface(), _instance, _service, _context); } - COMMONAPI_EXPORT bool unregisterService(const std::string &_domain, + COMMONAPI_METHOD_EXPORT bool unregisterService(const std::string &_domain, const std::string &_interface, const std::string &_instance) { return unregisterStub(_domain, _interface, _instance); } - COMMONAPI_EXPORT bool registerFactory(const std::string &_ipc, std::shared_ptr _factory); - COMMONAPI_EXPORT bool unregisterFactory(const std::string &_ipc); + COMMONAPI_METHOD_EXPORT bool registerFactory(const std::string &_ipc, std::shared_ptr _factory); + COMMONAPI_METHOD_EXPORT bool unregisterFactory(const std::string &_ipc); - inline const std::string &getDefaultBinding() const { return defaultBinding_; }; + inline const std::string &getDefaultBinding() const { return defaultBinding_; } - COMMONAPI_EXPORT void initFactories(); - COMMONAPI_EXPORT Timeout_t getDefaultCallTimeout() const; + COMMONAPI_METHOD_EXPORT void initFactories(); + COMMONAPI_METHOD_EXPORT Timeout_t getDefaultCallTimeout() const; private: - COMMONAPI_EXPORT void init(); - COMMONAPI_EXPORT bool readConfiguration(); - COMMONAPI_EXPORT bool splitAddress(const std::string &, std::string &, std::string &, std::string &); + COMMONAPI_METHOD_EXPORT void init(); + COMMONAPI_METHOD_EXPORT bool readConfiguration(); + COMMONAPI_METHOD_EXPORT bool splitAddress(const std::string &, std::string &, std::string &, std::string &); - COMMONAPI_EXPORT std::shared_ptr createProxy(const std::string &, const std::string &, const std::string &, + COMMONAPI_METHOD_EXPORT std::shared_ptr createProxy(const std::string &, const std::string &, const std::string &, const ConnectionId_t &); - COMMONAPI_EXPORT std::shared_ptr createProxy(const std::string &, const std::string &, const std::string &, + COMMONAPI_METHOD_EXPORT std::shared_ptr createProxy(const std::string &, const std::string &, const std::string &, std::shared_ptr); - COMMONAPI_EXPORT std::shared_ptr createProxyHelper(const std::string &, const std::string &, const std::string &, + COMMONAPI_METHOD_EXPORT std::shared_ptr createProxyHelper(const std::string &, const std::string &, const std::string &, const ConnectionId_t &, bool); - COMMONAPI_EXPORT std::shared_ptr createProxyHelper(const std::string &, const std::string &, const std::string &, + COMMONAPI_METHOD_EXPORT std::shared_ptr createProxyHelper(const std::string &, const std::string &, const std::string &, std::shared_ptr, bool); - COMMONAPI_EXPORT bool registerStub(const std::string &, const std::string &, const std::string &, + COMMONAPI_METHOD_EXPORT bool registerStub(const std::string &, const std::string &, const std::string &, std::shared_ptr, const ConnectionId_t &); - COMMONAPI_EXPORT bool registerStub(const std::string &, const std::string &, const std::string &, + COMMONAPI_METHOD_EXPORT bool registerStub(const std::string &, const std::string &, const std::string &, std::shared_ptr, std::shared_ptr); - COMMONAPI_EXPORT bool registerStubHelper(const std::string &, const std::string &, const std::string &, + COMMONAPI_METHOD_EXPORT bool registerStubHelper(const std::string &, const std::string &, const std::string &, std::shared_ptr, const ConnectionId_t &, bool); - COMMONAPI_EXPORT bool registerStubHelper(const std::string &, const std::string &, const std::string &, + COMMONAPI_METHOD_EXPORT bool registerStubHelper(const std::string &, const std::string &, const std::string &, std::shared_ptr, std::shared_ptr, bool); - COMMONAPI_EXPORT bool unregisterStub(const std::string &, const std::string &, const std::string &); + COMMONAPI_METHOD_EXPORT bool unregisterStub(const std::string &, const std::string &, const std::string &); - COMMONAPI_EXPORT std::string getLibrary(const std::string &, const std::string &, const std::string &, bool); - COMMONAPI_EXPORT bool loadLibrary(const std::string &); + COMMONAPI_METHOD_EXPORT std::string getLibrary(const std::string &, const std::string &, const std::string &, bool); + COMMONAPI_METHOD_EXPORT bool loadLibrary(const std::string &); private: std::string usedConfig_; diff --git a/include/CommonAPI/Struct.hpp b/include/CommonAPI/Struct.hpp index fbbefaf..5de71ee 100644 --- a/include/CommonAPI/Struct.hpp +++ b/include/CommonAPI/Struct.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace CommonAPI { @@ -38,8 +39,12 @@ struct StructReader, D_> { V_ &_values, const D_ *_depls) { StructReader, D_>{}(_input, _values, _depls); - _input.template readValue<>(std::get(_values.values_), - (_depls ? std::get(_depls->values_) : nullptr)); + if (_input.hasError()) { + COMMONAPI_ERROR("StructReader: deserialization failed at index: ", Index_-1); + } else { + _input.template readValue<>(std::get(_values.values_), + (_depls ? std::get(_depls->values_) : nullptr)); + } } }; @@ -52,7 +57,11 @@ struct StructReader, D_> { V_ &_values, const D_ *_depls) { StructReader, D_>{}(_input, _values, _depls); - _input.template readValue(std::get(_values.values_)); + if (_input.hasError()) { + COMMONAPI_ERROR("StructReader: deserialization failed at index: ", Index_-1); + } else { + _input.template readValue(std::get(_values.values_)); + } } }; @@ -65,6 +74,9 @@ struct StructReader<0, Input_, V_, D_> { const D_ *_depls) { _input.template readValue<>(std::get<0>(_values.values_), (_depls ? std::get<0>(_depls->values_) : nullptr)); + if (_input.hasError()) { + COMMONAPI_ERROR("StructReader: deserialization failed at index: 0"); + } } }; @@ -77,6 +89,9 @@ struct StructReader<0, Input_, V_, D_> { const D_ *_depls) { (void)_depls; _input.template readValue(std::get<0>(_values.values_)); + if (_input.hasError()) { + COMMONAPI_ERROR("StructReader: deserialization failed at index: 0"); + } } }; diff --git a/include/CommonAPI/Types.hpp b/include/CommonAPI/Types.hpp index 750f50e..a1dd83c 100644 --- a/include/CommonAPI/Types.hpp +++ b/include/CommonAPI/Types.hpp @@ -96,6 +96,7 @@ typedef std::uint32_t gid_t; typedef ::uid_t uid_t; typedef ::gid_t gid_t; #endif + /** * \brief Identifies a client sending a call to a stub. * @@ -109,6 +110,12 @@ class ClientId { virtual std::size_t hashCode() = 0; virtual uid_t getUid() const = 0; virtual gid_t getGid() const = 0; + virtual std::string getEnv() const { + return ""; + } + virtual std::string getHostAddress() const { + return ""; + } }; template diff --git a/include/CommonAPI/Variant.hpp b/include/CommonAPI/Variant.hpp index fc4398e..2d76554 100644 --- a/include/CommonAPI/Variant.hpp +++ b/include/CommonAPI/Variant.hpp @@ -650,19 +650,23 @@ Variant::~Variant() { template Variant& Variant::operator=(const Variant &_source) { - AssignmentVisitor visitor(*this, hasValue()); - ApplyVoidVisitor< - AssignmentVisitor, Variant, Types_... - >::visit(visitor, _source); + if (*this != _source) { + AssignmentVisitor visitor(*this, hasValue()); + ApplyVoidVisitor< + AssignmentVisitor, Variant, Types_... + >::visit(visitor, _source); + } return *this; } template Variant& Variant::operator=(Variant &&_source) { - AssignmentVisitor visitor(*this, hasValue()); - ApplyVoidVisitor< - AssignmentVisitor, Variant, Types_... - >::visit(visitor, _source); + if (*this != _source) { + AssignmentVisitor visitor(*this, hasValue()); + ApplyVoidVisitor< + AssignmentVisitor, Variant, Types_... + >::visit(visitor, _source); + } return *this; } diff --git a/libcommonapi.yaml b/libcommonapi.yaml new file mode 100644 index 0000000..f070008 --- /dev/null +++ b/libcommonapi.yaml @@ -0,0 +1,6 @@ +- name: libcommonapi + version: 3.2.3 + vendor: Lynx Team + license: + concluded: CLOSED and MPLv2 + declared: MPLv2 \ No newline at end of file diff --git a/src/CommonAPI/CallInfo.cpp b/src/CommonAPI/CallInfo.cpp index 189e9d8..3cf1c88 100644 --- a/src/CommonAPI/CallInfo.cpp +++ b/src/CommonAPI/CallInfo.cpp @@ -35,6 +35,11 @@ CallInfo::CallInfo(Timeout_t _timeout, Sender_t _sender) timeout_ = globalCallTimeout; } } + + //If timeout is set to -1, timeout should be the max value possible + if(timeout_ < 0){ + timeout_ = std::numeric_limits::max(); + } } } // namespace CommonAPI \ No newline at end of file diff --git a/src/CommonAPI/Logger.cpp b/src/CommonAPI/Logger.cpp index f5804c8..9c7194d 100644 --- a/src/CommonAPI/Logger.cpp +++ b/src/CommonAPI/Logger.cpp @@ -7,7 +7,59 @@ #include #ifdef USE_DLT +#ifndef ANDROID #include +#endif +#endif + +#ifdef ANDROID +#include + +#ifdef ALOGE +#undef ALOGE +#endif + +#define ALOGE(LOG_TAG, ...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGE ALOGE +#endif + +#ifdef ALOGW +#undef ALOGW +#endif + +#define ALOGW(LOG_TAG, ...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGW ALOGW +#endif + +#ifdef ALOGI +#undef ALOGI +#endif + +#define ALOGI(LOG_TAG, ...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGI ALOGI +#endif + +#ifdef ALOGD +#undef ALOGD +#endif + +#define ALOGD(LOG_TAG, ...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGD ALOGD +#endif + +#ifdef ALOGV +#undef ALOGV +#endif + +#define ALOGV(LOG_TAG, ...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGV ALOGV +#endif + #endif #include @@ -25,7 +77,9 @@ class Logger::LoggerImpl { useConsole_(true), useDlt_(false) #ifdef USE_DLT +#ifndef ANDROID , ownAppID_(false) +#endif #endif { } @@ -44,6 +98,7 @@ class Logger::LoggerImpl { } } #ifdef USE_DLT +#ifndef ANDROID if (useDlt_) { std::string app = Runtime::getProperty("LogApplication"); if (!app.empty()) { @@ -56,11 +111,13 @@ class Logger::LoggerImpl { context = "CAPI"; DLT_REGISTER_CONTEXT(dlt_, context.c_str(), "CAPI"); } +#endif #endif } ~LoggerImpl() { #ifdef USE_DLT +#ifndef ANDROID if (useDlt_) { DLT_UNREGISTER_CONTEXT(dlt_); if (ownAppID_) { @@ -68,6 +125,7 @@ class Logger::LoggerImpl { ; } } +#endif #endif } @@ -78,8 +136,36 @@ class Logger::LoggerImpl { void doLog(Logger::Level _level, const std::string &_message) { if (useConsole_) { std::lock_guard itsLock(mutex_); + +#ifndef ANDROID std::cerr << "[CAPI][" << levelAsString(_level) << "] " << _message << std::endl; +#else + std::string app = Runtime::getProperty("LogApplication"); + + switch (_level) { + case Logger::Level::CAPI_LOG_FATAL: + ALOGE(app.c_str(), "CAPI: %s ", _message.c_str()); + break; + case Logger::Level::CAPI_LOG_ERROR: + ALOGE(app.c_str(), "CAPI: %s ", _message.c_str()); + break; + case Logger::Level::CAPI_LOG_WARNING: + ALOGW(app.c_str(), "CAPI: %s ", _message.c_str()); + break; + case Logger::Level::CAPI_LOG_INFO: + ALOGI(app.c_str(), "CAPI: %s ", _message.c_str()); + break; + case Logger::Level::CAPI_LOG_DEBUG: + ALOGD(app.c_str(), "CAPI: %s ", _message.c_str()); + break; + case Logger::Level::CAPI_LOG_VERBOSE: + ALOGV(app.c_str(), "CAPI: %s ", _message.c_str()); + break; + default: + ALOGI(app.c_str(), "CAPI: %s ", _message.c_str()); + }; +#endif // !ANDROID } if (file_ && file_->is_open()) { std::lock_guard itsLock(mutex_); @@ -88,9 +174,11 @@ class Logger::LoggerImpl { } #ifdef USE_DLT +#ifndef ANDROID if (useDlt_) { DLT_LOG_STRING(dlt_, levelAsDlt(_level), _message.c_str()); } +#endif #endif } @@ -138,6 +226,7 @@ class Logger::LoggerImpl { } #ifdef USE_DLT +#ifndef ANDROID static DltLogLevelType levelAsDlt(Logger::Level _level) { switch (_level) { case Logger::Level::CAPI_LOG_NONE: @@ -159,6 +248,7 @@ class Logger::LoggerImpl { } } #endif +#endif private: std::mutex mutex_; @@ -171,28 +261,33 @@ class Logger::LoggerImpl { bool useDlt_; #ifdef USE_DLT +#ifndef ANDROID DLT_DECLARE_CONTEXT(dlt_) bool ownAppID_; #endif +#endif }; -std::unique_ptr Logger::loggerImpl_ = - std::unique_ptr(new Logger::LoggerImpl()); - Logger::Logger() = default; Logger::~Logger() = default; +std::shared_ptr Logger::getLoggerImpl() +{ + static std::shared_ptr loggerImpl = std::make_shared(); + return loggerImpl; +} + void Logger::init(bool _useConsole, const std::string &_fileName, bool _useDlt, const std::string& _level) { - loggerImpl_->init(_useConsole, _fileName, _useDlt, _level); + getLoggerImpl()->init(_useConsole, _fileName, _useDlt, _level); } bool Logger::isLogged(Level _level) { - return loggerImpl_->isLogged(_level); + return getLoggerImpl()->isLogged(_level); } void Logger::doLog(Level _level, const std::string& _message) { - loggerImpl_->doLog(_level, _message); + getLoggerImpl()->doLog(_level, _message); } } //namespace CommonAPI diff --git a/src/CommonAPI/Runtime.cpp b/src/CommonAPI/Runtime.cpp index 1f531a0..ad1bca9 100644 --- a/src/CommonAPI/Runtime.cpp +++ b/src/CommonAPI/Runtime.cpp @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -33,7 +34,10 @@ static std::mutex getMutex__; #ifndef _WIN32 DEINITIALIZER(RuntimeDeinit) { if (theRuntimePtr__) { - std::lock_guard itsLock(getMutex__); + // TODO: This mutex is causing a crash due to the changes introduced with 938f3d1. Since + // this "deinitializer" only runs on the main thread, no mutex should be needed. Leaving a + // comment pending a refactor. + // std::lock_guard itsLock(getMutex__); theRuntimePtr__->reset(); delete theRuntimePtr__; theRuntimePtr__ = nullptr; @@ -74,6 +78,7 @@ std::shared_ptr Runtime::get() { Runtime::Runtime() : defaultBinding_(COMMONAPI_DEFAULT_BINDING), defaultFolder_(COMMONAPI_DEFAULT_FOLDER), + defaultCallTimeout_(DEFAULT_SEND_TIMEOUT), isConfigured_(false), isInitialized_(false) { } @@ -266,7 +271,12 @@ Runtime::createProxy( // ...it seems do not, lets try to load a library that does... std::lock_guard itsGuard(loadMutex_); std::string library = getLibrary(_domain, _interface, _instance, true); - if (loadLibrary(library) || defaultFactory_) { + bool libraryLoaded = loadLibrary(library); + + if (libraryLoaded || defaultFactory_) { + if(!libraryLoaded){ + COMMONAPI_DEBUG("Loading interface library failed, using default factory now."); + } proxy = createProxyHelper(_domain, _interface, _instance, _connectionId, true); } } @@ -287,7 +297,12 @@ Runtime::createProxy( // ...it seems do not, lets try to load a library that does... std::lock_guard itsGuard(loadMutex_); std::string library = getLibrary(_domain, _interface, _instance, true); - if (loadLibrary(library) || defaultFactory_) { + bool libraryLoaded = loadLibrary(library); + + if (libraryLoaded || defaultFactory_) { + if(!libraryLoaded){ + COMMONAPI_DEBUG("Loading interface library failed, using default factory now."); + } proxy = createProxyHelper(_domain, _interface, _instance, _context, true); } } @@ -310,7 +325,12 @@ Runtime::registerStub(const std::string &_domain, const std::string &_interface, if (!isRegistered) { std::string library = getLibrary(_domain, _interface, _instance, false); std::lock_guard itsGuard(loadMutex_); - if (loadLibrary(library) || defaultFactory_) { + bool libraryLoaded = loadLibrary(library); + + if (libraryLoaded || defaultFactory_) { + if(!libraryLoaded){ + COMMONAPI_DEBUG("Loading interface library failed, using default factory now."); + } isRegistered = registerStubHelper(_domain, _interface, _instance, _stub, _connectionId, true); } } @@ -332,7 +352,12 @@ Runtime::registerStub(const std::string &_domain, const std::string &_interface, if (!isRegistered) { std::string library = getLibrary(_domain, _interface, _instance, false); std::lock_guard itsGuard(loadMutex_); - if (loadLibrary(library) || defaultFactory_) { + bool libraryLoaded = loadLibrary(library); + + if (libraryLoaded || defaultFactory_) { + if(!libraryLoaded){ + COMMONAPI_DEBUG("Loading interface library failed, using default factory now."); + } isRegistered = registerStubHelper(_domain, _interface, _instance, _stub, _context, true); } } @@ -407,7 +432,7 @@ Runtime::loadLibrary(const std::string &_library) { // Check the version information while (soStart < itsLibrary.length()) { - if (itsLibrary[soStart] != '.' + if (itsLibrary[soStart] != '.' && itsLibrary[soStart] != '-' && !std::isdigit(static_cast(itsLibrary[soStart]))) { break; } @@ -432,7 +457,7 @@ Runtime::loadLibrary(const std::string &_library) { isLoaded = false; } #else - if (dlopen(itsLibrary.c_str(), RTLD_LAZY | RTLD_GLOBAL) != 0) { + if (dlopen(itsLibrary.c_str(), RTLD_LAZY | RTLD_GLOBAL) != NULL) { loadedLibraries_.insert(itsLibrary); COMMONAPI_DEBUG("Loading interface library \"", itsLibrary, "\" succeeded."); } diff --git a/src/CommonAPI/Utils.cpp b/src/CommonAPI/Utils.cpp index 8f7f6e7..548feac 100644 --- a/src/CommonAPI/Utils.cpp +++ b/src/CommonAPI/Utils.cpp @@ -3,6 +3,7 @@ // 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/. +#include #include #include #include @@ -31,7 +32,7 @@ void trim(std::string& toTrim) { std::find_if( toTrim.begin(), toTrim.end(), - std::not1(std::ptr_fun(isspace)) + [](int c) {return !std::isspace(c);} ) ); @@ -39,7 +40,7 @@ void trim(std::string& toTrim) { std::find_if( toTrim.rbegin(), toTrim.rend(), - std::not1(std::ptr_fun(isspace))).base(), + [](int c) {return !std::isspace(c);}).base(), toTrim.end() ); }