Modified the KONA Issue. 42/125942/1
authorSegwon <segwon.han@samsung.com>
Wed, 19 Apr 2017 09:43:15 +0000 (18:43 +0900)
committerSegwon <segwon.han@samsung.com>
Wed, 19 Apr 2017 09:45:44 +0000 (18:45 +0900)
(The service is maintained even when the app is terminated abnormally.)

Signed-off-by: Segwon <segwon.han@samsung.com>
Change-Id: I504ef3125d95d99246aef794f23ecf3ddccafa09

daemon/Request.cpp
daemon/Request.h
daemon/service_provider/AppCommServiceApplication.cpp
daemon/service_provider/AppCommServiceProvider.cpp
daemon/service_provider/RemoteAppControlServiceProvider.cpp
lib/conv_lib_service.cpp

index a089dc0ee12c1184b7cca8346e37f9f3e6b16fa4..09c33114147808e284b1f2d275fcf41515b41d18 100755 (executable)
@@ -32,6 +32,7 @@ conv::Request::Request(int type, const char *client, int reqId, const char *subj
        , __invocation(inv)
        , __binaryLength(binaryLength)
        , __binary(binary)
+       , __isConnect(false)
 {
 }
 
@@ -41,6 +42,7 @@ conv::Request::Request(int type, const char* client, int reqId, const char* subj
        , __client(client)
        , __subject(subj)
        , __description(desc)
+       , __isConnect(false)
 {
 }
 
@@ -55,6 +57,7 @@ conv::Request::Request(int type,
        , __creds(creds)
        , __sender(sender)
        , __invocation(inv)
+       , __isConnect(false)
 {
 }
 
@@ -62,9 +65,15 @@ conv::Request::~Request()
 {
        if ( __creds != NULL ) {
                delete __creds;
+               __creds = NULL;
        }
 }
 
+void conv::Request::setType(int type)
+{
+       __type = type;
+}
+
 int conv::Request::getType()
 {
        return __type;
@@ -105,20 +114,32 @@ conv::Json& conv::Request::getDescription()
        return __description;
 }
 
+void conv::Request::setCreds(Credentials* creds)
+{
+       __creds = creds;
+}
+
 conv::Credentials* conv::Request::getCreds()
 {
        return __creds;
 }
 
+GDBusMethodInvocation* conv::Request::getInvocation()
+{
+       return __invocation;
+}
+
 bool conv::Request::reply(int error)
 {
        IF_FAIL_RETURN(__invocation, true);
 
        _I("Reply %#x", error);
 
-       g_dbus_method_invocation_return_value(__invocation, g_variant_new("(i)", error));
-       __invocation = NULL;
-       _D("Reply done");
+       if (!__isConnect) {
+               g_dbus_method_invocation_return_value(__invocation, g_variant_new("(i)", error));
+               __invocation = NULL;
+               _D("Reply done");
+       }
        return true;
 }
 
@@ -135,7 +156,10 @@ bool conv::Request::publish(int error, conv::Json& data, int binaryLength, const
        _D("info : binary length %d", binaryLength);
        _D("info : description %s", __description.str().c_str());
 
-       conv::dbus_server::publish(__sender.c_str(), __reqId, __subject.c_str(), error, dataStr, binaryLength, binary);
+       if (!__isConnect) {
+               _I("REPLY");
+               conv::dbus_server::publish(__sender.c_str(), __reqId, __subject.c_str(), error, dataStr, binaryLength, binary);
+       }
        g_free(dataStr);
 
        return true;
@@ -170,3 +194,20 @@ void conv::Request::setCommunicationInfo(conv::ICommunicationInfo* communication
 {
        __communicationInfo = communicationInfo;
 }
+
+bool conv::Request::getIsConnect()
+{
+       return __isConnect;
+}
+
+void conv::Request::setIsConnect(bool state)
+{
+       __isConnect = state;
+}
+
+conv::Request* conv::Request::clone()
+{
+       conv::Request *instance = new conv::Request(*this);
+       instance->setCreds(NULL);
+       return instance;
+}
\ No newline at end of file
index 0072310637f533a743624aff1f12b924dbf69a9c..cd53252dc8e0666521e93c030e523e6d29da25e8 100644 (file)
@@ -37,6 +37,7 @@ namespace conv {
                                        int binaryLength, const unsigned char* binary);
                        ~Request();
 
+                       void setType(int type);
                        int getType();
                        int getId();
                        int getBinaryLength();
@@ -46,6 +47,9 @@ namespace conv {
                        const unsigned char *getBinary();
                        Json& getDescription();
                        Credentials *getCreds();
+                       void setCreds(Credentials* creds);
+                       GDBusMethodInvocation* getInvocation();
+
                        bool reply(int error);
                        bool publish(int error, Json &data, int binaryLength, const unsigned char* binary);
 
@@ -57,20 +61,27 @@ namespace conv {
                        void setServiceInfo(IServiceInfo* serviceInfo);
                        void setCommunicationInfo(ICommunicationInfo* communicationInfo);
 
+                       void setIsConnect(bool state);
+                       bool getIsConnect();
+
+                       Request* clone();
+
                protected:
                        int __type;
                        int __reqId;
                        std::string __client;
                        std::string __subject;
                        Json __description;
-                       Credentials *__creds;
+                       Credentials *__creds = NULL;
                        std::string __sender;
-                       GDBusMethodInvocation *__invocation;
+                       GDBusMethodInvocation *__invocation = NULL;
+
+                       IServiceInfo* __serviceInfo = NULL;
+                       ICommunicationInfo* __communicationInfo = NULL;
+                       int __binaryLength = 0;
+                       const unsigned char* __binary = NULL;
 
-                       IServiceInfo* __serviceInfo;
-                       ICommunicationInfo* __communicationInfo;
-                       int __binaryLength;
-                       const unsigned char* __binary;
+                       bool __isConnect;
        };
 }
 
index c48802b1a8afe48520d55b30dea5bcbb4c4b434a..16aa6cea5c811085f1eca61ecdfd0d8a33fdf6aa 100755 (executable)
@@ -40,6 +40,9 @@ void conv::AppCommServiceApplication::onStart(bool start_result)
        } else {
                _D("state : APP_COMM_STATE_FAILED");
                state = APP_COMM_STATE_FAILED;
+               if (!isLocal && application != NULL) {
+                       application->disconnect();
+               }
        }
 
        if ((*requestObj) != NULL) {
index fda572b3dee142a8322439fa2ecdc996663d6e54..4191350eeef4550468634649e2ad25b7839d3781 100755 (executable)
@@ -21,6 +21,8 @@
 
 using namespace std;
 
+static std::map<std::string, guint> dbus_listener_info_map;
+
 static void vconf_update_cb(keynode_t *node, void* user_data)
 {
        conv::AppCommServiceProvider* instance = static_cast<conv::AppCommServiceProvider*>(user_data);
@@ -61,6 +63,7 @@ int conv::AppCommServiceProvider::handleVconfUpdate(keynode_t *node)
 
 conv::AppCommServiceProvider::~AppCommServiceProvider()
 {
+       dbus_listener_info_map.clear();
 }
 
 int conv::AppCommServiceProvider::init()
@@ -144,6 +147,80 @@ int conv::AppCommServiceProvider::loadServiceInfo(Request* requestObj)
        return CONV_ERROR_NONE;
 }
 
+static int stop_request(conv::Request* requestObj);
+
+static void _dbusDisconnectListenerFreeCallback(gpointer userData)
+{
+       conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
+       if (_requestObj != NULL) {
+               delete _requestObj;
+               _requestObj = NULL;
+       }
+}
+
+static void _dbusDisconnectListener(GDBusConnection* conn, const gchar* sender, const gchar* path, const gchar* iface, const gchar* name, GVariant* param, gpointer userData)
+{
+       conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
+
+       char* disconnectName;
+       g_variant_get_child(param, 0, "&s", &disconnectName);
+
+       if (!strcmp(disconnectName, _requestObj->getSender())) {
+               _D("Detected the dbus disconnection.");
+               stop_request(_requestObj);
+
+               std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
+               iter = dbus_listener_info_map.find(_requestObj->getSender());
+               if (iter != dbus_listener_info_map.end()) {
+                       guint listener_id = reinterpret_cast<guint>(iter->second);
+                       dbus_listener_info_map.erase(iter);
+                       GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
+                       g_dbus_connection_signal_unsubscribe(conn, listener_id);
+                       _D("Unsubscribe the dbus signal. id = %d", listener_id);
+
+                       conv::AppCommServiceInfo *svcInfo = reinterpret_cast<conv::AppCommServiceInfo*>(_requestObj->getServiceInfo());
+                       if (svcInfo->registeredRequest != NULL) {
+                               delete svcInfo->registeredRequest;
+                               svcInfo->registeredRequest = NULL;
+                       }
+                       if (_requestObj != NULL) {
+                               delete _requestObj;
+                               _requestObj = NULL;
+                       }
+               }
+       } else {
+               _E("Not found dbus disconnect listener.");
+       }
+}
+
+static void registDbusDisconnectListener(conv::Request* requestObj)
+{
+       std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
+       iter = dbus_listener_info_map.find(requestObj->getSender());
+       if (iter != dbus_listener_info_map.end()) {
+               guint listener_id = reinterpret_cast<guint>(iter->second);
+               dbus_listener_info_map.erase(iter);
+               GDBusConnection *conn = g_dbus_method_invocation_get_connection(requestObj->getInvocation());
+               g_dbus_connection_signal_unsubscribe(conn, listener_id);
+               _D("Unsubscribe the dbus signal. id = %d", listener_id);
+       }
+       conv::Request *_requestObj = requestObj->clone();
+       _requestObj->setIsConnect(true);
+
+       GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
+       guint listener_id = g_dbus_connection_signal_subscribe(conn, "org.freedesktop.DBus", "org.freedesktop.DBus", "NameOwnerChanged", "/org/freedesktop/DBus",
+               _requestObj->getSender(), G_DBUS_SIGNAL_FLAGS_NONE, _dbusDisconnectListener, _requestObj, _dbusDisconnectListenerFreeCallback);
+
+       if (listener_id == 0) {
+               _E("Dbus signal listener registration failed.");
+               delete _requestObj;
+               _requestObj = NULL;
+       } else {
+               _D("Subscribe the dbus signal. id = %d", listener_id);
+               dbus_listener_info_map[_requestObj->getSender()] = listener_id;
+       }
+}
+
 int conv::AppCommServiceProvider::startRequest(Request* requestObj)
 {
        _D("communcation/start requested");
@@ -254,6 +331,9 @@ int conv::AppCommServiceProvider::startRequest(Request* requestObj)
 
                svcInfo->applicationInstanceList.push_back(appInfo);
        }
+
+       registDbusDisconnectListener(requestObj);
+
        _D("connect requested");
 
        return CONV_ERROR_NONE;
@@ -262,9 +342,14 @@ int conv::AppCommServiceProvider::startRequest(Request* requestObj)
 int conv::AppCommServiceProvider::stopRequest(Request* requestObj)
 {
        _D("communcation/stop requested");
-       AppCommServiceInfo *svcInfo = reinterpret_cast<AppCommServiceInfo*>(requestObj->getServiceInfo());
+       return stop_request(requestObj);
+}
 
-       Json channel;
+static int stop_request(conv::Request* requestObj)
+{
+       conv::AppCommServiceInfo *svcInfo = reinterpret_cast<conv::AppCommServiceInfo*>(requestObj->getServiceInfo());
+
+       conv::Json channel;
        requestObj->getChannelFromDescription(&channel);
 
        string uri, channelId;
@@ -275,12 +360,12 @@ int conv::AppCommServiceProvider::stopRequest(Request* requestObj)
        IF_FAIL_RETURN_TAG(!uri.empty() || svcInfo->isLocal, CONV_ERROR_INVALID_PARAMETER, _E, "uri is empty");
        IF_FAIL_RETURN_TAG(!channelId.empty(), CONV_ERROR_INVALID_PARAMETER, _E, "channelId is empty");
 
-       for (ApplicationInstanceList::iterator iter = svcInfo->applicationInstanceList.begin(); iter != svcInfo->applicationInstanceList.end(); ++iter) {
+       for (conv::ApplicationInstanceList::iterator iter = svcInfo->applicationInstanceList.begin(); iter != svcInfo->applicationInstanceList.end(); ++iter) {
                _D("%s, %s", (*iter)->uri.c_str(), (*iter)->channelId.c_str());
                if ( (*iter) != NULL && !(*iter)->uri.compare(uri) && !(*iter)->channelId.compare(channelId) ) {
                        if ( (*iter)->state == APP_COMM_STATE_STARTED ) {
                                _D("stopping the application");
-                               AppCommServiceApplication *appInfo = *iter;
+                               conv::AppCommServiceApplication *appInfo = *iter;
 
                                _D("COMMUNCATION_STOP : uri : %s, channel_id : %s", uri.c_str(), channelId.c_str());
 
@@ -303,7 +388,6 @@ int conv::AppCommServiceProvider::stopRequest(Request* requestObj)
        return CONV_ERROR_NONE;
 }
 
-
 int conv::AppCommServiceProvider::readRequest(Request* requestObj)
 {
        _D("communcation/get requested");
index ba6777b55012cbf84210f2f8407e80efe5c9bcba..c6ac8d237ff77b2a67cfcfa276ffa998a27eeff5 100755 (executable)
@@ -20,6 +20,7 @@
 #include "RemoteAppControlServiceProvider.h"
 #include "../ClientManager.h"
 #include "../Util.h"
+#include "../Server.h"
 #if defined(_D2D_INTERNAL_ACL_)
 #include "../access_control/ACLManager.h"
 
@@ -53,6 +54,7 @@ static int get_req_id()
 
 static std::map<long long, app_control_cb_info_s> app_control_cb_map;
 static std::map<int, response_cb_info_s> response_cb_map;
+static std::map<std::string, guint> dbus_listener_info_map;
 
 static void vconf_update_cb(keynode_t *node, void* user_data)
 {
@@ -87,6 +89,7 @@ conv::RemoteAppControlServiceProvider::~RemoteAppControlServiceProvider()
 {
        app_control_cb_map.clear();
        response_cb_map.clear();
+       dbus_listener_info_map.clear();
 
 #if !defined(_D2D_INTERNAL_ACL_)
        int error = rdm_deinit();
@@ -210,6 +213,9 @@ static void _app_control_cb(app_control_h request, app_control_h reply, app_cont
        _send_response(cb_info.request_handle, rep, IOTCON_RESPONSE_OK);
        _D("Response sent");
 
+       iotcon_attributes_destroy(attributes);
+       iotcon_representation_destroy(rep);
+
        bundle_free(p_bundle);
        bundle_free(p_bundle_request);
        app_control_cb_map.erase(find_iter);
@@ -653,19 +659,19 @@ int conv::RemoteAppControlServiceProvider::init()
                iotcon_resource_types_add(resource_types, __resourceType.c_str());
 
                error = iotcon_resource_interfaces_create(&resource_ifaces);
-
-               IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "ri creation failed");
+               IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "ri creation failed");
 
                iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
 
-
                error = iotcon_resource_create(CONV_URI_REMOTE_APP_CONTROL, resource_types, resource_ifaces, properties, __iotcon_request_cb, NULL, &iotcon_resource);
-               IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "resource creation failed");
+               IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "resource creation failed");
 
+               _D("RemoteAppControlServiceProvider init done");
+CATCH:
                iotcon_resource_types_destroy(resource_types);
                iotcon_resource_interfaces_destroy(resource_ifaces);
+               IF_FAIL_RETURN(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION);
 
-               _D("RemoteAppControlServiceProvider init done");
        } else {
                _D("RemoteAppControlServiceProvider is already initiated");
        }
@@ -812,6 +818,88 @@ static void passkey_popup_callback(void *user_data, int result, char *passkey)
 }
 #endif
 
+static int stop_request(conv::Request* requestObj);
+
+static void _dbusDisconnectListenerFreeCallback(gpointer userData)
+{
+       conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
+       if (_requestObj != NULL) {
+               delete _requestObj;
+               _requestObj = NULL;
+       }
+}
+
+static void _dbusDisconnectListener(GDBusConnection* conn, const gchar* sender, const gchar* path, const gchar* iface, const gchar* name, GVariant* param, gpointer userData)
+{
+       conv::Request *_requestObj = reinterpret_cast<conv::Request *>(userData);
+
+       char* disconnectName;
+       g_variant_get_child(param, 0, "&s", &disconnectName);
+
+       if (!strcmp(disconnectName, _requestObj->getSender())) {
+               _D("Detected the dbus disconnection.");
+               stop_request(_requestObj);
+
+               std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
+               iter = dbus_listener_info_map.find(_requestObj->getSender());
+
+               if (iter != dbus_listener_info_map.end()) {
+
+                       guint listener_id = reinterpret_cast<guint>(iter->second);
+                       dbus_listener_info_map.erase(iter);
+
+                       GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
+                       g_dbus_connection_signal_unsubscribe(conn, listener_id);
+                       _D("Delete dbus disconnect listener.");
+
+                       conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(_requestObj->getServiceInfo());
+                       if (svcInfo->registeredRequest != NULL) {
+                               delete svcInfo->registeredRequest;
+                               svcInfo->registeredRequest = NULL;
+                       }
+                       if (_requestObj != NULL) {
+                               delete _requestObj;
+                               _requestObj = NULL;
+                       }
+               }
+       } else {
+               _D("Not found dbus disconnect listener.");
+       }
+}
+
+static void registDbusDisconnectListener(conv::Request* requestObj)
+{
+       std::map<std::string, guint>::iterator iter = dbus_listener_info_map.end();
+       iter = dbus_listener_info_map.find(requestObj->getSender());
+
+       if (iter != dbus_listener_info_map.end()) {
+
+               guint listener_id = reinterpret_cast<guint>(iter->second);
+               dbus_listener_info_map.erase(iter);
+
+               GDBusConnection *conn = g_dbus_method_invocation_get_connection(requestObj->getInvocation());
+               g_dbus_connection_signal_unsubscribe(conn, listener_id);
+               _D("Delete dbus disconnect listener.");
+       }
+
+       conv::Request *_requestObj = requestObj->clone();
+       _requestObj->setIsConnect(true);
+
+       GDBusConnection *conn = g_dbus_method_invocation_get_connection(_requestObj->getInvocation());
+
+       guint listener_id = g_dbus_connection_signal_subscribe(conn, "org.freedesktop.DBus", "org.freedesktop.DBus", "NameOwnerChanged", "/org/freedesktop/DBus",
+               _requestObj->getSender(), G_DBUS_SIGNAL_FLAGS_NONE, _dbusDisconnectListener, _requestObj, _dbusDisconnectListenerFreeCallback);
+
+       if (listener_id == 0) {
+               _E("Dbus signal listener registration failed.");
+               delete _requestObj;
+               _requestObj = NULL;
+       } else {
+               dbus_listener_info_map[_requestObj->getSender()] = listener_id;
+               _D("Subscribe the dbus signal. id = %d", listener_id);
+       }
+}
+
 int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
 {
        _D("communcation/start requested");
@@ -838,8 +926,7 @@ int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
        iotcon_resource_types_add(resource_types, svcInfo->iotconInfoObj.resourceType.c_str());
 
        error = iotcon_resource_interfaces_create(&resource_ifaces);
-
-       IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "ri creation failed");
+       IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "ri creation failed");
 
        iotcon_resource_interfaces_add(resource_ifaces, IOTCON_INTERFACE_DEFAULT);
 
@@ -847,11 +934,14 @@ int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
                        &(svcInfo->iotconInfoObj.iotconResourceHandle));
 
        _D("remote resource created : %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
+       IF_FAIL_CATCH_TAG(error == IOTCON_ERROR_NONE, _E, "remote resource creation failed %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
 
-       IF_FAIL_RETURN_TAG(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION, _E, "remote resource creation failed %s, %s", svcInfo->iotconInfoObj.address.c_str(), svcInfo->iotconInfoObj.uri.c_str());
+       registDbusDisconnectListener(requestObj);
 
+CATCH:
        iotcon_resource_types_destroy(resource_types);
        iotcon_resource_interfaces_destroy(resource_ifaces);
+       IF_FAIL_RETURN(error == IOTCON_ERROR_NONE, CONV_ERROR_INVALID_OPERATION);
 
        //send message for access request
        iotcon_representation_h representation;
@@ -877,9 +967,13 @@ int conv::RemoteAppControlServiceProvider::startRequest(Request* requestObj)
 int conv::RemoteAppControlServiceProvider::stopRequest(Request* requestObj)
 {
        _D("communcation/stop requested");
-       Json result;
+       return stop_request(requestObj);
+}
 
-       RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
+static int stop_request(conv::Request* requestObj)
+{
+       conv::Json result;
+       conv::RemoteAppControlServiceInfo *svcInfo = reinterpret_cast<conv::RemoteAppControlServiceInfo*>(requestObj->getServiceInfo());
 
        if (svcInfo->iotconInfoObj.iotconResourceHandle == NULL) {
                _D("not even started");
@@ -889,8 +983,8 @@ int conv::RemoteAppControlServiceProvider::stopRequest(Request* requestObj)
 
        iotcon_remote_resource_destroy(svcInfo->iotconInfoObj.iotconResourceHandle);
        svcInfo->iotconInfoObj.iotconResourceHandle = NULL;
-       sendResponse(result, CONV_JSON_ON_STOP, CONV_ERROR_NONE, svcInfo->registeredRequest);
 
+       sendResponse(result, CONV_JSON_ON_STOP, CONV_ERROR_NONE, svcInfo->registeredRequest);
        return CONV_ERROR_NONE;
 }
 
@@ -1104,7 +1198,6 @@ int conv::RemoteAppControlServiceProvider::registerRequest(Request* requestObj)
                                        it->second = cbInfo;
                                }
                        }
-
                        delete svcInfo->registeredRequest;
                }
                svcInfo->registeredRequest = requestObj;
@@ -1121,7 +1214,6 @@ int conv::RemoteAppControlServiceProvider::registerRequest(Request* requestObj)
                                it->second = cbInfo;
                        }
                }
-
                delete svcInfo->registeredRequest;
                svcInfo->registeredRequest = NULL;
                requestObj->reply(CONV_ERROR_NONE);
@@ -1137,7 +1229,6 @@ int conv::RemoteAppControlServiceProvider::registerRequest(Request* requestObj)
        return CONV_ERROR_NONE;
 }
 
-
 int conv::RemoteAppControlServiceProvider::loadServiceInfo(Request* requestObj)
 {
        string client;
index ea99bf755a71b86b4dd513ad2f929863aca5339d..9379893ea15d45ae71856d6fc6bc07c893270dea 100755 (executable)
@@ -73,6 +73,7 @@ static void conv_subject_cb(const char* subject, int req_id, int error, json dat
                return;
        }
 
+       conv_error_e conv_error;
        _conv_service_callback_info* callback_info = it->second;
 
        conv_service_h service_handle = new(std::nothrow) _conv_service_handle();
@@ -87,22 +88,23 @@ static void conv_subject_cb(const char* subject, int req_id, int error, json dat
 
        if (!channel.isEmpty()) {
                channel_handle = new(std::nothrow) _conv_channel_handle();
-               IF_FAIL_VOID_TAG(channel_handle, _E, "Memory allocation failed");
+               IF_FAIL_CATCH_TAG(channel_handle, _E, "Memory allocation failed");
                channel_handle->jchannel = channel;
        }
 
        if (!payload.isEmpty() || binary_length > 0) {
                payload_handle = new(std::nothrow) _conv_payload_handle();
-               IF_FAIL_VOID_TAG(payload_handle, _E, "Memory allocation failed");
+               IF_FAIL_CATCH_TAG(payload_handle, _E, "Memory allocation failed");
 
                payload_handle->jpayload = payload;
                payload_handle->binary_length = binary_length;
                payload_handle->binary = binary;
        }
 
-       conv_error_e conv_error = (conv_error_e)error;
+       conv_error = (conv_error_e)error;
        callback_info->cb(service_handle, channel_handle, conv_error, payload_handle, callback_info->user_data);
 
+CATCH:
        if (payload_handle) {
                delete payload_handle;
        }
@@ -287,7 +289,7 @@ EXTAPI int conv_service_unset_listener_cb(conv_service_h handle)
        _conv_service_callback_info* callback_info = it->second;
 
        delete callback_info;
-    callback_map.erase(it);
+       callback_map.erase(it);
 
        return CONV_ERROR_NONE;
 }