[Convergence] added proper stopping communication channels 64/99964/1
authorPiotr Kosko <p.kosko@samsung.com>
Thu, 24 Nov 2016 13:20:10 +0000 (14:20 +0100)
committerPiotr Kosko <p.kosko@samsung.com>
Thu, 24 Nov 2016 13:26:30 +0000 (14:26 +0100)
[Feature] While start/stop service, channels are managed to perform proper
  cleaning when instance would be destroyed.

[Verification] all AppCommunicationService_getClientList* and AppCommunicationService_start*
  tests stopped blocking.

Change-Id: I4f6de9e664a122cb29d99e67fd65c7553a744d23
Signed-off-by: Piotr Kosko <p.kosko@samsung.com>
src/convergence/convergence_app_communication_service.cc
src/convergence/convergence_app_communication_service.h
src/convergence/convergence_channel_info.cc
src/convergence/convergence_channel_info.h
src/convergence/convergence_instance.cc
src/convergence/convergence_service.cc
src/convergence/convergence_service.h

index e88b82f..8a80eb7 100644 (file)
@@ -20,6 +20,7 @@
 #include <glib.h>
 #include <d2d_conv_internal.h>
 #include <stdlib.h>
+#include <memory>
 
 #include "convergence/convergence_instance.h"
 #include "convergence/convergence_channel_info.h"
@@ -59,11 +60,12 @@ ConvergenceAppCommunicationService::~ConvergenceAppCommunicationService() {
 }
 
 common::TizenResult ConvergenceAppCommunicationService::Start(
-  ConvergenceChannel& channel,
+  ConvergenceChannel* channel,
   const int cur_listener_id) {
   ScopeLogger();
 
   LoggerI("Starting service [0x%x] with handle [0x%x]", this, service_handle_);
+  std::unique_ptr<ConvergenceChannel> ch_ptr(channel); // auto release memory in case of error
 
   conv_service_h service_handle = FindServiceHandle();
   if (!service_handle) {
@@ -72,11 +74,13 @@ common::TizenResult ConvergenceAppCommunicationService::Start(
 
   UpdateListener(cur_listener_id);
 
-  const int error = conv_service_start(service_handle, channel.GetHandle(), nullptr);
+  const int error = conv_service_start(service_handle, channel->GetHandle(), nullptr);
   if (CONV_ERROR_NONE != error) {
     return LogAndCreateTizenError(AbortError, "Failed to start service");
   }
 
+  opened_channels.push_back(ch_ptr.release());
+
   return TizenSuccess();
 }
 
@@ -96,6 +100,20 @@ common::TizenResult ConvergenceAppCommunicationService::Stop(
   if (CONV_ERROR_NONE != error) {
     return LogAndCreateTizenError(AbortError, "Failed to stop service");
   }
+
+  std::string removed_uri = channel.GetUri();
+  std::string removed_id = channel.GetId();
+
+  for (auto it = opened_channels.begin(); it != opened_channels.end(); ++it){
+    if((*it)->GetUri() == removed_uri && (*it)->GetId() == removed_id) {
+      LoggerD("Removing channel uri: [%s] id: [%s]", removed_uri.c_str(), removed_id.c_str());
+      delete *it;
+      (*it) = nullptr;
+      opened_channels.erase(it);
+      break;
+    }
+  }
+
   return TizenSuccess();
 }
 
@@ -343,7 +361,7 @@ ConvergenceAppCommunicationServerService::~ConvergenceAppCommunicationServerServ
 }
 
 common::TizenResult ConvergenceAppCommunicationServerService::Start(
-  ConvergenceChannel& channel,
+  ConvergenceChannel* channel,
   const int cur_listener_id) {
   ScopeLogger();
 
@@ -355,7 +373,7 @@ common::TizenResult ConvergenceAppCommunicationServerService::Start(
   picojson::object param;
   param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusOk);
 
-  param[kChannel] = ConvergenceChannel::ToJson(channel.GetHandle()); // Define string as constant
+  param[kChannel] = ConvergenceChannel::ToJson(channel->GetHandle()); // Define string as constant
   param[kServiceResultType] = picojson::value(kServiceResultTypeOnStart);
 
   common::TizenResult result = ConvergenceAppCommunicationService::Start(channel, cur_listener_id);
index 57dd5de..ed759d3 100644 (file)
@@ -43,7 +43,7 @@ class ConvergenceAppCommunicationService : public ConvergenceService {
   ConvergenceAppCommunicationService& operator=(const ConvergenceAppCommunicationService&) = delete;
   ConvergenceAppCommunicationService& operator=(ConvergenceAppCommunicationService&&) = delete;
  public:
-  virtual common::TizenResult Start(ConvergenceChannel& channel,
+  virtual common::TizenResult Start(ConvergenceChannel* channel,
    const int cur_listener_id);
   virtual common::TizenResult Stop(ConvergenceChannel& channel,
    const int cur_listener_id);
@@ -75,7 +75,7 @@ class ConvergenceAppCommunicationServerService : public ConvergenceAppCommunicat
   ConvergenceAppCommunicationServerService& operator=(ConvergenceAppCommunicationServerService&&) = delete;
 
  public:
-  virtual common::TizenResult Start(ConvergenceChannel& channel,
+  virtual common::TizenResult Start(ConvergenceChannel* channel,
    const int cur_listener_id);
   virtual common::TizenResult Stop(ConvergenceChannel& channel,
    const int cur_listener_id);
index ef4d579..a87c290 100644 (file)
@@ -59,6 +59,14 @@ conv_channel_h ConvergenceChannel::GetHandle() const {
   return channel_handle_;
 }
 
+std::string ConvergenceChannel::GetUri() const {
+  return uri_;
+}
+
+std::string ConvergenceChannel::GetId() const {
+  return id_;
+}
+
 
 void ConvergenceChannel::FromJson(const picojson::value &channel_json) {
   ScopeLogger();
@@ -78,14 +86,14 @@ void ConvergenceChannel::FromJson(const picojson::value &channel_json) {
     return;
   }
 
-  const std::string id = channel_json.get(kId).to_str();
-  error = conv_channel_set_string(channel_handle_, kChannelId.c_str(), id.c_str());
+  id_ = channel_json.get(kId).to_str();
+  error = conv_channel_set_string(channel_handle_, kChannelId.c_str(), id_.c_str());
   if (CONV_ERROR_NONE != error) {
     trace_conv_error(error, __LINE__, "setting channel string Id");
   }
 
-  const std::string uri = channel_json.get(kUri).to_str();
-  error = conv_channel_set_string(channel_handle_, kUri.c_str(), uri.c_str());
+  uri_ = channel_json.get(kUri).to_str();
+  error = conv_channel_set_string(channel_handle_, kUri.c_str(), uri_.c_str());
   if (CONV_ERROR_NONE != error) {
     trace_conv_error(error, __LINE__, "setting channel string URI");
   }
index 952838c..f1e87c7 100644 (file)
@@ -41,6 +41,8 @@ class ConvergenceChannel {
 
  public:
   conv_channel_h GetHandle() const;
+  std::string GetId() const;
+  std::string GetUri() const;
   void FromJson(const picojson::value &channel_json);
 
  public:
@@ -48,6 +50,8 @@ class ConvergenceChannel {
 
  private:
   conv_channel_h channel_handle_;
+  std::string id_;
+  std::string uri_;
 };
 
 } // namespace convergence
index 89e0031..91f6c4d 100644 (file)
@@ -430,7 +430,8 @@ common::TizenResult ConvergenceInstance::AppCommunicationServiceStart(const pico
       result = LogAndCreateTizenError(NotFoundError, "Can not find the service type = 1");
     } else {
       // Running the service start procedure
-      ConvergenceChannel channel(ConvergenceUtils::GetArg(args, kJSArgumentChannel));
+      ConvergenceChannel* channel = new ConvergenceChannel
+          (ConvergenceUtils::GetArg(args, kJSArgumentChannel));  // memory would be managed in Start method
       const int id = static_cast<int>(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get<double>());
 
       result = service->Start(channel, id);
index 035b51f..7c5fc62 100644 (file)
@@ -53,7 +53,26 @@ ConvergenceService::ConvergenceService(conv_device_h device, conv_service_e type
 
 ConvergenceService::~ConvergenceService() {
   ScopeLogger();
-  LoggerI("DESTROYING SERVICE HANDLE [0x0%x] in ConvergenceService destr", service_handle_);
+  LoggerI("!!! DESTROYING SERVICE HANDLE [0x0%x] in ConvergenceService destr", service_handle_);
+  // first try to stop service
+  int error = conv_service_unset_listener_cb(service_handle_);
+  if (CONV_ERROR_NONE != error) {
+    LoggerW("unset_listener error %d [%s]", error, get_error_message(error));
+  } else {
+    LoggerD("listener usnet");
+  }
+
+  std::for_each(opened_channels.begin(), opened_channels.end(),
+                [this](ConvergenceChannel* c){
+    int error = conv_service_stop(service_handle_, c->GetHandle(), nullptr);
+    if (CONV_ERROR_NONE != error) {
+      LoggerW("2 service was not stopped - error %d [%s]", error, get_error_message(error));
+    } else {
+      LoggerD("2 service stopped");
+    }
+  });
+
+  // later destroy handle
   conv_service_destroy(service_handle_);
 }
 
index 55fe741..737debd 100644 (file)
 
 #include <string>
 #include <unordered_map>
+#include <vector>
 
 #include "common/tizen_result.h"
+#include "convergence/convergence_channel_info.h"
 
 namespace extension {
 namespace convergence {
@@ -63,6 +65,7 @@ class ConvergenceService {
   conv_device_h device_; // TODO rename to device_handle_
   conv_service_e type_;
   mutable conv_service_h service_handle_;
+  std::vector<ConvergenceChannel*> opened_channels;
   friend class ConvergenceAppCommunicationServerService; // It is needed to register the local service
  private:
   conv_service_connection_state_e connection_state_;