diff options
author | Conlain Kelly <conlain.k@gmail.com> | 2018-07-24 17:18:21 -0400 |
---|---|---|
committer | Conlain Kelly <conlain.k@gmail.com> | 2018-07-24 17:18:21 -0400 |
commit | 8ff26a734267451030ee8ee62b5f672324a755c9 (patch) | |
tree | 6b59826fe5cf726ce458eda18e9e20dcb6ce0c58 /src | |
parent | 0ed004d9a7f961ccb964851dff1266949ebea1ee (diff) | |
parent | 5bf976c98f56a1d6867114ffe622eff2cc8785fd (diff) | |
download | sdl_core-8ff26a734267451030ee8ee62b5f672324a755c9.tar.gz |
Merge branch 'develop' of https://github.com/smartdevicelink/sdl_core into feature/choice_vr_optional
Diffstat (limited to 'src')
43 files changed, 373 insertions, 394 deletions
diff --git a/src/3rd_party/CMakeLists.txt b/src/3rd_party/CMakeLists.txt index ae9267e5bb..6c70e8988b 100644 --- a/src/3rd_party/CMakeLists.txt +++ b/src/3rd_party/CMakeLists.txt @@ -209,34 +209,34 @@ else() ) endif() -if (HMIADAPTER STREQUAL "messagebroker") - find_package(Boost 1.66.0 COMPONENTS system) - set(BOOST_LIB_SOURCE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/boost_src) - set(BOOST_LIBS_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX}/lib) - SET_PROPERTY(GLOBAL PROPERTY GLOBAL_BOOST_LIBS ${BOOST_LIBS_DIRECTORY}) - set(BOOST_INCLUDE_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX}/include ) - if (NOT ${Boost_FOUND}) - message(STATUS "Did not find boost. Downloading and installing boost 1.66") - set(BOOST_INSTALL_COMMAND ./b2 install) - if (${3RD_PARTY_INSTALL_PREFIX} MATCHES "/usr/local") - set(BOOST_INSTALL_COMMAND sudo ./b2 install) - endif() - include(ExternalProject) - ExternalProject_Add( - Boost - URL https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz - DOWNLOAD_DIR ${BOOST_LIB_SOURCE_DIRECTORY} - SOURCE_DIR ${BOOST_LIB_SOURCE_DIRECTORY} - CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=system --prefix=${3RD_PARTY_INSTALL_PREFIX} - BUILD_COMMAND ./b2 - INSTALL_COMMAND ${BOOST_INSTALL_COMMAND} --with-system --prefix=${3RD_PARTY_INSTALL_PREFIX} > boost_install.log - INSTALL_DIR ${3RD_PARTY_INSTALL_PREFIX} - BUILD_IN_SOURCE true - ) - - set(BOOST_INCLUDE_DIR ${BOOST_ROOT_DIR}/Boost-prefix/src/Boost) - set(BOOST_LIB_DIR ${BOOST_ROOT_DIR}/Boost-prefix/src/Boost/stage/lib/) +find_package(Boost 1.66.0 COMPONENTS system thread) +set(BOOST_LIB_SOURCE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/boost_src) +set(BOOST_LIBS_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX}/lib) +SET_PROPERTY(GLOBAL PROPERTY GLOBAL_BOOST_LIBS ${BOOST_LIBS_DIRECTORY}) +set(BOOST_INCLUDE_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX}/include ) +if (NOT ${Boost_FOUND}) + message(STATUS "Did not find boost. Downloading and installing boost 1.66") + set(BOOST_INSTALL_COMMAND ./b2 install) + if (${3RD_PARTY_INSTALL_PREFIX} MATCHES "/usr/local") + set(BOOST_INSTALL_COMMAND sudo ./b2 install) endif() + include(ExternalProject) + ExternalProject_Add( + Boost + URL https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz + DOWNLOAD_DIR ${BOOST_LIB_SOURCE_DIRECTORY} + SOURCE_DIR ${BOOST_LIB_SOURCE_DIRECTORY} + CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=system,thread --prefix=${3RD_PARTY_INSTALL_PREFIX} + BUILD_COMMAND ./b2 + INSTALL_COMMAND ${BOOST_INSTALL_COMMAND} --with-system --with-thread --prefix=${3RD_PARTY_INSTALL_PREFIX} > boost_install.log + INSTALL_DIR ${3RD_PARTY_INSTALL_PREFIX} + BUILD_IN_SOURCE true + ) + + set(BOOST_INCLUDE_DIR ${BOOST_ROOT_DIR}/Boost-prefix/src/Boost) + set(BOOST_LIB_DIR ${BOOST_ROOT_DIR}/Boost-prefix/src/Boost/stage/lib/) +else() +add_custom_target(Boost) # empty target, Boost is already installed endif() add_custom_target(install-3rd_party diff --git a/src/appMain/audio.8bit.wav b/src/appMain/audio.8bit.wav Binary files differindex cebf6cc0e2..7a3f970a21 100644 --- a/src/appMain/audio.8bit.wav +++ b/src/appMain/audio.8bit.wav 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 e9166439f8..a292b84fc0 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 @@ -142,7 +142,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 8da8dec8f1..3f60040db9 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 std::shared_ptr<sync_primitives::Lock> commands_lock_ptr_; + mutable std::shared_ptr<sync_primitives::RecursiveLock> commands_lock_ptr_; SubMenuMap sub_menu_; mutable std::shared_ptr<sync_primitives::Lock> sub_menu_lock_ptr_; ChoiceSetMap choice_set_map_; mutable std::shared_ptr<sync_primitives::Lock> choice_set_map_lock_ptr_; PerformChoiceSetMap performinteraction_choice_set_map_; - mutable std::shared_ptr<sync_primitives::Lock> + mutable std::shared_ptr<sync_primitives::RecursiveLock> performinteraction_choice_set_lock_ptr_; uint32_t is_perform_interaction_active_; bool is_reset_global_properties_active_; 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 2b83c2fccd..87a6c521e8 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 @@ -1450,7 +1450,8 @@ class ApplicationManagerImpl ForbiddenApps forbidden_applications; // Lock for applications list - mutable std::shared_ptr<sync_primitives::Lock> applications_list_lock_ptr_; + mutable std::shared_ptr<sync_primitives::RecursiveLock> + applications_list_lock_ptr_; mutable std::shared_ptr<sync_primitives::Lock> apps_to_register_list_lock_ptr_; mutable sync_primitives::Lock subscribed_way_points_apps_lock_; @@ -1536,7 +1537,7 @@ class ApplicationManagerImpl std::vector<TimerSPtr> timer_pool_; sync_primitives::Lock timer_pool_lock_; - mutable sync_primitives::Lock stopping_application_mng_lock_; + mutable sync_primitives::RecursiveLock stopping_application_mng_lock_; StateControllerImpl state_ctrl_; std::unique_ptr<app_launch::AppLaunchData> app_launch_dto_; std::unique_ptr<app_launch::AppLaunchCtrl> app_launch_ctrl_; 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 14e2841eb5..c8f3bcf888 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 @@ -756,7 +756,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_; std::shared_ptr<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/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/create_interaction_choice_set_request.h b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/create_interaction_choice_set_request.h index 285b0b10db..950c295072 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/create_interaction_choice_set_request.h +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/include/sdl_rpc_plugin/commands/mobile/create_interaction_choice_set_request.h @@ -142,7 +142,7 @@ class CreateInteractionChoiceSetRequest 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/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc index 91ef7c3bbd..87f270d48a 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/create_interaction_choice_set_request.cc @@ -62,8 +62,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/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/dial_number_request_test.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/dial_number_request_test.cc index 8e95f43752..5d6c6dc89e 100644 --- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/dial_number_request_test.cc +++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/test/commands/mobile/dial_number_request_test.cc @@ -139,48 +139,45 @@ TEST_F(DialNumberRequestTest, Run_SUCCESS) { } TEST_F(DialNumberRequestTest, OnEvent_UnknownEvent_UNSUCCESS) { - MessageSharedPtr command_msg(CreateMessage(smart_objects::SmartType_Map)); - (*command_msg)[am::strings::params][am::strings::connection_key] = - kConnectionKey; + MessageSharedPtr command_msg(CreateMessage(smart_objects::SmartType_Map)); + (*command_msg)[am::strings::params][am::strings::connection_key] = + kConnectionKey; - DialNumberRequestPtr - command(CreateCommand<DialNumberRequest>(command_msg)); + DialNumberRequestPtr command(CreateCommand<DialNumberRequest>(command_msg)); - MockAppPtr app(CreateMockApp()); - EXPECT_CALL(app_mngr_, application(kConnectionKey)).WillOnce(Return(app)); + MockAppPtr app(CreateMockApp()); + EXPECT_CALL(app_mngr_, application(kConnectionKey)).WillOnce(Return(app)); - Event event(hmi_apis::FunctionID::INVALID_ENUM); - EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); + Event event(hmi_apis::FunctionID::INVALID_ENUM); + EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _)).Times(0); command->on_event(event); } TEST_F(DialNumberRequestTest, OnEvent_SUCCESS) { - MessageSharedPtr event_msg(CreateMessage(smart_objects::SmartType_Map)); - (*event_msg)[am::strings::params][am::hmi_response::code] = - mobile_apis::Result::SUCCESS; - (*event_msg)[am::strings::params][am::strings::info] = "test_info"; - - Event event(hmi_apis::FunctionID::BasicCommunication_DialNumber); - event.set_smart_object(*event_msg); - - MockAppPtr app(CreateMockApp()); - EXPECT_CALL(app_mngr_, application(kConnectionKey)) - .WillRepeatedly(Return(app)); - ON_CALL(app_mngr_, - GetRPCService()).WillByDefault(ReturnRef(mock_rpc_service_)); - EXPECT_CALL( - mock_rpc_service_, - ManageMobileCommand(MobileResultCodeIs(mobile_apis::Result::SUCCESS), - _)); - - MessageSharedPtr command_msg(CreateMessage(smart_objects::SmartType_Map)); - (*command_msg)[am::strings::params][am::strings::connection_key] = - kConnectionKey; - - DialNumberRequestPtr - command(CreateCommand<DialNumberRequest>(command_msg)); - command->on_event(event); + MessageSharedPtr event_msg(CreateMessage(smart_objects::SmartType_Map)); + (*event_msg)[am::strings::params][am::hmi_response::code] = + mobile_apis::Result::SUCCESS; + (*event_msg)[am::strings::params][am::strings::info] = "test_info"; + + Event event(hmi_apis::FunctionID::BasicCommunication_DialNumber); + event.set_smart_object(*event_msg); + + MockAppPtr app(CreateMockApp()); + EXPECT_CALL(app_mngr_, application(kConnectionKey)) + .WillRepeatedly(Return(app)); + ON_CALL(app_mngr_, GetRPCService()) + .WillByDefault(ReturnRef(mock_rpc_service_)); + EXPECT_CALL( + mock_rpc_service_, + ManageMobileCommand(MobileResultCodeIs(mobile_apis::Result::SUCCESS), _)); + + MessageSharedPtr command_msg(CreateMessage(smart_objects::SmartType_Map)); + (*command_msg)[am::strings::params][am::strings::connection_key] = + kConnectionKey; + + DialNumberRequestPtr command(CreateCommand<DialNumberRequest>(command_msg)); + command->on_event(event); } } // namespace dial_number_request 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 f59053d97b..9179f2c08b 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 @@ -43,9 +43,7 @@ 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) {} + : AppLaunchDataImpl(settings), 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 f271b7ff6a..3cfbeb2602 100644 --- a/src/components/application_manager/src/application_data_impl.cc +++ b/src/components/application_manager/src/application_data_impl.cc @@ -178,13 +178,14 @@ DynamicApplicationDataImpl::DynamicApplicationDataImpl() , night_color_scheme_(NULL) , display_layout_("") , commands_() - , commands_lock_ptr_(new sync_primitives::Lock(true)) + , commands_lock_ptr_(std::make_shared<sync_primitives::RecursiveLock>()) , sub_menu_() , sub_menu_lock_ptr_(std::make_shared<sync_primitives::Lock>()) , choice_set_map_() , choice_set_map_lock_ptr_(std::make_shared<sync_primitives::Lock>()) , performinteraction_choice_set_map_() - , performinteraction_choice_set_lock_ptr_(new sync_primitives::Lock(true)) + , performinteraction_choice_set_lock_ptr_( + std::make_shared<sync_primitives::RecursiveLock>()) , 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 8efd92a0d1..9b936bdf41 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -143,7 +143,8 @@ ApplicationManagerImpl::ApplicationManagerImpl( const ApplicationManagerSettings& am_settings, const policy::PolicySettings& policy_settings) : settings_(am_settings) - , applications_list_lock_ptr_(std::make_shared<sync_primitives::Lock>(true)) + , applications_list_lock_ptr_( + std::make_shared<sync_primitives::RecursiveLock>()) , apps_to_register_list_lock_ptr_(std::make_shared<sync_primitives::Lock>()) , audio_pass_thru_active_(false) , audio_pass_thru_app_id_(0) @@ -165,7 +166,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) , application_list_update_timer_( "AM ListUpdater", 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..f1e5bf9735 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 @@ -39,8 +39,7 @@ namespace application_manager { namespace event_engine { using namespace sync_primitives; -EventDispatcherImpl::EventDispatcherImpl() - : state_lock_(false), observer_lock_(true), observers_event_() {} +EventDispatcherImpl::EventDispatcherImpl() : 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 ce0bac9c0e..05e9d6cb2c 100644 --- a/src/components/application_manager/src/policies/policy_handler.cc +++ b/src/components/application_manager/src/policies/policy_handler.cc @@ -327,7 +327,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_(std::make_shared<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 74054eab29..42dc335878 100644 --- a/src/components/application_manager/src/resumption/resume_ctrl_impl.cc +++ b/src/components/application_manager/src/resumption/resume_ctrl_impl.cc @@ -64,7 +64,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 72215dcf97..856fb03750 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 63d1f4471a..1e8a5f5a40 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 @@ -254,7 +254,7 @@ TEST(MessageHelperTestCreate, MockApplicationSharedPtr appSharedMock = std::make_shared<MockApplication>(); ::application_manager::CommandsMap vis; DataAccessor<application_manager::CommandsMap> data_accessor( - vis, std::make_shared<sync_primitives::Lock>(true)); + vis, std::make_shared<sync_primitives::RecursiveLock>()); EXPECT_CALL(*appSharedMock, commands_map()).WillOnce(Return(data_accessor)); application_manager_test::MockApplicationManager mock_application_manager; @@ -270,7 +270,7 @@ TEST(MessageHelperTestCreate, MockApplicationSharedPtr appSharedMock = std::make_shared<MockApplication>(); CommandsMap vis; DataAccessor<CommandsMap> data_accessor( - vis, std::make_shared<sync_primitives::Lock>(true)); + vis, std::make_shared<sync_primitives::RecursiveLock>()); smart_objects::SmartObjectSPtr smartObjectPtr = std::make_shared<smart_objects::SmartObject>(); @@ -312,7 +312,7 @@ TEST(MessageHelperTestCreate, MockApplicationSharedPtr appSharedMock = std::make_shared<MockApplication>(); application_manager::ChoiceSetMap vis; DataAccessor< ::application_manager::ChoiceSetMap> data_accessor( - vis, std::make_shared<sync_primitives::Lock>(true)); + vis, std::make_shared<sync_primitives::RecursiveLock>()); EXPECT_CALL(*appSharedMock, choice_set_map()).WillOnce(Return(data_accessor)); application_manager_test::MockApplicationManager mock_application_manager; @@ -328,7 +328,7 @@ TEST(MessageHelperTestCreate, MockApplicationSharedPtr appSharedMock = std::make_shared<MockApplication>(); application_manager::ChoiceSetMap vis; DataAccessor< ::application_manager::ChoiceSetMap> data_accessor( - vis, std::make_shared<sync_primitives::Lock>(true)); + vis, std::make_shared<sync_primitives::RecursiveLock>()); smart_objects::SmartObjectSPtr smartObjectPtr = std::make_shared<smart_objects::SmartObject>(); @@ -375,7 +375,7 @@ TEST(MessageHelperTestCreate, CreateAddSubMenuRequestToHMI_SendObject_Equal) { MockApplicationSharedPtr appSharedMock = std::make_shared<MockApplication>(); application_manager::SubMenuMap vis; DataAccessor< ::application_manager::SubMenuMap> data_accessor( - vis, std::make_shared<sync_primitives::Lock>(true)); + vis, std::make_shared<sync_primitives::RecursiveLock>()); smart_objects::SmartObjectSPtr smartObjectPtr = std::make_shared<smart_objects::SmartObject>(); @@ -415,7 +415,7 @@ TEST(MessageHelperTestCreate, MockApplicationSharedPtr appSharedMock = std::make_shared<MockApplication>(); application_manager::SubMenuMap vis; DataAccessor< ::application_manager::SubMenuMap> data_accessor( - vis, std::make_shared<sync_primitives::Lock>(true)); + vis, std::make_shared<sync_primitives::RecursiveLock>()); EXPECT_CALL(*appSharedMock, sub_menu_map()).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 a2309c1521..4f900bb65e 100644 --- a/src/components/connection_handler/include/connection_handler/connection.h +++ b/src/components/connection_handler/include/connection_handler/connection.h @@ -340,7 +340,7 @@ class Connection { */ SessionMap session_map_; - mutable sync_primitives::Lock session_map_lock_; + mutable sync_primitives::RecursiveLock session_map_lock_; /** * @brief primary connection handle for secondary connections diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h index 121d5ed08c..730d7ebe32 100644 --- a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h +++ b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h @@ -640,7 +640,7 @@ class ConnectionHandlerImpl * @brief session/connection map */ SessionConnectionMap session_connection_map_; - mutable std::shared_ptr<sync_primitives::Lock> + mutable std::shared_ptr<sync_primitives::RecursiveLock> session_connection_map_lock_ptr_; /** 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 b8399b2c9b..5a35919c6c 100644 --- a/src/components/connection_handler/src/connection.cc +++ b/src/components/connection_handler/src/connection.cc @@ -81,7 +81,6 @@ Connection::Connection(ConnectionHandle connection_handle, : connection_handler_(connection_handler) , connection_handle_(connection_handle) , connection_device_handle_(connection_device_handle) - , session_map_lock_(true) , primary_connection_handle_(0) , heartbeat_timeout_(heartbeat_timeout) { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index 270b38d724..9aa84989d9 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -69,7 +69,7 @@ ConnectionHandlerImpl::ConnectionHandlerImpl( , transport_manager_(tm) , protocol_handler_(NULL) , session_connection_map_lock_ptr_( - std::make_shared<sync_primitives::Lock>(true)) + std::make_shared<sync_primitives::RecursiveLock>()) , connection_list_lock_() , connection_handler_observer_lock_() , connection_list_deleter_(&connection_list_) 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 b828f513eb..1be7c3ab53 100644 --- a/src/components/include/utils/data_accessor.h +++ b/src/components/include/utils/data_accessor.h @@ -32,7 +32,6 @@ #ifndef SRC_COMPONENTS_INCLUDE_UTILS_DATA_ACCESSOR_H_ #define SRC_COMPONENTS_INCLUDE_UTILS_DATA_ACCESSOR_H_ -#include <iostream> #include "utils/lock.h" // This class is for thread-safe const access to data @@ -40,7 +39,7 @@ template <class T> class DataAccessor { public: DataAccessor(const T& data, - const std::shared_ptr<sync_primitives::Lock>& lock) + const std::shared_ptr<sync_primitives::BaseLock>& lock) : data_(data), lock_(lock), counter_(new uint32_t(0)) { lock_->Acquire(); } @@ -65,7 +64,7 @@ class DataAccessor { void* operator new(size_t size); const T& data_; // Require that the lock lives at least as long as the DataAccessor - const std::shared_ptr<sync_primitives::Lock> lock_; + const std::shared_ptr<sync_primitives::BaseLock> lock_; std::shared_ptr<uint32_t> counter_; }; diff --git a/src/components/include/utils/lock.h b/src/components/include/utils/lock.h Binary files differindex 081e651b13..bfa1ef1770 100644 --- a/src/components/include/utils/lock.h +++ b/src/components/include/utils/lock.h diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml index 18966ff00a..bdbb60f98a 100644 --- a/src/components/interfaces/HMI_API.xml +++ b/src/components/interfaces/HMI_API.xml @@ -1137,21 +1137,35 @@ <enum name="SamplingRate"> <description>Describes different sampling options for PerformAudioPassThru.</description> - <element name="8KHZ" internal_name="RATE_8KHZ"/> - <element name="16KHZ" internal_name="RATE_16KHZ"/> - <element name="22KHZ" internal_name="RATE_22KHZ"/> - <element name="44KHZ" internal_name="RATE_44KHZ"/> + <element name="8KHZ" internal_name="RATE_8KHZ"> + <description>Sampling rate of 8000 Hz.</description> + </element> + <element name="16KHZ" internal_name="RATE_16KHZ"> + <description>Sampling rate of 16000 Hz.</description> + </element> + <element name="22KHZ" internal_name="RATE_22KHZ"> + <description>Sampling rate of 22050 Hz.</description> + </element> + <element name="44KHZ" internal_name="RATE_44KHZ"> + <description>Sampling rate of 44100 Hz.</description> + </element> </enum> <enum name="BitsPerSample"> <description>Describes different quality options for PerformAudioPassThru.</description> - <element name="8_BIT" internal_name="RATE_8_BIT"/> - <element name="16_BIT" internal_name="RATE_16_BIT"/> + <element name="8_BIT" internal_name="RATE_8_BIT"> + <description>Audio sample is 8 bits wide, unsigned.</description> + </element> + <element name="16_BIT" internal_name="RATE_16_BIT"> + <description>Audio sample is 16 bits wide, signed, and in little endian.</description> + </element> </enum> <enum name="AudioType"> <description>Describes different audio type options for PerformAudioPassThru.</description> - <element name="PCM" /> + <element name="PCM"> + <description>Linear PCM.</description> + </element> </enum> <enum name="KeyboardLayout"> @@ -2396,6 +2410,7 @@ <description> Describes different audio type configurations for PerformAudioPassThru. e.g. 8kHz,8-bit,PCM + The audio is recorded in monaural. </description> <param name="samplingRate" type="Common.SamplingRate" mandatory="true"/> <param name="bitsPerSample" type="Common.BitsPerSample" mandatory="true"/> diff --git a/src/components/interfaces/MOBILE_API.xml b/src/components/interfaces/MOBILE_API.xml index 09ed9f674d..95ced4e975 100644 --- a/src/components/interfaces/MOBILE_API.xml +++ b/src/components/interfaces/MOBILE_API.xml @@ -480,27 +480,42 @@ <enum name="SamplingRate"> <description>Describes different sampling options for PerformAudioPassThru.</description> - <element name="8KHZ" internal_name="SamplingRate_8KHZ"/> - <element name="16KHZ" internal_name="SamplingRate_16KHZ"/> - <element name="22KHZ" internal_name="SamplingRate_22KHZ"/> - <element name="44KHZ" internal_name="SamplingRate_44KHZ"/> + <element name="8KHZ" internal_name="SamplingRate_8KHZ"> + <description>Sampling rate of 8000 Hz.</description> + </element> + <element name="16KHZ" internal_name="SamplingRate_16KHZ"> + <description>Sampling rate of 16000 Hz.</description> + </element> + <element name="22KHZ" internal_name="SamplingRate_22KHZ"> + <description>Sampling rate of 22050 Hz.</description> + </element> + <element name="44KHZ" internal_name="SamplingRate_44KHZ"> + <description>Sampling rate of 44100 Hz.</description> + </element> </enum> <enum name="BitsPerSample"> <description>Describes different quality options for PerformAudioPassThru.</description> - <element name="8_BIT" internal_name="BitsPerSample_8_BIT"/> - <element name="16_BIT" internal_name="BitsPerSample_16_BIT"/> + <element name="8_BIT" internal_name="BitsPerSample_8_BIT"> + <description>Audio sample is 8 bits wide, unsigned.</description> + </element> + <element name="16_BIT" internal_name="BitsPerSample_16_BIT"> + <description>Audio sample is 16 bits wide, signed, and in little endian.</description> + </element> </enum> <enum name="AudioType"> <description>Describes different audio type options for PerformAudioPassThru.</description> - <element name="PCM" /> + <element name="PCM"> + <description>Linear PCM.</description> + </element> </enum> <struct name="AudioPassThruCapabilities"> <description> Describes different audio type configurations for PerformAudioPassThru. e.g. {8kHz,8-bit,PCM} + The audio is recorded in monaural. </description> <param name="samplingRate" type="SamplingRate" mandatory="true"/> <param name="bitsPerSample" type="BitsPerSample" mandatory="true"/> diff --git a/src/components/media_manager/src/audio/a2dp_source_player_adapter.cc b/src/components/media_manager/src/audio/a2dp_source_player_adapter.cc index 5e9d6ab0ba..91e3c5465d 100644 --- a/src/components/media_manager/src/audio/a2dp_source_player_adapter.cc +++ b/src/components/media_manager/src/audio/a2dp_source_player_adapter.cc @@ -91,19 +91,19 @@ void A2DPSourcePlayerAdapter::StartActivity(int32_t application_key) { if (application_key != current_application_) { current_application_ = application_key; - uint32_t device_id = 0; + transport_manager::DeviceHandle device_id = 0; session_observer_.GetDataOnSessionKey(application_key, 0, NULL, &device_id); - std::string mac_adddress; - session_observer_.GetDataOnDeviceID(device_id, NULL, NULL, &mac_adddress); + std::string mac_address; + session_observer_.GetDataOnDeviceID(device_id, NULL, NULL, &mac_address); - // TODO(PK): Convert mac_adddress to the + // TODO(PK): Convert mac_address to the // following format : "bluez_source.XX_XX_XX_XX_XX_XX" if needed // before passing to the A2DPSourcePlayerThread constructor A2DPSourcePlayerThread* delegate = - new A2DPSourcePlayerAdapter::A2DPSourcePlayerThread(mac_adddress); + new A2DPSourcePlayerAdapter::A2DPSourcePlayerThread(mac_address); threads::Thread* new_activity = - threads::CreateThread(mac_adddress.c_str(), delegate); + threads::CreateThread(mac_address.c_str(), delegate); sources_[application_key] = Pair(new_activity, delegate); new_activity->start(); } diff --git a/src/components/media_manager/src/audio/audio_stream_sender_thread.cc b/src/components/media_manager/src/audio/audio_stream_sender_thread.cc index e1b932b611..23181e7431 100644 --- a/src/components/media_manager/src/audio/audio_stream_sender_thread.cc +++ b/src/components/media_manager/src/audio/audio_stream_sender_thread.cc @@ -61,6 +61,15 @@ const int32_t AudioStreamSenderThread::kAudioPassThruTimeout = 1000; #endif const uint32_t kMqueueMessageSize = 4095; +// Size of RIFF header contained in a .wav file: 12 bytes for 'RIFF' chunk +// descriptor, 24 bytes for 'fmt ' sub-chunk and 8 bytes for 'data' sub-chunk +// header. +// The correct format of audio stream for AudioPassThru feature is to include +// only audio sample data. Since both pre-recorded file (audio.8bit.wav) and +// GStreamer-generated file contain RIFF header, we will skip it when reading +// the files. +static const uint32_t kRIFFHeaderSize = 44; + CREATE_LOGGERPTR_GLOBAL(logger_, "MediaManager") AudioStreamSenderThread::AudioStreamSenderThread( @@ -69,7 +78,7 @@ AudioStreamSenderThread::AudioStreamSenderThread( application_manager::ApplicationManager& app_mngr) : session_key_(session_key) , fileName_(fileName) - , offset_(0) + , offset_(kRIFFHeaderSize) , shouldBeStoped_(false) , shouldBeStoped_lock_() , shouldBeStoped_cv_() @@ -82,7 +91,7 @@ AudioStreamSenderThread::~AudioStreamSenderThread() {} void AudioStreamSenderThread::threadMain() { LOG4CXX_AUTO_TRACE(logger_); - offset_ = 0; + offset_ = kRIFFHeaderSize; while (false == getShouldBeStopped()) { AutoLock auto_lock(shouldBeStoped_lock_); @@ -125,7 +134,7 @@ void AudioStreamSenderThread::sendAudioChunkToMobile() { } #if !defined(EXTENDED_MEDIA_MODE) // without recording stream restart reading 1-sec file - offset_ = 0; + offset_ = kRIFFHeaderSize; #endif } diff --git a/src/components/media_manager/src/audio/from_mic_to_file_recorder_thread.cc b/src/components/media_manager/src/audio/from_mic_to_file_recorder_thread.cc index 99548e71bd..5c12614662 100644 --- a/src/components/media_manager/src/audio/from_mic_to_file_recorder_thread.cc +++ b/src/components/media_manager/src/audio/from_mic_to_file_recorder_thread.cc @@ -42,6 +42,9 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "MediaManager") GMainLoop* FromMicToFileRecorderThread::loop = NULL; +// As per spec, AudioPassThru recording is in monaural +static const int kNumAudioChannels = 1; + FromMicToFileRecorderThread::FromMicToFileRecorderThread( const std::string& output_file, int32_t duration) : threads::ThreadDelegate() @@ -119,7 +122,8 @@ void FromMicToFileRecorderThread::threadMain() { initArgs(); GstElement* pipeline; - GstElement* alsasrc, *wavenc, *filesink; + GstElement* alsasrc, *audioconvert, *capsfilter, *wavenc, *filesink; + GstCaps* audiocaps; GstBus* bus; const gchar* device = "hw:0,0"; @@ -196,11 +200,18 @@ void FromMicToFileRecorderThread::threadMain() { // Create all of the elements to be added to the pipeline alsasrc = gst_element_factory_make("alsasrc", "alsasrc0"); + audioconvert = gst_element_factory_make("audioconvert", "audioconvert0"); + capsfilter = gst_element_factory_make("capsfilter", "filter0"); wavenc = gst_element_factory_make("wavenc", "wavenc0"); filesink = gst_element_factory_make("filesink", "filesink0"); + // create a capability to downmix the recorded audio to monaural + audiocaps = gst_caps_new_simple( + "audio/x-raw", "channels", G_TYPE_INT, kNumAudioChannels, NULL); + // Assert that all the elements were created - if (!alsasrc || !wavenc || !filesink) { + if (!alsasrc || !audioconvert || !capsfilter || !wavenc || !filesink || + !audiocaps) { g_error("Failed creating one or more of the pipeline elements.\n"); } @@ -209,10 +220,21 @@ void FromMicToFileRecorderThread::threadMain() { g_object_set(G_OBJECT(filesink), "location", outfile, NULL); // Add the elements to the pipeline - gst_bin_add_many(GST_BIN(pipeline), alsasrc, wavenc, filesink, NULL); + gst_bin_add_many(GST_BIN(pipeline), + alsasrc, + audioconvert, + capsfilter, + wavenc, + filesink, + NULL); // Link the elements - gst_element_link_many(alsasrc, wavenc, filesink, NULL); + gst_element_link_many( + alsasrc, audioconvert, capsfilter, wavenc, filesink, NULL); + + // set the capability + g_object_set(G_OBJECT(capsfilter), "caps", audiocaps, NULL); + gst_caps_unref(audiocaps); gst_element_set_state(pipeline, GST_STATE_PLAYING); diff --git a/src/components/media_manager/src/media_manager_impl.cc b/src/components/media_manager/src/media_manager_impl.cc index 15b58aee1f..ec88e910d3 100644 --- a/src/components/media_manager/src/media_manager_impl.cc +++ b/src/components/media_manager/src/media_manager_impl.cc @@ -116,7 +116,7 @@ void MediaManagerImpl::Init() { #if defined(EXTENDED_MEDIA_MODE) LOG4CXX_INFO(logger_, "Called Init with default configuration."); - from_mic_recorder_ = std::make_shared<FromMicRecorderAdapter>(); + from_mic_recorder_ = new FromMicRecorderAdapter(); #endif if ("socket" == settings().video_server_type()) { 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 e84c0fb782..a28f1b3461 100644 --- a/src/components/policy/policy_regular/include/policy/cache_manager.h +++ b/src/components/policy/policy_regular/include/policy/cache_manager.h @@ -781,7 +781,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 4530e6692b..2ae0f79f75 100644 --- a/src/components/policy/policy_regular/src/cache_manager.cc +++ b/src/components/policy/policy_regular/src/cache_manager.cc @@ -103,8 +103,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_); diff --git a/src/components/utils/CMakeLists.txt b/src/components/utils/CMakeLists.txt index b256a2fadc..0eb64ae8c2 100644 --- a/src/components/utils/CMakeLists.txt +++ b/src/components/utils/CMakeLists.txt @@ -102,7 +102,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 @@ -110,11 +110,14 @@ 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_thread) target_link_libraries("Utils" ${LIBRARIES}) +add_dependencies("Utils" Boost) + if(ENABLE_LOG) add_dependencies("Utils" install-3rd_party_logger) diff --git a/src/components/utils/src/conditional_variable_boost.cc b/src/components/utils/src/conditional_variable_boost.cc new file mode 100644 index 0000000000..c07b8284ea --- /dev/null +++ b/src/components/utils/src/conditional_variable_boost.cc @@ -0,0 +1,124 @@ +/* + * 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 "utils/conditional_variable.h" + +#include <errno.h> +#include <time.h> + +#include "utils/lock.h" +#include "utils/logger.h" + +namespace { +const long kNanosecondsPerSecond = 1000000000; +const long kMillisecondsPerSecond = 1000; +const long kNanosecondsPerMillisecond = 1000000; +} // namespace + +namespace sync_primitives { + +CREATE_LOGGERPTR_GLOBAL(logger_, "Utils") + +ConditionalVariable::ConditionalVariable() {} + +ConditionalVariable::~ConditionalVariable() {} + +void ConditionalVariable::NotifyOne() { + cond_var_.notify_one(); +} + +void ConditionalVariable::Broadcast() { + cond_var_.notify_all(); +} + +bool ConditionalVariable::Wait(BaseLock& lock) { + // NOTE this grossness is due to boost mutex and recursive mutex not sharing a + // superclass + + 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, give up the lock + LOG4CXX_ERROR(logger_, "Unknown lock type!"); + NOTREACHED(); + } + lock.AssertFreeAndMarkTaken(); + + return true; +} + +bool ConditionalVariable::Wait(AutoLock& auto_lock) { + BaseLock& lock = auto_lock.GetLock(); + return Wait(lock); +} + +ConditionalVariable::WaitStatus ConditionalVariable::WaitFor( + AutoLock& auto_lock, uint32_t milliseconds) { + BaseLock& lock = auto_lock.GetLock(); + + WaitStatus wait_status = kNoTimeout; + lock.AssertTakenAndMarkFree(); + 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 { + // this is an unknown lock, we have an issue + LOG4CXX_ERROR(logger_, "Unknown lock type!"); + NOTREACHED(); + } + + if (!timeout) { + wait_status = kTimeout; + } + lock.AssertFreeAndMarkTaken(); + + return wait_status; +} + +} // namespace sync_primitives diff --git a/src/components/utils/src/conditional_variable_posix.cc b/src/components/utils/src/conditional_variable_posix.cc deleted file mode 100644 index 50ebc74556..0000000000 --- a/src/components/utils/src/conditional_variable_posix.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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 "utils/conditional_variable.h" - -#include <errno.h> -#include <time.h> - -#include "utils/lock.h" -#include "utils/logger.h" - -namespace { -const long kNanosecondsPerSecond = 1000000000; -const long kMillisecondsPerSecond = 1000; -const long kNanosecondsPerMillisecond = 1000000; -} - -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() { - pthread_cond_destroy(&cond_var_); -} - -void ConditionalVariable::NotifyOne() { - int signaled = pthread_cond_signal(&cond_var_); - if (signaled != 0) - LOG4CXX_ERROR(logger_, "Failed to signal conditional variable"); -} - -void ConditionalVariable::Broadcast() { - int signaled = pthread_cond_broadcast(&cond_var_); - if (signaled != 0) - LOG4CXX_ERROR(logger_, "Failed to broadcast conditional variable"); -} - -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"); - 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; -} - -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(); - WaitStatus wait_status = kNoTimeout; - switch (timedwait_status) { - case 0: { - wait_status = kNoTimeout; - break; - } - case EINTR: { - wait_status = kNoTimeout; - break; - } - case ETIMEDOUT: { - wait_status = kTimeout; - break; - } - default: { - LOG4CXX_ERROR( - logger_, - "Failed to timewait for conditional variable timedwait_status: " - << timedwait_status); - } - } - return wait_status; -} - -} // namespace sync_primitives diff --git a/src/components/utils/src/lock_posix.cc b/src/components/utils/src/lock_boost.cc index e5e6d7fad0..2299bcf77d 100644 --- a/src/components/utils/src/lock_posix.cc +++ b/src/components/utils/src/lock_boost.cc @@ -30,94 +30,51 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "utils/lock.h" #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() -#ifndef NDEBUG - : lock_taken_(0) - , is_mutex_recursive_(false) -#endif // NDEBUG -{ - Init(false); -} - -Lock::Lock(bool is_recursive) -#ifndef NDEBUG - : lock_taken_(0) - , is_mutex_recursive_(is_recursive) -#endif // NDEBUG -{ - Init(is_recursive); -} +Lock::Lock() : lock_taken_(0) {} Lock::~Lock() { -#ifndef NDEBUG if (lock_taken_ > 0) { - LOG4CXX_FATAL(logger_, "Destroying non-released mutex " << &mutex_); - NOTREACHED(); - } -#endif - int32_t status = pthread_mutex_destroy(&mutex_); - if (status != 0) { - LOG4CXX_FATAL(logger_, - "Failed to destroy mutex " << &mutex_ << ": " - << strerror(status)); - NOTREACHED(); + LOG4CXX_FATAL(logger_, "Destroying non-released regular mutex " << &mutex_); } } void Lock::Acquire() { - const int32_t status = pthread_mutex_lock(&mutex_); - if (status != 0) { - LOG4CXX_FATAL(logger_, - "Failed to acquire mutex " << &mutex_ << ": " - << strerror(status)); - NOTREACHED(); - } else { - AssertFreeAndMarkTaken(); - } + mutex_.lock(); + AssertFreeAndMarkTaken(); } void Lock::Release() { AssertTakenAndMarkFree(); - const int32_t status = pthread_mutex_unlock(&mutex_); - if (status != 0) { - LOG4CXX_FATAL(logger_, - "Failed to unlock mutex" << &mutex_ << ": " - << strerror(status)); - NOTREACHED(); - } + mutex_.unlock(); } bool Lock::Try() { - const int32_t status = pthread_mutex_trylock(&mutex_); - if (status == 0) { -#ifndef NDEBUG - lock_taken_++; -#endif - return true; + bool status = mutex_.try_lock(); + if (status) { + AssertFreeAndMarkTaken(); } - return false; + return status; } -#ifndef NDEBUG void Lock::AssertFreeAndMarkTaken() { - if ((lock_taken_ > 0) && !is_mutex_recursive_) { + if (lock_taken_ != 0) { LOG4CXX_FATAL(logger_, "Locking already taken not recursive mutex"); NOTREACHED(); } lock_taken_++; } + void Lock::AssertTakenAndMarkFree() { if (lock_taken_ == 0) { LOG4CXX_FATAL(logger_, "Unlocking a mutex that is not taken"); @@ -125,25 +82,46 @@ void Lock::AssertTakenAndMarkFree() { } lock_taken_--; } -#endif -void Lock::Init(bool is_recursive) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); +// Recursive lock looks the same on the surface, some code duplication is +// necessary since they don't have a shared parent superclass +RecursiveLock::RecursiveLock() : lock_taken_(0) {} - const int32_t mutex_type = - is_recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_ERRORCHECK; +RecursiveLock::~RecursiveLock() { + if (lock_taken_ > 0) { + LOG4CXX_FATAL(logger_, + "Destroying non-released recursive mutex " << &mutex_); + } +} - pthread_mutexattr_settype(&attr, mutex_type); - const int32_t status = pthread_mutex_init(&mutex_, &attr); +void RecursiveLock::Acquire() { + mutex_.lock(); + AssertFreeAndMarkTaken(); +} - pthread_mutexattr_destroy(&attr); +void RecursiveLock::Release() { + AssertTakenAndMarkFree(); + mutex_.unlock(); +} - if (status != 0) { - LOG4CXX_FATAL(logger_, - "Failed to initialize mutex. " << std::strerror(status)); - DCHECK(status != 0); +bool RecursiveLock::Try() { + bool status = mutex_.try_lock(); + if (status) { + AssertFreeAndMarkTaken(); } + return status; +} + +void RecursiveLock::AssertFreeAndMarkTaken() { + lock_taken_++; +} + +void RecursiveLock::AssertTakenAndMarkFree() { + if (lock_taken_ == 0) { + LOG4CXX_FATAL(logger_, "Unlocking a recursive mutex that is not taken"); + NOTREACHED(); + } + lock_taken_--; } } // namespace sync_primitives diff --git a/src/components/utils/test/conditional_variable_test.cc b/src/components/utils/test/conditional_variable_test.cc index 48e2e53200..1ef29685e6 100644 --- a/src/components/utils/test/conditional_variable_test.cc +++ b/src/components/utils/test/conditional_variable_test.cc @@ -30,14 +30,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <iostream> #include <pthread.h> +#include <iostream> #include "gtest/gtest.h" +#include "utils/conditional_variable.h" #include "utils/lock.h" #include "utils/macro.h" -#include "utils/conditional_variable.h" namespace test { namespace components { @@ -102,6 +102,7 @@ TEST_F(ConditionalVariableTest, cond_var_.WaitFor(test_lock, 2000); std::string last_value("changed again by thread 1"); EXPECT_EQ(last_value, test_value_); + pthread_join(thread1, NULL); } TEST_F(ConditionalVariableTest, diff --git a/src/components/utils/test/lock_posix_test.cc b/src/components/utils/test/lock_boost_test.cc index a78659ab31..0da735a990 100644 --- a/src/components/utils/test/lock_posix_test.cc +++ b/src/components/utils/test/lock_boost_test.cc @@ -38,8 +38,9 @@ namespace components { namespace utils_test { using sync_primitives::Lock; +using sync_primitives::RecursiveLock; -TEST(LockPosixTest, DefaultCtorTest_ExpectNonRecursiveMutexCreated) { +TEST(LockBoostTest, TestNonRecursive) { // Create Lock object Lock test_mutex; // Lock mutex @@ -50,20 +51,9 @@ TEST(LockPosixTest, DefaultCtorTest_ExpectNonRecursiveMutexCreated) { test_mutex.Release(); } -TEST(LockPosixTest, CtorTestWithFalseArgument_ExpectNonRecursiveMutexCreated) { +TEST(LockBoostTest, TestRecursive) { // Create Lock object - Lock test_mutex(false); - // 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(LockPosixTest, CtorTestWithTrueArgument_ExpectRecursiveMutexCreated) { - // Create Lock object - Lock test_mutex(true); + RecursiveLock test_mutex; // Lock mutex test_mutex.Acquire(); // Check if created mutex is recursive @@ -73,17 +63,7 @@ TEST(LockPosixTest, CtorTestWithTrueArgument_ExpectRecursiveMutexCreated) { test_mutex.Release(); } -TEST(LockPosixTest, AcquireMutex_ExpectMutexLocked) { - // Create Lock object (non-recursive mutex) - Lock test_mutex; - // Lock mutex - test_mutex.Acquire(); - // Try to lock it again. If locked expect false - EXPECT_FALSE(test_mutex.Try()); - test_mutex.Release(); -} - -TEST(LockPosixTest, ReleaseMutex_ExpectMutexReleased) { +TEST(LockBoostTest, ReleaseMutex_ExpectMutexReleased) { // Create Lock object (non-recursive mutex) Lock test_mutex; // Lock mutex @@ -95,7 +75,7 @@ TEST(LockPosixTest, ReleaseMutex_ExpectMutexReleased) { test_mutex.Release(); } -TEST(LockPosixTest, TryLockNonRecursiveMutex_ExpectMutexNotLockedTwice) { +TEST(LockBoostTest, TryLockNonRecursiveMutex_ExpectMutexNotLockedTwice) { // Create Lock object (non-recursive mutex) Lock test_mutex; // Lock mutex @@ -105,9 +85,9 @@ TEST(LockPosixTest, TryLockNonRecursiveMutex_ExpectMutexNotLockedTwice) { test_mutex.Release(); } -TEST(LockPosixTest, TryLockRecursiveMutex_ExpectMutexLockedTwice) { +TEST(LockBoostTest, TryLockRecursiveMutex_ExpectMutexLockedTwice) { // Create Lock object (recursive mutex) - Lock test_mutex(true); + RecursiveLock test_mutex; // Lock mutex test_mutex.Try(); // Try to lock it again. Expect true and internal counter increase diff --git a/src/components/utils/test/message_queue_test.cc b/src/components/utils/test/message_queue_test.cc index ddc1aa1d81..9aa70933d6 100644 --- a/src/components/utils/test/message_queue_test.cc +++ b/src/components/utils/test/message_queue_test.cc @@ -158,6 +158,8 @@ TEST_F(MessageQueueTest, ASSERT_EQ(test_val_1, test_line); // Check the size of queue after 1 element was removed ASSERT_EQ(0u, test_queue.size()); + pthread_join(thread1, NULL); + pthread_join(thread2, NULL); } TEST_F(MessageQueueTest, @@ -169,6 +171,7 @@ TEST_F(MessageQueueTest, test_queue.wait(); check_value = true; ASSERT_TRUE(check_value); + pthread_join(thread1, NULL); } } // namespace utils_test |