[MediaController] Add locks for variable used in different threads 43/242843/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:25:52 +0000 (09:25 +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 55dccb2..7bfb7dd 100644 (file)
@@ -38,10 +38,12 @@ MediaControllerClient::MediaControllerClient() : handle_(nullptr) {
 MediaControllerClient::~MediaControllerClient() {
   ScopeLogger();
   if (handle_) {
+    std::lock_guard<std::mutex> 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<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",
         ("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<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",
         ("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<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 (ret != MEDIA_CONTROLLER_ERROR_NONE) {
index f359dc5..2ebbc16 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"
@@ -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_;
index bd88e3f..d280d8a 100644 (file)
@@ -56,6 +56,7 @@ MediaControllerServer::~MediaControllerServer() {
       LOGGER(ERROR) << "mc_server_destroy() failed, error: " << ret;
     }
   }
+  handle_ = nullptr;
 }
 
 PlatformResult MediaControllerServer::Init() {