diff options
author | Conlain Kelly <conlain.k@gmail.com> | 2018-05-31 14:54:52 -0400 |
---|---|---|
committer | Conlain Kelly <conlain.k@gmail.com> | 2018-05-31 14:54:52 -0400 |
commit | 44007f451d947d97870624f4990c1033d3808276 (patch) | |
tree | 3e4a77a396295db226e32d25248acd3a6ff7d2d4 /src/components | |
parent | 33b00a89cc114d433669fe8af6e9889efb7b67c1 (diff) | |
download | sdl_core-44007f451d947d97870624f4990c1033d3808276.tar.gz |
Begin changing locks over, very segfault-y right now
This required modification of the condition variable class as well
as every instance of a recursive lock
Diffstat (limited to 'src/components')
32 files changed, 622 insertions, 199 deletions
diff --git a/src/components/application_manager/include/application_manager/app_launch/app_launch_data_json.h b/src/components/application_manager/include/application_manager/app_launch/app_launch_data_json.h index 61117e552b..44b70ee305 100644 --- a/src/components/application_manager/include/application_manager/app_launch/app_launch_data_json.h +++ b/src/components/application_manager/include/application_manager/app_launch/app_launch_data_json.h @@ -141,7 +141,7 @@ class AppLaunchDataJson : public AppLaunchDataImpl { /** * @brief lock to protected common data */ - mutable sync_primitives::Lock app_launch_json_lock_; + mutable sync_primitives::RecursiveLock app_launch_json_lock_; /** * @brief ponter to Last State object diff --git a/src/components/application_manager/include/application_manager/application_data_impl.h b/src/components/application_manager/include/application_manager/application_data_impl.h index dc9be4e1d8..3690508f74 100644 --- a/src/components/application_manager/include/application_manager/application_data_impl.h +++ b/src/components/application_manager/include/application_manager/application_data_impl.h @@ -275,13 +275,13 @@ class DynamicApplicationDataImpl : public virtual Application { std::string display_layout_; CommandsMap commands_; - mutable sync_primitives::Lock commands_lock_; + mutable sync_primitives::RecursiveLock commands_lock_; SubMenuMap sub_menu_; mutable sync_primitives::Lock sub_menu_lock_; ChoiceSetMap choice_set_map_; mutable sync_primitives::Lock choice_set_map_lock_; PerformChoiceSetMap performinteraction_choice_set_map_; - mutable sync_primitives::Lock performinteraction_choice_set_lock_; + mutable sync_primitives::RecursiveLock performinteraction_choice_set_lock_; uint32_t is_perform_interaction_active_; bool is_reset_global_properties_active_; int32_t perform_interaction_mode_; diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index 286ad87018..985932a172 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -1698,7 +1698,7 @@ class ApplicationManagerImpl ForbiddenApps forbidden_applications; // Lock for applications list - mutable sync_primitives::Lock applications_list_lock_; + mutable sync_primitives::RecursiveLock applications_list_lock_; mutable sync_primitives::Lock apps_to_register_list_lock_; mutable sync_primitives::Lock subscribed_way_points_apps_lock_; @@ -1799,7 +1799,7 @@ class ApplicationManagerImpl std::vector<TimerSPtr> timer_pool_; sync_primitives::Lock timer_pool_lock_; - sync_primitives::Lock stopping_application_mng_lock_; + sync_primitives::RecursiveLock stopping_application_mng_lock_; StateControllerImpl state_ctrl_; std::auto_ptr<app_launch::AppLaunchData> app_launch_dto_; std::auto_ptr<app_launch::AppLaunchCtrl> app_launch_ctrl_; diff --git a/src/components/application_manager/include/application_manager/commands/mobile/create_interaction_choice_set_request.h b/src/components/application_manager/include/application_manager/commands/mobile/create_interaction_choice_set_request.h index c00d310e7d..f79a2e7225 100644 --- a/src/components/application_manager/include/application_manager/commands/mobile/create_interaction_choice_set_request.h +++ b/src/components/application_manager/include/application_manager/commands/mobile/create_interaction_choice_set_request.h @@ -136,7 +136,7 @@ class CreateInteractionChoiceSetRequest : public CommandRequestImpl { volatile bool is_timed_out_; sync_primitives::Lock is_timed_out_lock_; - sync_primitives::Lock vr_commands_lock_; + sync_primitives::RecursiveLock vr_commands_lock_; /* * @brief Sends VR AddCommand request to HMI * diff --git a/src/components/application_manager/include/application_manager/event_engine/event_dispatcher_impl.h b/src/components/application_manager/include/application_manager/event_engine/event_dispatcher_impl.h index 4cdbb902de..ed923369ac 100644 --- a/src/components/application_manager/include/application_manager/event_engine/event_dispatcher_impl.h +++ b/src/components/application_manager/include/application_manager/event_engine/event_dispatcher_impl.h @@ -118,7 +118,7 @@ class EventDispatcherImpl : public EventDispatcher { private: // Members section sync_primitives::Lock state_lock_; - sync_primitives::Lock observer_lock_; + sync_primitives::RecursiveLock observer_lock_; EventObserverMap observers_event_; ObserverVector observers_; }; diff --git a/src/components/application_manager/include/application_manager/policies/policy_handler.h b/src/components/application_manager/include/application_manager/policies/policy_handler.h index b4653c6cb2..4be01214ab 100644 --- a/src/components/application_manager/include/application_manager/policies/policy_handler.h +++ b/src/components/application_manager/include/application_manager/policies/policy_handler.h @@ -726,7 +726,7 @@ class PolicyHandler : public PolicyHandlerInterface, std::map<std::string, std::string> app_to_device_link_; // Lock for app to device list - sync_primitives::Lock app_to_device_link_lock_; + sync_primitives::RecursiveLock app_to_device_link_lock_; utils::SharedPtr<StatisticManagerImpl> statistic_manager_impl_; const PolicySettings& settings_; diff --git a/src/components/application_manager/include/application_manager/resumption/resumption_data.h b/src/components/application_manager/include/application_manager/resumption/resumption_data.h index bee2bce570..5ecfaf3c11 100644 --- a/src/components/application_manager/include/application_manager/resumption/resumption_data.h +++ b/src/components/application_manager/include/application_manager/resumption/resumption_data.h @@ -276,7 +276,7 @@ class ResumptionData { ++first; } } - mutable sync_primitives::Lock resumption_lock_; + mutable sync_primitives::RecursiveLock resumption_lock_; const application_manager::ApplicationManager& application_manager_; }; } // namespace resumption diff --git a/src/components/application_manager/src/app_launch/app_launch_data_json.cc b/src/components/application_manager/src/app_launch/app_launch_data_json.cc index 7599dcccb3..99a6416a69 100644 --- a/src/components/application_manager/src/app_launch/app_launch_data_json.cc +++ b/src/components/application_manager/src/app_launch/app_launch_data_json.cc @@ -44,7 +44,6 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "AppLaunch") AppLaunchDataJson::AppLaunchDataJson(const AppLaunchSettings& settings, resumption::LastState& last_state) : AppLaunchDataImpl(settings) - , app_launch_json_lock_(true) , last_state_(last_state) {} AppLaunchDataJson::~AppLaunchDataJson() {} diff --git a/src/components/application_manager/src/application_data_impl.cc b/src/components/application_manager/src/application_data_impl.cc index 226c83dbf6..931b3571fb 100644 --- a/src/components/application_manager/src/application_data_impl.cc +++ b/src/components/application_manager/src/application_data_impl.cc @@ -177,11 +177,9 @@ DynamicApplicationDataImpl::DynamicApplicationDataImpl() , night_color_scheme_(NULL) , display_layout_("") , commands_() - , commands_lock_(true) , sub_menu_() , choice_set_map_() , performinteraction_choice_set_map_() - , performinteraction_choice_set_lock_(true) , is_perform_interaction_active_(false) , is_reset_global_properties_active_(false) , perform_interaction_mode_(-1) {} diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 3ead8fe65e..7d1b1aaeda 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -141,7 +141,6 @@ ApplicationManagerImpl::ApplicationManagerImpl( const ApplicationManagerSettings& am_settings, const policy::PolicySettings& policy_settings) : settings_(am_settings) - , applications_list_lock_(true) , audio_pass_thru_active_(false) , audio_pass_thru_app_id_(0) , driver_distraction_state_( @@ -168,7 +167,6 @@ ApplicationManagerImpl::ApplicationManagerImpl( , resume_ctrl_(new resumption::ResumeCtrlImpl(*this)) , navi_close_app_timeout_(am_settings.stop_streaming_timeout()) , navi_end_stream_timeout_(am_settings.stop_streaming_timeout()) - , stopping_application_mng_lock_(true) , state_ctrl_(*this) #ifdef TELEMETRY_MONITOR , metric_observer_(NULL) diff --git a/src/components/application_manager/src/commands/mobile/create_interaction_choice_set_request.cc b/src/components/application_manager/src/commands/mobile/create_interaction_choice_set_request.cc index 20387ef230..2ee3fd8bb8 100644 --- a/src/components/application_manager/src/commands/mobile/create_interaction_choice_set_request.cc +++ b/src/components/application_manager/src/commands/mobile/create_interaction_choice_set_request.cc @@ -53,8 +53,7 @@ CreateInteractionChoiceSetRequest::CreateInteractionChoiceSetRequest( , expected_chs_count_(0) , received_chs_count_(0) , error_from_hmi_(false) - , is_timed_out_(false) - , vr_commands_lock_(true) {} + , is_timed_out_(false) {} CreateInteractionChoiceSetRequest::~CreateInteractionChoiceSetRequest() { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/application_manager/src/event_engine/event_dispatcher_impl.cc b/src/components/application_manager/src/event_engine/event_dispatcher_impl.cc index b19a6f9194..505465d001 100644 --- a/src/components/application_manager/src/event_engine/event_dispatcher_impl.cc +++ b/src/components/application_manager/src/event_engine/event_dispatcher_impl.cc @@ -40,7 +40,7 @@ namespace event_engine { using namespace sync_primitives; EventDispatcherImpl::EventDispatcherImpl() - : state_lock_(false), observer_lock_(true), observers_event_() {} + : observers_event_() {} EventDispatcherImpl::~EventDispatcherImpl() {} diff --git a/src/components/application_manager/src/policies/policy_handler.cc b/src/components/application_manager/src/policies/policy_handler.cc index 559b9c0035..4c4b5d47da 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -325,7 +325,6 @@ PolicyHandler::PolicyHandler(const PolicySettings& settings, : AsyncRunner("PolicyHandler async runner thread") , dl_handle_(0) , last_activated_app_id_(0) - , app_to_device_link_lock_(true) , statistic_manager_impl_(utils::MakeShared<StatisticManagerImpl>(this)) , settings_(settings) , application_manager_(application_manager) {} diff --git a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc index e3fd423970..e370d345b8 100644 --- a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc +++ b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc @@ -57,7 +57,6 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "Resumption") ResumeCtrlImpl::ResumeCtrlImpl(ApplicationManager& application_manager) : event_engine::EventObserver(application_manager.event_dispatcher()) - , queue_lock_(false) , restore_hmi_level_timer_( "RsmCtrlRstore", new timer::TimerTaskImpl<ResumeCtrlImpl>( diff --git a/src/components/application_manager/src/resumption/resumption_data.cc b/src/components/application_manager/src/resumption/resumption_data.cc index bd5bdbddab..ca049917c4 100644 --- a/src/components/application_manager/src/resumption/resumption_data.cc +++ b/src/components/application_manager/src/resumption/resumption_data.cc @@ -41,7 +41,7 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "Resumption") ResumptionData::ResumptionData( const application_manager::ApplicationManager& application_manager) - : resumption_lock_(true), application_manager_(application_manager) {} + : application_manager_(application_manager) {} smart_objects::SmartObject ResumptionData::GetApplicationCommands( app_mngr::ApplicationConstSharedPtr application) const { diff --git a/src/components/application_manager/test/message_helper/message_helper_test.cc b/src/components/application_manager/test/message_helper/message_helper_test.cc index 289e4f5d05..dc4b3f48bf 100644 --- a/src/components/application_manager/test/message_helper/message_helper_test.cc +++ b/src/components/application_manager/test/message_helper/message_helper_test.cc @@ -236,7 +236,7 @@ TEST(MessageHelperTestCreate, CreateAddCommandRequestToHMI_SendSmartObject_Empty) { MockApplicationSharedPtr appSharedMock = utils::MakeShared<MockApplication>(); ::application_manager::CommandsMap vis; - DataAccessor<application_manager::CommandsMap> data_accessor(vis, true); + DataAccessor<application_manager::CommandsMap> data_accessor(vis, sync_primitives::RecursiveLock()); EXPECT_CALL(*appSharedMock, commands_map()).WillOnce(Return(data_accessor)); application_manager_test::MockApplicationManager mock_application_manager; @@ -251,7 +251,7 @@ TEST(MessageHelperTestCreate, CreateAddCommandRequestToHMI_SendSmartObject_Equal) { MockApplicationSharedPtr appSharedMock = utils::MakeShared<MockApplication>(); CommandsMap vis; - DataAccessor<CommandsMap> data_accessor(vis, true); + DataAccessor<CommandsMap> data_accessor(vis, sync_primitives::RecursiveLock()); smart_objects::SmartObjectSPtr smartObjectPtr = utils::MakeShared<smart_objects::SmartObject>(); @@ -292,7 +292,7 @@ TEST(MessageHelperTestCreate, CreateAddVRCommandRequestFromChoiceToHMI_SendEmptyData_EmptyList) { MockApplicationSharedPtr appSharedMock = utils::MakeShared<MockApplication>(); application_manager::ChoiceSetMap vis; - DataAccessor< ::application_manager::ChoiceSetMap> data_accessor(vis, true); + DataAccessor< ::application_manager::ChoiceSetMap> data_accessor(vis, sync_primitives::RecursiveLock()); EXPECT_CALL(*appSharedMock, choice_set_map()).WillOnce(Return(data_accessor)); application_manager_test::MockApplicationManager mock_application_manager; @@ -307,7 +307,7 @@ TEST(MessageHelperTestCreate, CreateAddVRCommandRequestFromChoiceToHMI_SendObject_EqualList) { MockApplicationSharedPtr appSharedMock = utils::MakeShared<MockApplication>(); application_manager::ChoiceSetMap vis; - DataAccessor< ::application_manager::ChoiceSetMap> data_accessor(vis, true); + DataAccessor< ::application_manager::ChoiceSetMap> data_accessor(vis, sync_primitives::RecursiveLock()); smart_objects::SmartObjectSPtr smartObjectPtr = utils::MakeShared<smart_objects::SmartObject>(); @@ -353,7 +353,7 @@ TEST(MessageHelperTestCreate, TEST(MessageHelperTestCreate, CreateAddSubMenuRequestToHMI_SendObject_Equal) { MockApplicationSharedPtr appSharedMock = utils::MakeShared<MockApplication>(); application_manager::SubMenuMap vis; - DataAccessor< ::application_manager::SubMenuMap> data_accessor(vis, true); + DataAccessor< ::application_manager::SubMenuMap> data_accessor(vis, sync_primitives::RecursiveLock()); smart_objects::SmartObjectSPtr smartObjectPtr = utils::MakeShared<smart_objects::SmartObject>(); @@ -392,7 +392,7 @@ TEST(MessageHelperTestCreate, CreateAddSubMenuRequestToHMI_SendEmptyMap_EmptySmartObjectList) { MockApplicationSharedPtr appSharedMock = utils::MakeShared<MockApplication>(); application_manager::SubMenuMap vis; - DataAccessor< ::application_manager::SubMenuMap> data_accessor(vis, true); + DataAccessor< ::application_manager::SubMenuMap> data_accessor(vis, sync_primitives::RecursiveLock()); EXPECT_CALL(*appSharedMock, sub_menu_map()).WillOnce(Return(data_accessor)); @@ -713,7 +713,7 @@ TEST_F(MessageHelperTest, // Creating data acessor application_manager::VehicleInfoSubscriptions vis; DataAccessor<application_manager::VehicleInfoSubscriptions> data_accessor( - vis, true); + vis, sync_primitives::RecursiveLock()); // Calls for ApplicationManager EXPECT_CALL(*appSharedMock, app_id()).WillOnce(Return(1u)); EXPECT_CALL(*appSharedMock, SubscribedIVI()).WillOnce(Return(data_accessor)); diff --git a/src/components/connection_handler/include/connection_handler/connection.h b/src/components/connection_handler/include/connection_handler/connection.h index 9b72d60776..d46f574707 100644 --- a/src/components/connection_handler/include/connection_handler/connection.h +++ b/src/components/connection_handler/include/connection_handler/connection.h @@ -304,7 +304,7 @@ class Connection { */ SessionMap session_map_; - mutable sync_primitives::Lock session_map_lock_; + mutable sync_primitives::RecursiveLock session_map_lock_; /** * @brief monitor that closes connection if there is no traffic over it diff --git a/src/components/connection_handler/include/connection_handler/heartbeat_monitor.h b/src/components/connection_handler/include/connection_handler/heartbeat_monitor.h index 4d1d07112c..1a0bfce264 100644 --- a/src/components/connection_handler/include/connection_handler/heartbeat_monitor.h +++ b/src/components/connection_handler/include/connection_handler/heartbeat_monitor.h @@ -111,7 +111,7 @@ class HeartBeatMonitor : public threads::ThreadDelegate { typedef std::map<uint8_t, SessionState> SessionMap; SessionMap sessions_; - sync_primitives::Lock sessions_list_lock_; // recurcive + sync_primitives::RecursiveLock sessions_list_lock_; // recurcive sync_primitives::Lock main_thread_lock_; mutable sync_primitives::Lock heartbeat_timeout_seconds_lock_; sync_primitives::ConditionalVariable heartbeat_monitor_; diff --git a/src/components/connection_handler/src/connection.cc b/src/components/connection_handler/src/connection.cc index 16b88c4164..ae7eb1be18 100644 --- a/src/components/connection_handler/src/connection.cc +++ b/src/components/connection_handler/src/connection.cc @@ -81,7 +81,7 @@ Connection::Connection(ConnectionHandle connection_handle, : connection_handler_(connection_handler) , connection_handle_(connection_handle) , connection_device_handle_(connection_device_handle) - , session_map_lock_(true) + , session_map_lock_() , heartbeat_timeout_(heartbeat_timeout) { LOG4CXX_AUTO_TRACE(logger_); DCHECK(connection_handler_); diff --git a/src/components/connection_handler/src/heartbeat_monitor.cc b/src/components/connection_handler/src/heartbeat_monitor.cc index f3a2322810..50af5a042a 100644 --- a/src/components/connection_handler/src/heartbeat_monitor.cc +++ b/src/components/connection_handler/src/heartbeat_monitor.cc @@ -47,7 +47,6 @@ HeartBeatMonitor::HeartBeatMonitor(uint32_t heartbeat_timeout_mseconds, Connection* connection) : default_heartbeat_timeout_(heartbeat_timeout_mseconds) , connection_(connection) - , sessions_list_lock_(true) , run_(true) {} void HeartBeatMonitor::Process() { diff --git a/src/components/include/utils/conditional_variable.h b/src/components/include/utils/conditional_variable.h index f54a22e993..a29f255dbf 100644 --- a/src/components/include/utils/conditional_variable.h +++ b/src/components/include/utils/conditional_variable.h @@ -32,24 +32,13 @@ #ifndef SRC_COMPONENTS_INCLUDE_UTILS_CONDITIONAL_VARIABLE_H_ #define SRC_COMPONENTS_INCLUDE_UTILS_CONDITIONAL_VARIABLE_H_ -#if defined(OS_POSIX) -#include <pthread.h> -#else -#error Please implement conditional variable for your OS -#endif #include <stdint.h> +#include <boost/thread/condition_variable.hpp> +#include "utils/lock.h" #include "utils/macro.h" namespace sync_primitives { -class AutoLock; -class Lock; - -namespace impl { -#if defined(OS_POSIX) -typedef pthread_cond_t PlatformConditionalVariable; -#endif -} // namespace impl /* * Conditional variable wrapper @@ -82,11 +71,11 @@ class ConditionalVariable { // Wait forever or up to milliseconds time limit bool Wait(AutoLock& auto_lock); - bool Wait(Lock& lock); + bool Wait(BaseLock& lock); WaitStatus WaitFor(AutoLock& auto_lock, uint32_t milliseconds); private: - impl::PlatformConditionalVariable cond_var_; + boost::condition_variable_any cond_var_; private: DISALLOW_COPY_AND_ASSIGN(ConditionalVariable); diff --git a/src/components/include/utils/data_accessor.h b/src/components/include/utils/data_accessor.h index 9be28a638b..6239812678 100644 --- a/src/components/include/utils/data_accessor.h +++ b/src/components/include/utils/data_accessor.h @@ -39,9 +39,9 @@ template <class T> class DataAccessor { public: - DataAccessor(const T& data, const sync_primitives::Lock& lock) + DataAccessor(const T& data, const sync_primitives::BaseLock& lock) : data_(data) - , lock_(const_cast<sync_primitives::Lock&>(lock)) + , lock_(const_cast<sync_primitives::BaseLock&>(lock)) , counter_(new uint32_t(0)) { lock_.Acquire(); } @@ -65,7 +65,7 @@ class DataAccessor { private: void* operator new(size_t size); const T& data_; - sync_primitives::Lock& lock_; + sync_primitives::BaseLock& lock_; utils::SharedPtr<uint32_t> counter_; }; diff --git a/src/components/include/utils/lock.h b/src/components/include/utils/lock.h index e615a58f9d..4ace34d71e 100644 --- a/src/components/include/utils/lock.h +++ b/src/components/include/utils/lock.h @@ -32,24 +32,17 @@ #ifndef SRC_COMPONENTS_INCLUDE_UTILS_LOCK_H_ #define SRC_COMPONENTS_INCLUDE_UTILS_LOCK_H_ -#if defined(OS_POSIX) -#include <pthread.h> -#include <sched.h> -#else -#error Please implement lock for your OS -#endif #include <stdint.h> -#include "utils/macro.h" +#include <boost/thread/mutex.hpp> +#include <boost/thread/recursive_mutex.hpp> #include "utils/atomic.h" +#include "utils/macro.h" #include "utils/memory_barrier.h" +#include <iostream> -namespace sync_primitives { +using boost::system::error_code; -namespace impl { -#if defined(OS_POSIX) -typedef pthread_mutex_t PlatformMutex; -#endif -} // namespace impl +namespace sync_primitives { class SpinMutex { public: @@ -78,71 +71,89 @@ class SpinMutex { volatile unsigned int state_; }; -/* Platform-indepenednt NON-RECURSIVE lock (mutex) wrapper - Please use AutoLock to ackquire and (automatically) release it - It eases balancing of multple lock taking/releasing and makes it - Impossible to forget to release the lock: - ... - ConcurentlyAccessedData data_; - sync_primitives::Lock data_lock_; - ... - { - sync_primitives::AutoLock auto_lock(data_lock_); - data_.ReadOrWriteData(); - } // lock is automatically released here -*/ -class Lock { +/* Abstract base class that allows AutoLock to handle both recursive and + * non-recursive locks + */ +class BaseLock { public: - Lock(); - Lock(bool is_recursive); - ~Lock(); - + BaseLock() : lock_taken_(0) {} // Ackquire the lock. Must be called only once on a thread. // Please consider using AutoLock to capture it. - void Acquire(); + virtual void Acquire() = 0; // Release the lock. Must be called only once on a thread after lock. // was acquired. Please consider using AutoLock to automatically release // the lock - void Release(); + virtual void Release() = 0; // Try if lock can be captured and lock it if it was possible. // If it captured, lock must be manually released calling to Release // when protected resource access was finished. // @returns wether lock was captured. - bool Try(); - - private: - impl::PlatformMutex mutex_; + virtual bool Try() = 0; -#ifndef NDEBUG + protected: /** - * @brief Basic debugging aid, a flag that signals wether this lock is - * currently taken - * Allows detection of abandoned and recursively captured mutexes - */ + * @brief Basic debugging aid, a flag that signals wether this lock is + * currently taken + * Allows detection of abandoned and recursively captured mutexes + */ uint32_t lock_taken_; - /** - * @brief Describe if mutex is recurcive or not - */ - bool is_mutex_recursive_; + // Ensures safety in locking + virtual void AssertTakenAndMarkFree() = 0; + virtual void AssertFreeAndMarkTaken() = 0; - void AssertFreeAndMarkTaken(); - void AssertTakenAndMarkFree(); -#else - void AssertFreeAndMarkTaken() {} - void AssertTakenAndMarkFree() {} -#endif +friend class ConditionalVariable; +}; - void Init(bool is_recursive); +/* + * Platform-indepenednt NON-RECURSIVE lock (mutex) wrapper + */ +class Lock : public BaseLock { + public: + Lock(); + ~Lock(); - friend class ConditionalVariable; + virtual void Acquire(); + + virtual void Release(); + + virtual bool Try(); + + private: + virtual void AssertTakenAndMarkFree(); + virtual void AssertFreeAndMarkTaken(); + boost::mutex mutex_; DISALLOW_COPY_AND_ASSIGN(Lock); + friend class ConditionalVariable; +}; + +/* + * Platform-indepenednt RECURSIVE lock (mutex) wrapper + */ +class RecursiveLock : public BaseLock { + public: + RecursiveLock(); + ~RecursiveLock(); + + virtual void Acquire(); + + virtual void Release(); + + virtual bool Try(); + + private: + virtual void AssertTakenAndMarkFree(); + virtual void AssertFreeAndMarkTaken(); + boost::recursive_mutex mutex_; + DISALLOW_COPY_AND_ASSIGN(RecursiveLock); + friend class ConditionalVariable; }; // This class is used to automatically acquire and release the a lock class AutoLock { public: - explicit AutoLock(Lock& lock) : lock_(lock) { + explicit AutoLock(BaseLock& lock) : lock_(lock) { + std::cerr << "lock is at " << &lock << std::endl; lock_.Acquire(); } ~AutoLock() { @@ -150,21 +161,32 @@ class AutoLock { } private: - Lock& GetLock() { + BaseLock& GetLock() { return lock_; } - Lock& lock_; + BaseLock& lock_; private: friend class AutoUnlock; friend class ConditionalVariable; DISALLOW_COPY_AND_ASSIGN(AutoLock); }; - +/* Please use AutoLock to ackquire and (automatically) release it + * It eases balancing of multple lock taking/releasing and makes it + * Impossible to forget to release the lock: + * ... + * ConcurentlyAccessedData data_; + * sync_primitives::Lock data_lock_; + * ... + * { + * sync_primitives::AutoLock auto_lock(data_lock_); + * data_.ReadOrWriteData(); + * } // lock is automatically released here + */ // This class is used to temporarly unlock autolocked lock class AutoUnlock { public: - explicit AutoUnlock(Lock& lock) : lock_(lock) { + explicit AutoUnlock(BaseLock& lock) : lock_(lock) { lock_.Release(); } explicit AutoUnlock(AutoLock& lock) : lock_(lock.GetLock()) { @@ -175,7 +197,7 @@ class AutoUnlock { } private: - Lock& lock_; + BaseLock& lock_; private: DISALLOW_COPY_AND_ASSIGN(AutoUnlock); diff --git a/src/components/include/utils/lock_posix.h b/src/components/include/utils/lock_posix.h new file mode 100644 index 0000000000..ae8b64959f --- /dev/null +++ b/src/components/include/utils/lock_posix.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2013, 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_INCLUDE_UTILS_LOCK_H_ +#define SRC_COMPONENTS_INCLUDE_UTILS_LOCK_H_ + +#if defined(OS_POSIX) +#include <pthread.h> +#include <sched.h> +#else +#error Please implement lock for your OS +#endif +#include <stdint.h> +#include "utils/macro.h" +#include "utils/atomic.h" +#include "utils/memory_barrier.h" + +namespace sync_primitives_posix { + +namespace impl { +#if defined(OS_POSIX) +typedef pthread_mutex_t PlatformMutex; +#endif +} // namespace impl + +class SpinMutex { + public: + SpinMutex() : state_(0) {} + void Lock() { + // Comment below add exception for lint error + // Reason: FlexeLint doesn't know about compiler's built-in instructions + /*lint -e1055*/ + if (atomic_post_set(&state_) == 0) { + return; + } + for (;;) { + sched_yield(); + /*lint -e1055*/ + if (state_ == 0 && atomic_post_set(&state_) == 0) { + return; + } + } + } + void Unlock() { + state_ = 0; + } + ~SpinMutex() {} + + private: + volatile unsigned int state_; +}; + +/* Platform-indepenednt NON-RECURSIVE lock (mutex) wrapper + Please use AutoLock to ackquire and (automatically) release it + It eases balancing of multple lock taking/releasing and makes it + Impossible to forget to release the lock: + ... + ConcurentlyAccessedData data_; + sync_primitives::Lock data_lock_; + ... + { + sync_primitives::AutoLock auto_lock(data_lock_); + data_.ReadOrWriteData(); + } // lock is automatically released here +*/ +class Lock { + public: + Lock(); + Lock(bool is_recursive); + ~Lock(); + + // Ackquire the lock. Must be called only once on a thread. + // Please consider using AutoLock to capture it. + void Acquire(); + // Release the lock. Must be called only once on a thread after lock. + // was acquired. Please consider using AutoLock to automatically release + // the lock + void Release(); + // Try if lock can be captured and lock it if it was possible. + // If it captured, lock must be manually released calling to Release + // when protected resource access was finished. + // @returns wether lock was captured. + bool Try(); + + private: + impl::PlatformMutex mutex_; + +#ifndef NDEBUG + /** + * @brief Basic debugging aid, a flag that signals wether this lock is + * currently taken + * Allows detection of abandoned and recursively captured mutexes + */ + uint32_t lock_taken_; + + /** + * @brief Describe if mutex is recurcive or not + */ + bool is_mutex_recursive_; + + void AssertFreeAndMarkTaken(); + void AssertTakenAndMarkFree(); +#else + void AssertFreeAndMarkTaken() {} + void AssertTakenAndMarkFree() {} +#endif + + void Init(bool is_recursive); + + friend class ConditionalVariable; + DISALLOW_COPY_AND_ASSIGN(Lock); +}; + +// This class is used to automatically acquire and release the a lock +class AutoLock { + public: + explicit AutoLock(Lock& lock) : lock_(lock) { + lock_.Acquire(); + } + ~AutoLock() { + lock_.Release(); + } + + private: + Lock& GetLock() { + return lock_; + } + Lock& lock_; + + private: + friend class AutoUnlock; + friend class ConditionalVariable; + DISALLOW_COPY_AND_ASSIGN(AutoLock); +}; + +// This class is used to temporarly unlock autolocked lock +class AutoUnlock { + public: + explicit AutoUnlock(Lock& lock) : lock_(lock) { + lock_.Release(); + } + explicit AutoUnlock(AutoLock& lock) : lock_(lock.GetLock()) { + lock_.Release(); + } + ~AutoUnlock() { + lock_.Acquire(); + } + + private: + Lock& lock_; + + private: + DISALLOW_COPY_AND_ASSIGN(AutoUnlock); +}; +} // namespace sync_primitives +#endif // SRC_COMPONENTS_INCLUDE_UTILS_LOCK_H_ diff --git a/src/components/policy/policy_regular/include/policy/cache_manager.h b/src/components/policy/policy_regular/include/policy/cache_manager.h index 8c0acd44d2..464aa711bd 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -756,7 +756,7 @@ class CacheManager : public CacheManagerInterface { typedef std::set<std::string> UnpairedDevices; UnpairedDevices is_unpaired_; - mutable sync_primitives::Lock cache_lock_; + mutable sync_primitives::RecursiveLock cache_lock_; sync_primitives::Lock unpaired_lock_; typedef std::map<std::string, Permissions> AppCalculatedPermissions; diff --git a/src/components/policy/policy_regular/src/cache_manager.cc b/src/components/policy/policy_regular/src/cache_manager.cc index 6a142374d5..b10cd51e8b 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -33,18 +33,18 @@ #include "policy/cache_manager.h" #include <algorithm> -#include <functional> -#include <ctime> #include <cmath> +#include <ctime> +#include <functional> #include <sstream> -#include "utils/file_system.h" -#include "json/reader.h" #include "json/features.h" +#include "json/reader.h" #include "json/writer.h" -#include "utils/logger.h" #include "utils/date_time.h" +#include "utils/file_system.h" #include "utils/gen_hash.h" +#include "utils/logger.h" #include "utils/macro.h" #include "utils/threads/thread.h" #include "utils/threads/thread_delegate.h" @@ -102,8 +102,7 @@ CacheManager::CacheManager() : CacheManagerInterface() , pt_(new policy_table::Table) , backup_(new SQLPTRepresentation()) - , update_required(false) - , cache_lock_(true) { + , update_required(false) { LOG4CXX_AUTO_TRACE(logger_); backuper_ = new BackgroundBackuper(this); backup_thread_ = threads::CreateThread("Backup thread", backuper_); @@ -1635,8 +1634,9 @@ void CacheManager::MergeFG(const policy_table::PolicyTable& new_pt, void CacheManager::MergeAP(const policy_table::PolicyTable& new_pt, policy_table::PolicyTable& pt) { LOG4CXX_AUTO_TRACE(logger_); - pt.app_policies_section.device = const_cast<policy_table::PolicyTable&>( - new_pt).app_policies_section.device; + pt.app_policies_section.device = + const_cast<policy_table::PolicyTable&>(new_pt) + .app_policies_section.device; pt.app_policies_section.apps[kDefaultId] = const_cast<policy_table::PolicyTable&>(new_pt) diff --git a/src/components/utils/CMakeLists.txt b/src/components/utils/CMakeLists.txt index 51835c125a..46acf76e89 100644 --- a/src/components/utils/CMakeLists.txt +++ b/src/components/utils/CMakeLists.txt @@ -101,7 +101,7 @@ set(PATHS collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") if (CMAKE_SYSTEM_NAME STREQUAL "QNX") - # --- QDB Wrapper + # --- QDB Wrapper add_subdirectory(./src/qdb_wrapper) else () # --- SQLite Wrapper @@ -109,10 +109,11 @@ else () endif () if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - list(APPEND LIBRARIES dl pthread ${RTLIB}) + list(APPEND LIBRARIES dl pthread ${RTLIB}) endif() add_library("Utils" ${SOURCES}) +list(APPEND LIBRARIES -lboost_system -lboost_filesystem -lboost_thread) target_link_libraries("Utils" ${LIBRARIES}) if(ENABLE_LOG) diff --git a/src/components/utils/src/conditional_variable_posix.cc b/src/components/utils/src/conditional_variable_posix.cc index 50ebc74556..6b2115ad80 100644 --- a/src/components/utils/src/conditional_variable_posix.cc +++ b/src/components/utils/src/conditional_variable_posix.cc @@ -41,108 +41,98 @@ namespace { const long kNanosecondsPerSecond = 1000000000; const long kMillisecondsPerSecond = 1000; const long kNanosecondsPerMillisecond = 1000000; -} +} // namespace namespace sync_primitives { CREATE_LOGGERPTR_GLOBAL(logger_, "Utils") -ConditionalVariable::ConditionalVariable() { - pthread_condattr_t attrs; - int initialized = pthread_condattr_init(&attrs); - if (initialized != 0) - LOG4CXX_ERROR(logger_, - "Failed to initialize " - "conditional variable attributes"); - pthread_condattr_setclock(&attrs, CLOCK_MONOTONIC); - initialized = pthread_cond_init(&cond_var_, &attrs); - if (initialized != 0) - LOG4CXX_ERROR(logger_, - "Failed to initialize " - "conditional variable"); - int rv = pthread_condattr_destroy(&attrs); - if (rv != 0) - LOG4CXX_ERROR(logger_, - "Failed to destroy " - "conditional variable attributes"); -} +ConditionalVariable::ConditionalVariable() {} -ConditionalVariable::~ConditionalVariable() { - pthread_cond_destroy(&cond_var_); -} +ConditionalVariable::~ConditionalVariable() {} void ConditionalVariable::NotifyOne() { - int signaled = pthread_cond_signal(&cond_var_); - if (signaled != 0) - LOG4CXX_ERROR(logger_, "Failed to signal conditional variable"); + cond_var_.notify_one(); } void ConditionalVariable::Broadcast() { - int signaled = pthread_cond_broadcast(&cond_var_); - if (signaled != 0) - LOG4CXX_ERROR(logger_, "Failed to broadcast conditional variable"); + cond_var_.notify_all(); } -bool ConditionalVariable::Wait(Lock& lock) { - lock.AssertTakenAndMarkFree(); - int wait_status = pthread_cond_wait(&cond_var_, &lock.mutex_); - lock.AssertFreeAndMarkTaken(); - if (wait_status != 0) { - LOG4CXX_ERROR(logger_, "Failed to wait for conditional variable"); +bool ConditionalVariable::Wait(BaseLock& lock) { + // NOTE this grossness is due to boost mutex and recursive mutex not sharing a + // superclass + + try { + lock.AssertTakenAndMarkFree(); + // What kind of lock are we ? + if (Lock* test_lock = dynamic_cast<Lock*>(&lock)) { + // Regular lock + cond_var_.wait<boost::mutex>(test_lock->mutex_); + } else if (RecursiveLock* test_rec_lock = + dynamic_cast<RecursiveLock*>(&lock)) { + // Recursive lock + cond_var_.wait<boost::recursive_mutex>(test_rec_lock->mutex_); + } else { + // unknown + LOG4CXX_ERROR(logger_, "Unknown lock type!"); + return false; + } + lock.AssertFreeAndMarkTaken(); + } catch (std::exception err) { + LOG4CXX_ERROR( + logger_, + "Failed to wait for conditional variable, exception:" << err.what()); return false; } + return true; } bool ConditionalVariable::Wait(AutoLock& auto_lock) { - Lock& lock = auto_lock.GetLock(); - lock.AssertTakenAndMarkFree(); - int wait_status = pthread_cond_wait(&cond_var_, &lock.mutex_); - lock.AssertFreeAndMarkTaken(); - if (wait_status != 0) { - LOG4CXX_ERROR(logger_, "Failed to wait for conditional variable"); - return false; - } - return true; + BaseLock& lock = auto_lock.GetLock(); + return Wait(lock); } ConditionalVariable::WaitStatus ConditionalVariable::WaitFor( AutoLock& auto_lock, uint32_t milliseconds) { - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - timespec wait_interval; - wait_interval.tv_sec = now.tv_sec + (milliseconds / kMillisecondsPerSecond); - wait_interval.tv_nsec = - now.tv_nsec + - (milliseconds % kMillisecondsPerSecond) * kNanosecondsPerMillisecond; - wait_interval.tv_sec += wait_interval.tv_nsec / kNanosecondsPerSecond; - wait_interval.tv_nsec %= kNanosecondsPerSecond; - Lock& lock = auto_lock.GetLock(); - lock.AssertTakenAndMarkFree(); - int timedwait_status = - pthread_cond_timedwait(&cond_var_, &lock.mutex_, &wait_interval); - lock.AssertFreeAndMarkTaken(); + BaseLock& lock = auto_lock.GetLock(); + WaitStatus wait_status = kNoTimeout; - switch (timedwait_status) { - case 0: { - wait_status = kNoTimeout; - break; - } - case EINTR: { - wait_status = kNoTimeout; - break; + lock.AssertTakenAndMarkFree(); + try { + bool timeout = true; + + // What kind of lock are we ? + if (Lock* test_lock = dynamic_cast<Lock*>(&lock)) { + // Regular lock + // cond_var_.wait<boost::mutex>(test_lock->mutex_); + timeout = cond_var_.timed_wait<boost::mutex>( + test_lock->mutex_, boost::posix_time::milliseconds(milliseconds)); + } else if (RecursiveLock* test_rec_lock = + dynamic_cast<RecursiveLock*>(&lock)) { + // Recursive lock + // cond_var_.wait<boost::recursive_mutex>(test_rec_lock->mutex_); + timeout = cond_var_.timed_wait<boost::recursive_mutex>( + test_rec_lock->mutex_, boost::posix_time::milliseconds(milliseconds)); + } else { + // unknown + LOG4CXX_ERROR(logger_, "Unknown lock type!"); } - case ETIMEDOUT: { + + if (!timeout) { wait_status = kTimeout; - break; - } - default: { - LOG4CXX_ERROR( - logger_, - "Failed to timewait for conditional variable timedwait_status: " - << timedwait_status); } + } catch (boost::thread_interrupted inter) { + wait_status = kNoTimeout; + + } catch (std::exception err) { + LOG4CXX_ERROR( + logger_, + "Failed to timewait for conditional variable timedwait_status: " + << err.what()); } + return wait_status; } diff --git a/src/components/utils/src/lock_boost.cc b/src/components/utils/src/lock_boost.cc new file mode 100644 index 0000000000..67f8b5d2db --- /dev/null +++ b/src/components/utils/src/lock_boost.cc @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013, 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. + */ + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <cstring> +#include "utils/lock.h" +#include "utils/logger.h" + +namespace sync_primitives { + +CREATE_LOGGERPTR_GLOBAL(logger_, "Utils") + +Lock::Lock() {} + +Lock::~Lock() { + if (lock_taken_ > 0) { + LOG4CXX_ERROR(logger_, "Destroying non-released regular mutex " << &mutex_); + } +} + +void Lock::Acquire() { + try { + mutex_.lock(); + } catch (std::exception err) { + LOG4CXX_FATAL(logger_, + "Failed to acquire mutex " << &mutex_ << ": " << err.what()); + NOTREACHED(); + } + AssertFreeAndMarkTaken(); +} + +void Lock::Release() { + AssertTakenAndMarkFree(); + + mutex_.unlock(); +} + +bool Lock::Try() { + bool status = mutex_.try_lock(); + if (status) { + lock_taken_++; + } + return status; +} + +void Lock::AssertFreeAndMarkTaken() { + if (lock_taken_ != 0) { + LOG4CXX_ERROR(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"); + NOTREACHED(); + } + lock_taken_--; +} + +// Recursive lock looks the same on the surface, some code duplication is +// necessary since they don't have a shared parent superclass +RecursiveLock::RecursiveLock() {} + +RecursiveLock::~RecursiveLock() { + if (lock_taken_ > 0) { + LOG4CXX_ERROR(logger_, + "Destroying non-released recursive mutex " << &mutex_); + } +} + +void RecursiveLock::Acquire() { + try { + mutex_.lock(); + } catch (std::exception err) { + LOG4CXX_FATAL(logger_, + "Failed to acquire mutex " << &mutex_ << ": " << err.what()); + NOTREACHED(); + } + + AssertFreeAndMarkTaken(); +} // namespace sync_primitives_boost + +void RecursiveLock::Release() { + AssertTakenAndMarkFree(); + mutex_.unlock(); +} + +bool RecursiveLock::Try() { + bool status = mutex_.try_lock(); + if (status) { + lock_taken_++; + } + return status; +} + +void RecursiveLock::AssertFreeAndMarkTaken() { + lock_taken_++; +} + +void RecursiveLock::AssertTakenAndMarkFree() { + if (lock_taken_ == 0) { + LOG4CXX_ERROR(logger_, "Unlocking a recursive mutex that is not taken"); + NOTREACHED(); + } + lock_taken_--; +} + +} // namespace sync_primitives diff --git a/src/components/utils/src/lock_posix.cc b/src/components/utils/src/lock_posix.cc index 9b90ad20b9..0f795bb669 100644 --- a/src/components/utils/src/lock_posix.cc +++ b/src/components/utils/src/lock_posix.cc @@ -30,7 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "utils/lock.h" +#include "utils/lock_posix.h" #include <errno.h> #include <stdint.h> #include <stdio.h> @@ -38,7 +38,7 @@ #include <cstring> #include "utils/logger.h" -namespace sync_primitives { +namespace sync_primitives_posix { CREATE_LOGGERPTR_GLOBAL(logger_, "Utils") diff --git a/src/components/utils/test/lock_boost_test.cc b/src/components/utils/test/lock_boost_test.cc new file mode 100644 index 0000000000..0da735a990 --- /dev/null +++ b/src/components/utils/test/lock_boost_test.cc @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, 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. + */ + +#include "gtest/gtest.h" +#include "utils/lock.h" + +namespace test { +namespace components { +namespace utils_test { + +using sync_primitives::Lock; +using sync_primitives::RecursiveLock; + +TEST(LockBoostTest, TestNonRecursive) { + // Create Lock object + Lock test_mutex; + // Lock mutex + test_mutex.Acquire(); + // Check if created mutex is non-recursive + EXPECT_FALSE(test_mutex.Try()); + // Release mutex before destroy + test_mutex.Release(); +} + +TEST(LockBoostTest, TestRecursive) { + // Create Lock object + RecursiveLock test_mutex; + // Lock mutex + test_mutex.Acquire(); + // Check if created mutex is recursive + EXPECT_TRUE(test_mutex.Try()); + // Release mutex before destroy + test_mutex.Release(); + test_mutex.Release(); +} + +TEST(LockBoostTest, ReleaseMutex_ExpectMutexReleased) { + // Create Lock object (non-recursive mutex) + Lock test_mutex; + // Lock mutex + test_mutex.Acquire(); + // Release mutex + test_mutex.Release(); + // Try to lock it again. If released expect true + EXPECT_TRUE(test_mutex.Try()); + test_mutex.Release(); +} + +TEST(LockBoostTest, TryLockNonRecursiveMutex_ExpectMutexNotLockedTwice) { + // Create Lock object (non-recursive mutex) + Lock test_mutex; + // Lock mutex + test_mutex.Try(); + // Try to lock it again. If locked expect false + EXPECT_FALSE(test_mutex.Try()); + test_mutex.Release(); +} + +TEST(LockBoostTest, TryLockRecursiveMutex_ExpectMutexLockedTwice) { + // Create Lock object (recursive mutex) + RecursiveLock test_mutex; + // Lock mutex + test_mutex.Try(); + // Try to lock it again. Expect true and internal counter increase + EXPECT_TRUE(test_mutex.Try()); + // Release mutex twice as was locked twice. + // Every Release() will decrement internal counter + test_mutex.Release(); + test_mutex.Release(); +} + +} // namespace utils_test +} // namespace components +} // namespace test diff --git a/src/components/utils/test/lock_posix_test.cc b/src/components/utils/test/lock_posix_test.cc index a78659ab31..04f2f5fa34 100644 --- a/src/components/utils/test/lock_posix_test.cc +++ b/src/components/utils/test/lock_posix_test.cc @@ -31,13 +31,13 @@ */ #include "gtest/gtest.h" -#include "utils/lock.h" +#include "utils/lock_posix.h" namespace test { namespace components { namespace utils_test { -using sync_primitives::Lock; +using sync_primitives_posix::Lock; TEST(LockPosixTest, DefaultCtorTest_ExpectNonRecursiveMutexCreated) { // Create Lock object |