diff options
author | Conlain Kelly <conlain.k@gmail.com> | 2018-07-18 13:11:19 -0400 |
---|---|---|
committer | Conlain Kelly <conlain.k@gmail.com> | 2018-07-18 13:11:25 -0400 |
commit | e380ed1779e4317437cea63f070a8345b41f2d33 (patch) | |
tree | b2d6669663b91a3f235c2ce4a00c0c888751ff20 /src/components/utils | |
parent | 09c941dd2ffd4f98ba706895a67133318c3c5007 (diff) | |
parent | 4f21cbafb247664bd7b89bf2d39944764b1763b1 (diff) | |
download | sdl_core-e380ed1779e4317437cea63f070a8345b41f2d33.tar.gz |
Merge branch 'develop' into feature/boost_lock_implementation
Diffstat (limited to 'src/components/utils')
-rw-r--r-- | src/components/utils/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/components/utils/include/utils/optional.h | 83 | ||||
-rw-r--r-- | src/components/utils/include/utils/system_time_handler.h | 151 | ||||
-rw-r--r-- | src/components/utils/include/utils/timer.h | 2 | ||||
-rw-r--r-- | src/components/utils/src/lock_posix.cc | 13 | ||||
-rw-r--r-- | src/components/utils/src/system_time_handler.cc (renamed from src/components/utils/test/atomic_object_test.cc) | 41 | ||||
-rw-r--r-- | src/components/utils/test/conditional_variable_test.cc | 2 | ||||
-rw-r--r-- | src/components/utils/test/data_accessor_test.cc | 36 |
8 files changed, 289 insertions, 40 deletions
diff --git a/src/components/utils/CMakeLists.txt b/src/components/utils/CMakeLists.txt index 46acf76e89..6449f123a4 100644 --- a/src/components/utils/CMakeLists.txt +++ b/src/components/utils/CMakeLists.txt @@ -38,6 +38,7 @@ include_directories ( ${COMPONENTS_DIR}/config_profile/include ${COMPONENTS_DIR}/media_manager/include ${COMPONENTS_DIR}/protocol_handler/include + ${JSONCPP_INCLUDE_DIRECTORY} ${LOG4CXX_INCLUDE_DIRECTORY} ) diff --git a/src/components/utils/include/utils/optional.h b/src/components/utils/include/utils/optional.h new file mode 100644 index 0000000000..0395945de0 --- /dev/null +++ b/src/components/utils/include/utils/optional.h @@ -0,0 +1,83 @@ +#ifndef ERROR_OR_H +#define ERROR_OR_H +#include <string> +#include "utils/macro.h" + +namespace utils { + +/** + * @brief The Optional class is able to keep value, manage it it is empty and + * specify error code. + * Can be used as return value of function that is not guarantee that vaue will + * be returned + * + */ +template <typename ObjectType, typename ErrorType = std::string> +class Optional { + public: + /** + * @brief The OptionalEmpty enum enum with one value to specify that Optional + * is not initialized + */ + enum OptionalEmpty { EMPTY }; + + /** + * @brief Optional constructor with object initialization + * @param object object to initialize Optional + */ + Optional(ObjectType& object) + : object_(&object), error_(), is_initialized_(true) {} + + /** + * @brief Optional constructor with object and error initialization + * @param object object to initialize Optional + * @param error error code initialization + */ + Optional(ObjectType& object, ErrorType error) + : object_(&object), error_(error), is_initialized_(true) {} + + /** + * @brief Optional constructir without object initialization + * @param empty manadatory parameter for explicit specifying that Optional is + * empty + * @param error error code initialization + */ + Optional(OptionalEmpty empty, ErrorType error) + : object_(nullptr), error_(error), is_initialized_(false) {} + + /** + * @brief Optional empty optional initialization without specifying error code + * @param empty manadatory parameter for explicit specifying that Optional is + * empty + */ + Optional(OptionalEmpty empty) + : object_(nullptr), error_(), is_initialized_(false) {} + + /** + * @brief operator bool operator for checking if optional is initialized + */ + operator bool() const { + return is_initialized_; + } + + /** + * @brief operator * access to object + * @return + */ + ObjectType& operator*() const { + DCHECK(is_initialized_); + return *object_; + } + + ErrorType error() const { + return error_; + } + + private: + ObjectType* object_; + ErrorType error_; + bool is_initialized_; +}; + +} // utils utils +#endif // ERROR_OR_H diff --git a/src/components/utils/include/utils/system_time_handler.h b/src/components/utils/include/utils/system_time_handler.h new file mode 100644 index 0000000000..15b2dd0cca --- /dev/null +++ b/src/components/utils/include/utils/system_time_handler.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2018, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_ +#define SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_ + +#include <time.h> + +namespace utils { + +/** + * @brief The SystemTimeListener interface. + * This interface allows to get notifications whenever + * system time appears or fails to appear. + */ +class SystemTimeListener { + public: + /** + * @brief OnSystemTimeArrived Notify about system time + * in utc format + * @param utc_time current system time. + */ + virtual void OnSystemTimeArrived(const time_t utc_time) = 0; +}; + +/** + * @brief SystemTimeHandler the interface which provides the necessary + * public API to work with system time. The class does not implement + * any logic it's public api forwards call to the private virtual + * methods which are suppose to be defined within specific implementation. + */ +class SystemTimeHandler { + public: + /** + * @brief SystemTimeHandler creates an instance + * for this class. + */ + SystemTimeHandler(); + + /** + * @brief QuerySystemTime provides the public interface + * to retrieve the system time. Interface uses private implementation + * hence the logic will be defined within descendant class. + */ + void QuerySystemTime(); + + /** + * @brief SubscribeOnSystemTime allows to subscribe listener + * to the certain event. This class does not provide such storage. + * It rather uses private pure virtual function. So the final behaviour + * should be defined within the descendant class + */ + void SubscribeOnSystemTime(SystemTimeListener* listener); + + /** + * @brief UnsubscribeFromSystemTime allows to unsubscribe listener + * from the certain event. This class does not manipulate with storage. + * It rather uses private pure virtual function. So the final behaviour + * should be defined within the descendant class + */ + void UnsubscribeFromSystemTime(SystemTimeListener* listener); + + /** + * @brief GetUTCTime allows to obtain cached result for the + * GetSystemTime request + * @return utc time. + */ + time_t GetUTCTime(); + + /** + * @brief Checks if system time is ready + * and can be requested by GetSystemTime request + * @return True if HMI is ready to provide UTC time + * otherwise False + */ + bool system_time_can_be_received() const; + + /** + * @brief ~SystemTimeHandler destroys the object + */ + virtual ~SystemTimeHandler(); + + private: + /** + * @brief DoSystemTimeQuery responsible for the system time querying. + * It is up to implementator how exactly system is going to receive this time. + */ + virtual void DoSystemTimeQuery() = 0; + + /** + * @brief DoSubscribe implements the logic which allows to handle + * subscription process. The handling logic should be defined within + * descendant class. + */ + virtual void DoSubscribe(SystemTimeListener* listener) = 0; + + /** + * @brief DoUnsubscribe implements the logic which allows to handle + * unsubscription process. The handling logic should be defined within + * descendant class. + */ + virtual void DoUnsubscribe(SystemTimeListener* listener) = 0; + + /** + * @brief FetchSystemTime allows to obtain the cached result + * for the GetSystemTime request. + * @return utc time. + */ + virtual time_t FetchSystemTime() = 0; + + /** + * @brief Checks if UTC time is ready to provided by HMI + * and can be requested by GetSystemTime request + * @return True if HMI is ready to provide UTC time + * otherwise False + */ + virtual bool utc_time_can_be_received() const = 0; +}; + +} // namespace utils + +#endif // SRC_COMPONENTS_UTILS_INCLUDE_UTILS_SYSTEM_TIME_HANDLER_H_ diff --git a/src/components/utils/include/utils/timer.h b/src/components/utils/include/utils/timer.h index ab3d48ef6f..e391db992c 100644 --- a/src/components/utils/include/utils/timer.h +++ b/src/components/utils/include/utils/timer.h @@ -218,7 +218,7 @@ class Timer { mutable sync_primitives::Lock state_lock_; - mutable std::auto_ptr<TimerDelegate> delegate_; + mutable std::unique_ptr<TimerDelegate> delegate_; threads::Thread* thread_; /** diff --git a/src/components/utils/src/lock_posix.cc b/src/components/utils/src/lock_posix.cc index 0f795bb669..2807de1d0a 100644 --- a/src/components/utils/src/lock_posix.cc +++ b/src/components/utils/src/lock_posix.cc @@ -63,14 +63,16 @@ Lock::Lock(bool is_recursive) Lock::~Lock() { #ifndef NDEBUG if (lock_taken_ > 0) { - LOG4CXX_ERROR(logger_, "Destroying non-released mutex " << &mutex_); + LOG4CXX_FATAL(logger_, "Destroying non-released mutex " << &mutex_); + NOTREACHED(); } #endif int32_t status = pthread_mutex_destroy(&mutex_); if (status != 0) { - LOG4CXX_ERROR(logger_, + LOG4CXX_FATAL(logger_, "Failed to destroy mutex " << &mutex_ << ": " << strerror(status)); + NOTREACHED(); } } @@ -90,9 +92,10 @@ void Lock::Release() { AssertTakenAndMarkFree(); const int32_t status = pthread_mutex_unlock(&mutex_); if (status != 0) { - LOG4CXX_ERROR(logger_, + LOG4CXX_FATAL(logger_, "Failed to unlock mutex" << &mutex_ << ": " << strerror(status)); + NOTREACHED(); } } @@ -110,14 +113,14 @@ bool Lock::Try() { #ifndef NDEBUG void Lock::AssertFreeAndMarkTaken() { if ((lock_taken_ > 0) && !is_mutex_recursive_) { - LOG4CXX_ERROR(logger_, "Locking already taken not recursive mutex"); + LOG4CXX_FATAL(logger_, "Locking already taken not recursive mutex"); NOTREACHED(); } lock_taken_++; } void Lock::AssertTakenAndMarkFree() { if (lock_taken_ == 0) { - LOG4CXX_ERROR(logger_, "Unlocking a mutex that is not taken"); + LOG4CXX_FATAL(logger_, "Unlocking a mutex that is not taken"); NOTREACHED(); } lock_taken_--; diff --git a/src/components/utils/test/atomic_object_test.cc b/src/components/utils/src/system_time_handler.cc index 44975fd004..0c3c62cc53 100644 --- a/src/components/utils/test/atomic_object_test.cc +++ b/src/components/utils/src/system_time_handler.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Ford Motor Company + * Copyright (c) 2018, Ford Motor Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,28 +30,33 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "utils/atomic_object.h" -#include "gtest/gtest.h" +#include "utils/system_time_handler.h" -namespace test { -namespace components { -namespace utils_test { +namespace utils { -TEST(AtomicObjectTest, Construct) { - sync_primitives::atomic_int var(5); - EXPECT_EQ(5, var); +SystemTimeHandler::SystemTimeHandler() {} - var = 8; - EXPECT_EQ(8, var); +SystemTimeHandler::~SystemTimeHandler() {} - sync_primitives::atomic_bool flag = true; +void SystemTimeHandler::QuerySystemTime() { + DoSystemTimeQuery(); +} + +void SystemTimeHandler::SubscribeOnSystemTime(SystemTimeListener* listener) { + DoSubscribe(listener); +} - EXPECT_TRUE(flag == true); +void SystemTimeHandler::UnsubscribeFromSystemTime( + SystemTimeListener* listener) { + DoUnsubscribe(listener); +} + +time_t SystemTimeHandler::GetUTCTime() { + return FetchSystemTime(); +} - flag = false; - EXPECT_FALSE(flag == true); +bool SystemTimeHandler::system_time_can_be_received() const { + return utc_time_can_be_received(); } -} // namespace utils_test -} // namespace components -} // namespace test +} // namespace utils diff --git a/src/components/utils/test/conditional_variable_test.cc b/src/components/utils/test/conditional_variable_test.cc index 290ff3434f..1ef29685e6 100644 --- a/src/components/utils/test/conditional_variable_test.cc +++ b/src/components/utils/test/conditional_variable_test.cc @@ -61,8 +61,8 @@ class ConditionalVariableTest : public ::testing::Test { protected: std::string test_value_; - sync_primitives::ConditionalVariable cond_var_; sync_primitives::Lock test_mutex_; + sync_primitives::ConditionalVariable cond_var_; unsigned counter_; }; diff --git a/src/components/utils/test/data_accessor_test.cc b/src/components/utils/test/data_accessor_test.cc index c7c728b676..24b7bab282 100644 --- a/src/components/utils/test/data_accessor_test.cc +++ b/src/components/utils/test/data_accessor_test.cc @@ -41,7 +41,8 @@ namespace utils_test { TEST(DataAccessorTest, CreateDataAccessor) { // arrange int test_value = 10; - sync_primitives::Lock testSet_lock_; + std::shared_ptr<sync_primitives::Lock> testSet_lock_ = + std::make_shared<sync_primitives::Lock>(); DataAccessor<int> testdata(test_value, testSet_lock_); int data_from_testdata = testdata.GetData(); @@ -52,17 +53,19 @@ TEST(DataAccessorTest, CreateDataAccessor) { TEST(DataAccessorTest, CreateDataAccessor_MutexIsLocked_CannotLockItAgain) { // arrange int test_value = 10; - sync_primitives::Lock testSet_lock_; + std::shared_ptr<sync_primitives::Lock> testSet_lock_ = + std::make_shared<sync_primitives::Lock>(); DataAccessor<int> testdata(test_value, testSet_lock_); // assert - EXPECT_FALSE(testSet_lock_.Try()); + EXPECT_FALSE(testSet_lock_->Try()); } TEST(DataAccessorTest, CopyDataAccessor_GetDataFromDataAccessors) { // arrange int test_value = 10; - sync_primitives::Lock testSet_lock_; + std::shared_ptr<sync_primitives::Lock> testSet_lock_ = + std::make_shared<sync_primitives::Lock>(); DataAccessor<int> testdata(test_value, testSet_lock_); DataAccessor<int> testdata_copy(testdata); @@ -72,14 +75,15 @@ TEST(DataAccessorTest, CopyDataAccessor_GetDataFromDataAccessors) { // assert EXPECT_EQ(data_from_testdata, data_from_testdata_copy); - EXPECT_FALSE(testSet_lock_.Try()); + EXPECT_FALSE(testSet_lock_->Try()); } TEST(DataAccessorTest, ChangedDataInDataAccessor_ChangeData_DataInDataAccessorIsChanged) { // arrange int test_value = 10; - sync_primitives::Lock testSet_lock_; + std::shared_ptr<sync_primitives::Lock> testSet_lock_ = + std::make_shared<sync_primitives::Lock>(); DataAccessor<int> testdata(test_value, testSet_lock_); test_value = 0; @@ -93,40 +97,42 @@ TEST(DataAccessorTest, DeleteDataAccessor_CreatedOneDeleteOneThread_MutexIsUnlocked) { // arrange int test_value = 10; - sync_primitives::Lock testSet_lock_; + std::shared_ptr<sync_primitives::Lock> testSet_lock_ = + std::make_shared<sync_primitives::Lock>(); { DataAccessor<int> testdata(test_value, testSet_lock_); // assert - EXPECT_FALSE(testSet_lock_.Try()); + EXPECT_FALSE(testSet_lock_->Try()); } // assert - EXPECT_TRUE(testSet_lock_.Try()); + EXPECT_TRUE(testSet_lock_->Try()); - testSet_lock_.Release(); + testSet_lock_->Release(); } TEST(DataAccessorTest, DeleteDataAccessor_CreatedThreadAndCopyDeleteBothThreads_MutexIsUnlocked) { // arrange int test_value = 10; - sync_primitives::Lock testSet_lock_; + std::shared_ptr<sync_primitives::Lock> testSet_lock_ = + std::make_shared<sync_primitives::Lock>(); { DataAccessor<int> testdata(test_value, testSet_lock_); { DataAccessor<int> testdata_copy(testdata); // assert - EXPECT_FALSE(testSet_lock_.Try()); + EXPECT_FALSE(testSet_lock_->Try()); } // assert - EXPECT_FALSE(testSet_lock_.Try()); + EXPECT_FALSE(testSet_lock_->Try()); } // assert - EXPECT_TRUE(testSet_lock_.Try()); - testSet_lock_.Release(); + EXPECT_TRUE(testSet_lock_->Try()); + testSet_lock_->Release(); } } // namespace utils_test |