[MediaController] Add locks for variable used in different threads 42/242842/1
authorRafal Walczyna <r.walczyna@samsung.com>
Tue, 25 Aug 2020 07:29:53 +0000 (09:29 +0200)
committerRafal Walczyna <r.walczyna@samsung.com>
Tue, 1 Sep 2020 07:00:19 +0000 (09:00 +0200)
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 <r.walczyna@samsung.com>
src/mediacontroller/mediacontroller_client.cc
src/mediacontroller/mediacontroller_client.h
src/mediacontroller/mediacontroller_server.cc

index cce90a2..429f141 100644 (file)
@@ -46,8 +46,12 @@ MediaControllerClient::~MediaControllerClient() {
     LoggerE("Failed to unset playback info listener");
   }
 
-  if (nullptr != handle_ && MEDIA_CONTROLLER_ERROR_NONE != mc_client_destroy(handle_)) {
-    LoggerE("Unable to destroy media controller client");
+  {
+    std::lock_guard<std::mutex> lock(handle_mutex_);
+    if (nullptr != handle_ && MEDIA_CONTROLLER_ERROR_NONE != mc_client_destroy(handle_)) {
+      LoggerE("Unable to destroy media controller client");
+    }
+    handle_ = nullptr;
   }
 }
 
@@ -66,8 +70,10 @@ PlatformResult MediaControllerClient::Init() {
 PlatformResult MediaControllerClient::FindServers(picojson::array* servers) {
   ScopeLogger();
   int ret;
-
-  ret = mc_client_foreach_server(handle_, FindServersCallback, servers);
+  {
+    std::lock_guard<std::mutex> 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",
@@ -125,7 +131,10 @@ PlatformResult MediaControllerClient::GetLatestServerInfo(picojson::value* serve
     free(name);
   };
   mc_server_state_e state;
-  ret = mc_client_get_latest_server_info(handle_, &name, &state);
+  {
+    std::lock_guard<std::mutex> 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",
@@ -547,6 +556,7 @@ PlatformResult MediaControllerClient::SendPlaybackState(const std::string& serve
   }
 
   int ret;
+  std::lock_guard<std::mutex> lock(handle_mutex_);
   ret = mc_client_send_playback_state_command(handle_, server_name.c_str(),
                                               static_cast<mc_playback_states_e>(state_e));
   if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
@@ -566,6 +576,7 @@ PlatformResult MediaControllerClient::SendPlaybackPosition(const std::string& se
   SCOPE_EXIT {
     free(request_id);
   };*/
+  std::lock_guard<std::mutex> lock(handle_mutex_);
   int ret = mc_client_send_playback_position_cmd(handle_, server_name.c_str(),
                                                  static_cast<unsigned long long>(position),
                                                  /*&request_id*/ nullptr);
@@ -585,6 +596,7 @@ PlatformResult MediaControllerClient::SendShuffleMode(const std::string& server_
   SCOPE_EXIT {
     free(request_id);
   };*/
+  std::lock_guard<std::mutex> lock(handle_mutex_);
   int ret = mc_client_send_shuffle_mode_cmd(handle_, server_name.c_str(),
                                             mode ? MC_SHUFFLE_MODE_ON : MC_SHUFFLE_MODE_OFF,
                                             /*&request_id*/ nullptr);
index bb7cb8a..f1aa8c4 100644 (file)
@@ -18,6 +18,7 @@
 #define MEDIACONTROLLER_MEDIACONTROLLER_CLIENT_H_
 
 #include <media_controller_client.h>
+#include <mutex>
 #include <string>
 
 #include "common/platform_result.h"
@@ -58,6 +59,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_;
index b2a3e83..86204fb 100644 (file)
@@ -56,6 +56,7 @@ MediaControllerServer::~MediaControllerServer() {
   if (nullptr != handle_ && MEDIA_CONTROLLER_ERROR_NONE != mc_server_destroy(handle_)) {
     LoggerE("Unable to destroy media controller server");
   }
+  handle_ = nullptr;
 }
 
 PlatformResult MediaControllerServer::Init() {