From: Rafal Walczyna Date: Tue, 25 Aug 2020 07:29:53 +0000 (+0200) Subject: [MediaController] Add locks for variable used in different threads X-Git-Tag: submit/tizen/20200923.101308~1^2~1^2^2^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b2124cd3a6e116aeba64cf3a6876d6d3fa887a1c;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [MediaController] Add locks for variable used in different threads Handles for client and server can be used in different threads. It may cause segmentation fault when already freed handle will be used. Verification: Build successful Change-Id: Iba90d1a85be51710ccda169389ce393f5ce1d1a3 Signed-off-by: Rafal Walczyna --- diff --git a/src/mediacontroller/mediacontroller_client.cc b/src/mediacontroller/mediacontroller_client.cc index 55dccb2b..7bfb7dd4 100644 --- a/src/mediacontroller/mediacontroller_client.cc +++ b/src/mediacontroller/mediacontroller_client.cc @@ -38,10 +38,12 @@ MediaControllerClient::MediaControllerClient() : handle_(nullptr) { MediaControllerClient::~MediaControllerClient() { ScopeLogger(); if (handle_) { + std::lock_guard lock(handle_mutex_); int ret = mc_client_destroy(handle_); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { LOGGER(ERROR) << "Unable to destroy media controller client"; } + handle_ = nullptr; } } @@ -60,9 +62,11 @@ PlatformResult MediaControllerClient::Init() { PlatformResult MediaControllerClient::FindServers(picojson::array* servers) { ScopeLogger(); int ret; - - ret = mc_client_foreach_server(handle_, FindServersCallback, servers); - if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + { + std::lock_guard lock(handle_mutex_); + ret = mc_client_foreach_server(handle_, FindServersCallback, servers); + } + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { return LogAndCreateResult( ErrorCode::UNKNOWN_ERR, "Unable to fetch active servers, error", ("mc_client_foreach_server() error: %d, message: %s", ret, get_error_message(ret))); @@ -119,8 +123,11 @@ PlatformResult MediaControllerClient::GetLatestServerInfo(picojson::value* serve free(name); }; mc_server_state_e state; - ret = mc_client_get_latest_server_info(handle_, &name, &state); - if (ret != MEDIA_CONTROLLER_ERROR_NONE) { + { + std::lock_guard lock(handle_mutex_); + ret = mc_client_get_latest_server_info(handle_, &name, &state); + } + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { return LogAndCreateResult( ErrorCode::UNKNOWN_ERR, "Error getting latest server info", ("mc_client_get_latest_server_info() error: %d, message: %s", ret, get_error_message(ret))); @@ -567,6 +574,7 @@ PlatformResult MediaControllerClient::SendPlaybackState(const std::string& serve } int ret; + std::lock_guard lock(handle_mutex_); ret = mc_client_send_playback_state_command(handle_, server_name.c_str(), static_cast(state_e)); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { diff --git a/src/mediacontroller/mediacontroller_client.h b/src/mediacontroller/mediacontroller_client.h index f359dc51..2ebbc163 100644 --- a/src/mediacontroller/mediacontroller_client.h +++ b/src/mediacontroller/mediacontroller_client.h @@ -18,6 +18,7 @@ #define MEDIACONTROLLER_MEDIACONTROLLER_CLIENT_H_ #include +#include #include #include "common/platform_result.h" @@ -55,6 +56,11 @@ class MediaControllerClient { private: mc_client_h handle_; + // This mutex is used to guard handle_ usage in TaskQueue + // and its destruction, but there is no need to + // guard every call on main thread. + std::mutex handle_mutex_; + JsonCallback playback_info_listener_; JsonCallback server_status_listener_; JsonCallback command_reply_callback_; diff --git a/src/mediacontroller/mediacontroller_server.cc b/src/mediacontroller/mediacontroller_server.cc index bd88e3f5..d280d8a2 100644 --- a/src/mediacontroller/mediacontroller_server.cc +++ b/src/mediacontroller/mediacontroller_server.cc @@ -56,6 +56,7 @@ MediaControllerServer::~MediaControllerServer() { LOGGER(ERROR) << "mc_server_destroy() failed, error: " << ret; } } + handle_ = nullptr; } PlatformResult MediaControllerServer::Init() {