[MediaController] Add locks for variable used in different threads 37/242837/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 06:45:58 +0000 (08:45 +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 cee9325..c95fcb9 100644 (file)
@@ -55,8 +55,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;
   }
 }
 
@@ -83,8 +87,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",
@@ -142,7 +148,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",
@@ -562,6 +571,7 @@ PlatformResult MediaControllerClient::SendPlaybackState(const std::string& serve
   SCOPE_EXIT {
     free(request_id);
   };*/
+  std::lock_guard<std::mutex> lock(handle_mutex_);
   int ret = mc_client_send_playback_action_cmd(handle_, server_name.c_str(), action_e, nullptr);
   if (MEDIA_CONTROLLER_ERROR_NONE != ret) {
     return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error sending playback state",
@@ -580,6 +590,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);
@@ -599,6 +610,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 d226e3f..8ea1216 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 622bfa7..d95e2fd 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() {