From be294cce97b972284fb311ee64a4111fa92387a2 Mon Sep 17 00:00:00 2001
From: Piotr Kosko
Date: Thu, 24 Nov 2016 14:20:10 +0100
Subject: [PATCH] [Convergence] added proper stopping communication channels
[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
---
.../convergence_app_communication_service.cc | 26 ++++++++++++++++++----
.../convergence_app_communication_service.h | 4 ++--
src/convergence/convergence_channel_info.cc | 16 +++++++++----
src/convergence/convergence_channel_info.h | 4 ++++
src/convergence/convergence_instance.cc | 3 ++-
src/convergence/convergence_service.cc | 21 ++++++++++++++++-
src/convergence/convergence_service.h | 3 +++
7 files changed, 65 insertions(+), 12 deletions(-)
diff --git a/src/convergence/convergence_app_communication_service.cc b/src/convergence/convergence_app_communication_service.cc
index e88b82f..8a80eb7 100644
--- a/src/convergence/convergence_app_communication_service.cc
+++ b/src/convergence/convergence_app_communication_service.cc
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#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 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);
diff --git a/src/convergence/convergence_app_communication_service.h b/src/convergence/convergence_app_communication_service.h
index 57dd5de..ed759d3 100644
--- a/src/convergence/convergence_app_communication_service.h
+++ b/src/convergence/convergence_app_communication_service.h
@@ -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);
diff --git a/src/convergence/convergence_channel_info.cc b/src/convergence/convergence_channel_info.cc
index ef4d579..a87c290 100644
--- a/src/convergence/convergence_channel_info.cc
+++ b/src/convergence/convergence_channel_info.cc
@@ -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");
}
diff --git a/src/convergence/convergence_channel_info.h b/src/convergence/convergence_channel_info.h
index 952838c..f1e87c7 100644
--- a/src/convergence/convergence_channel_info.h
+++ b/src/convergence/convergence_channel_info.h
@@ -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
diff --git a/src/convergence/convergence_instance.cc b/src/convergence/convergence_instance.cc
index 89e0031..91f6c4d 100644
--- a/src/convergence/convergence_instance.cc
+++ b/src/convergence/convergence_instance.cc
@@ -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(ConvergenceUtils::GetArg(args, kJSCurrentListenerId).get());
result = service->Start(channel, id);
diff --git a/src/convergence/convergence_service.cc b/src/convergence/convergence_service.cc
index 035b51f..7c5fc62 100644
--- a/src/convergence/convergence_service.cc
+++ b/src/convergence/convergence_service.cc
@@ -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_);
}
diff --git a/src/convergence/convergence_service.h b/src/convergence/convergence_service.h
index 55fe741..737debd 100644
--- a/src/convergence/convergence_service.h
+++ b/src/convergence/convergence_service.h
@@ -22,8 +22,10 @@
#include
#include
+#include
#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 opened_channels;
friend class ConvergenceAppCommunicationServerService; // It is needed to register the local service
private:
conv_service_connection_state_e connection_state_;
--
2.7.4