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