(ACR) Change from iotcon_remote_resource_ref to iotcon_remote_resource_clone
authorsung.goo.kim <sung.goo.kim@samsung.com>
Thu, 22 Oct 2015 03:29:27 +0000 (12:29 +0900)
committeryoungman <yman.jung@samsung.com>
Tue, 3 Nov 2015 11:08:20 +0000 (20:08 +0900)
Change-Id: Ifbb15b398675072d0ce17ec9ba0365756c1fd205

lib/icl-remote-resource-crud.c
lib/icl-remote-resource.c
lib/icl-remote-resource.h
lib/include/iotcon.h
test/crud-test-client.c

index a7f8065..6daaab8 100644 (file)
@@ -48,6 +48,33 @@ typedef struct {
        iotcon_remote_resource_h resource;
 } icl_on_observe_s;
 
+static GList *icl_cru_cb_list = NULL;
+static GList *icl_delete_cb_list = NULL;
+
+void icl_remote_resource_crud_stop(iotcon_remote_resource_h resource)
+{
+       GList *c;
+       for (c = icl_cru_cb_list; c; c = c->next) {
+               icl_on_cru_s *cb_container = c->data;
+               if (NULL == cb_container) {
+                       ERR("cb_container is NULL");
+                       continue;
+               }
+               if (cb_container->resource == resource)
+                       cb_container->cb = NULL;
+       }
+
+       for (c = icl_delete_cb_list; c; c = c->next) {
+               icl_on_delete_s *cb_container = c->data;
+               if (NULL == cb_container) {
+                       ERR("cb_container is NULL");
+                       continue;
+               }
+               if (cb_container->resource == resource)
+                       cb_container->cb = NULL;
+       }
+}
+
 
 static void _icl_on_cru_cb(GVariant *result, icl_on_cru_s *cb_container)
 {
@@ -62,10 +89,13 @@ static void _icl_on_cru_cb(GVariant *result, icl_on_cru_s *cb_container)
 
        g_variant_get(result, "(a(qs)vi)", &options, &repr_gvar, &res);
 
+       icl_cru_cb_list = g_list_remove(icl_cru_cb_list, cb_container);
+
        if (IOTCON_ERROR_NONE == res && g_variant_iter_n_children(options)) {
                ret = iotcon_options_create(&header_options);
                if (IOTCON_ERROR_NONE != ret) {
                        ERR("iotcon_options_create() Fail(%d)", ret);
+                       free(cb_container);
                        return;
                }
 
@@ -79,8 +109,6 @@ static void _icl_on_cru_cb(GVariant *result, icl_on_cru_s *cb_container)
                ERR("icl_representation_from_gvariant() Fail");
                if (header_options)
                        iotcon_options_destroy(header_options);
-
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return;
        }
@@ -96,7 +124,6 @@ static void _icl_on_cru_cb(GVariant *result, icl_on_cru_s *cb_container)
        if (header_options)
                iotcon_options_destroy(header_options);
 
-       iotcon_remote_resource_destroy(cb_container->resource);
        free(cb_container);
 }
 
@@ -112,7 +139,6 @@ static void _icl_on_get_cb(GObject *object, GAsyncResult *g_async_res,
        if (error) {
                ERR("ic_dbus_call_get_finish() Fail(%s)", error->message);
                g_error_free(error);
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return;
        }
@@ -132,7 +158,6 @@ static void _icl_on_put_cb(GObject *object, GAsyncResult *g_async_res,
        if (error) {
                ERR("ic_dbus_call_put_finish() Fail(%s)", error->message);
                g_error_free(error);
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return;
        }
@@ -152,7 +177,6 @@ static void _icl_on_post_cb(GObject *object, GAsyncResult *g_async_res,
        if (error) {
                ERR("ic_dbus_call_post_finish() Fail(%s)", error->message);
                g_error_free(error);
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return;
        }
@@ -164,7 +188,6 @@ static void _icl_on_post_cb(GObject *object, GAsyncResult *g_async_res,
 API int iotcon_remote_resource_get(iotcon_remote_resource_h resource,
                iotcon_query_h query, iotcon_remote_resource_cru_cb cb, void *user_data)
 {
-       int ret;
        GVariant *arg_query;
        GVariant *arg_remote_resource;
        icl_on_cru_s *cb_container;
@@ -179,13 +202,7 @@ API int iotcon_remote_resource_get(iotcon_remote_resource_h resource,
                return IOTCON_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = iotcon_remote_resource_ref(resource, &cb_container->resource);
-       if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon_remote_resource_ref() Fail");
-               free(cb_container);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
+       cb_container->resource = resource;
        cb_container->cb = cb;
        cb_container->user_data = user_data;
 
@@ -195,6 +212,8 @@ API int iotcon_remote_resource_get(iotcon_remote_resource_h resource,
        ic_dbus_call_get(icl_dbus_get_object(), arg_remote_resource, arg_query, NULL,
                        _icl_on_get_cb, cb_container);
 
+       icl_cru_cb_list = g_list_append(icl_cru_cb_list, cb_container);
+
        return IOTCON_ERROR_NONE;
 }
 
@@ -205,7 +224,6 @@ API int iotcon_remote_resource_put(iotcon_remote_resource_h resource,
                iotcon_remote_resource_cru_cb cb,
                void *user_data)
 {
-       int ret;
        GVariant *arg_repr;
        GVariant *arg_remote_resource;
        GVariant *arg_query;
@@ -222,20 +240,13 @@ API int iotcon_remote_resource_put(iotcon_remote_resource_h resource,
                return IOTCON_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = iotcon_remote_resource_ref(resource, &cb_container->resource);
-       if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon_remote_resource_ref() Fail");
-               free(cb_container);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
+       cb_container->resource = resource;
        cb_container->cb = cb;
        cb_container->user_data = user_data;
 
        arg_repr = icl_representation_to_gvariant(repr);
        if (NULL == arg_repr) {
                ERR("icl_representation_to_gvariant() Fail");
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return IOTCON_ERROR_REPRESENTATION;
        }
@@ -246,6 +257,8 @@ API int iotcon_remote_resource_put(iotcon_remote_resource_h resource,
        ic_dbus_call_put(icl_dbus_get_object(), arg_remote_resource, arg_repr, arg_query,
                        NULL, _icl_on_put_cb, cb_container);
 
+       icl_cru_cb_list = g_list_append(icl_cru_cb_list, cb_container);
+
        return IOTCON_ERROR_NONE;
 }
 
@@ -256,7 +269,6 @@ API int iotcon_remote_resource_post(iotcon_remote_resource_h resource,
                iotcon_remote_resource_cru_cb cb,
                void *user_data)
 {
-       int ret;
        GVariant *arg_repr;
        GVariant *arg_query;
        GVariant *arg_remote_resource;
@@ -273,20 +285,13 @@ API int iotcon_remote_resource_post(iotcon_remote_resource_h resource,
                return IOTCON_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = iotcon_remote_resource_ref(resource, &cb_container->resource);
-       if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon_remote_resource_ref() Fail");
-               free(cb_container);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
+       cb_container->resource = resource;
        cb_container->cb = cb;
        cb_container->user_data = user_data;
 
        arg_repr = icl_representation_to_gvariant(repr);
        if (NULL == arg_repr) {
                ERR("icl_representation_to_gvariant() Fail");
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return IOTCON_ERROR_REPRESENTATION;
        }
@@ -297,6 +302,8 @@ API int iotcon_remote_resource_post(iotcon_remote_resource_h resource,
        ic_dbus_call_post(icl_dbus_get_object(), arg_remote_resource, arg_repr, arg_query,
                        NULL, _icl_on_post_cb, cb_container);
 
+       icl_cru_cb_list = g_list_append(icl_cru_cb_list, cb_container);
+
        return IOTCON_ERROR_NONE;
 }
 
@@ -315,11 +322,12 @@ static void _icl_on_delete_cb(GObject *object, GAsyncResult *g_async_res,
        icl_on_delete_s *cb_container = user_data;
        iotcon_remote_resource_delete_cb cb = cb_container->cb;
 
+       icl_delete_cb_list = g_list_remove(icl_delete_cb_list, cb_container);
+
        ic_dbus_call_delete_finish(IC_DBUS(object), &result, g_async_res, &error);
        if (error) {
                ERR("ic_dbus_call_delete_finish() Fail(%s)", error->message);
                g_error_free(error);
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return;
        }
@@ -330,7 +338,6 @@ static void _icl_on_delete_cb(GObject *object, GAsyncResult *g_async_res,
                if (IOTCON_ERROR_NONE != ret) {
                        ERR("iotcon_options_create() Fail(%d)", ret);
                        g_variant_iter_free(options);
-                       iotcon_remote_resource_destroy(cb_container->resource);
                        free(cb_container);
                        return;
                }
@@ -348,7 +355,6 @@ static void _icl_on_delete_cb(GObject *object, GAsyncResult *g_async_res,
        if (header_options)
                iotcon_options_destroy(header_options);
 
-       iotcon_remote_resource_destroy(cb_container->resource);
        free(cb_container);
 }
 
@@ -356,7 +362,6 @@ static void _icl_on_delete_cb(GObject *object, GAsyncResult *g_async_res,
 API int iotcon_remote_resource_delete(iotcon_remote_resource_h resource,
                iotcon_remote_resource_delete_cb cb, void *user_data)
 {
-       int ret;
        GVariant *arg_remote_resource;
        icl_on_delete_s *cb_container;
 
@@ -370,13 +375,7 @@ API int iotcon_remote_resource_delete(iotcon_remote_resource_h resource,
                return IOTCON_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = iotcon_remote_resource_ref(resource, &cb_container->resource);
-       if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon_remote_resource_ref() Fail");
-               free(cb_container);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
+       cb_container->resource = resource;
        cb_container->cb = cb;
        cb_container->user_data = user_data;
 
@@ -385,6 +384,8 @@ API int iotcon_remote_resource_delete(iotcon_remote_resource_h resource,
        ic_dbus_call_delete(icl_dbus_get_object(), arg_remote_resource, NULL,
                        _icl_on_delete_cb, cb_container);
 
+       icl_delete_cb_list = g_list_append(icl_delete_cb_list, cb_container);
+
        return IOTCON_ERROR_NONE;
 }
 
@@ -417,7 +418,6 @@ static void _icl_on_observe_cb(GDBusConnection *connection,
                if (IOTCON_ERROR_NONE != ret) {
                        ERR("iotcon_options_create() Fail(%d)", ret);
                        g_variant_iter_free(options);
-                       iotcon_remote_resource_destroy(cb_container->resource);
                        free(cb_container);
                        return;
                }
@@ -433,7 +433,6 @@ static void _icl_on_observe_cb(GDBusConnection *connection,
                if (header_options)
                        iotcon_options_destroy(header_options);
 
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return;
        }
@@ -455,7 +454,6 @@ static void _icl_observe_conn_cleanup(icl_on_observe_s *cb_container)
 {
        cb_container->resource->observe_handle = 0;
        cb_container->resource->observe_sub_id = 0;
-       iotcon_remote_resource_destroy(cb_container->resource);
        free(cb_container);
 }
 
@@ -478,6 +476,7 @@ API int iotcon_remote_resource_observer_start(iotcon_remote_resource_h resource,
        RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
        RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
        RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
+       RETV_IF(resource->observe_handle || resource->observe_sub_id, IOTCON_ERROR_ALREADY);
 
        signal_number = icl_dbus_generate_signal_number();
 
@@ -509,13 +508,7 @@ API int iotcon_remote_resource_observer_start(iotcon_remote_resource_h resource,
                return IOTCON_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = iotcon_remote_resource_ref(resource, &cb_container->resource);
-       if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon_remote_resource_ref() Fail");
-               free(cb_container);
-               return IOTCON_ERROR_OUT_OF_MEMORY;
-       }
-
+       cb_container->resource = resource;
        cb_container->cb = cb;
        cb_container->user_data = user_data;
 
@@ -523,7 +516,6 @@ API int iotcon_remote_resource_observer_start(iotcon_remote_resource_h resource,
                        _icl_observe_conn_cleanup, _icl_on_observe_cb);
        if (0 == sub_id) {
                ERR("icl_dbus_subscribe_signal() Fail");
-               iotcon_remote_resource_destroy(cb_container->resource);
                free(cb_container);
                return IOTCON_ERROR_DBUS;
        }
index 24d22c2..4b7c68e 100644 (file)
@@ -162,8 +162,6 @@ API int iotcon_remote_resource_create(const char *host,
        resource->types = icl_resource_types_ref(resource_types);
        resource->ifaces = resource_ifs;
 
-       resource->ref_count = 1;
-
        *resource_handle = resource;
 
        return IOTCON_ERROR_NONE;
@@ -174,10 +172,10 @@ API void iotcon_remote_resource_destroy(iotcon_remote_resource_h resource)
 {
        RET_IF(NULL == resource);
 
-       resource->ref_count--;
+       if (resource->observe_handle)
+               iotcon_remote_resource_observer_stop(resource);
 
-       if (0 < resource->ref_count)
-               return;
+       icl_remote_resource_crud_stop(resource);
 
        free(resource->uri_path);
        free(resource->host);
@@ -191,15 +189,73 @@ API void iotcon_remote_resource_destroy(iotcon_remote_resource_h resource)
        free(resource);
 }
 
+static int _icl_remote_resource_header_foreach_cb(unsigned short id,
+               const char *data, void *user_data)
+{
+       int ret;
+       iotcon_remote_resource_h resource = user_data;
+
+       RETV_IF(NULL == resource, IOTCON_FUNC_STOP);
+
+       if (NULL == resource->header_options) {
+               ret = iotcon_options_create(&resource->header_options);
+               if (IOTCON_ERROR_NONE != ret) {
+                       ERR("resource->header_options() Fail(%d)", ret);
+                       return IOTCON_FUNC_STOP;
+               }
+       }
 
-API int iotcon_remote_resource_ref(iotcon_remote_resource_h src, iotcon_remote_resource_h *dest)
+       ret = iotcon_options_insert(resource->header_options, id, data);
+       if (IOTCON_ERROR_NONE != ret) {
+               ERR("iotcon_options_insert() Fail(%d)", ret);
+               return IOTCON_FUNC_STOP;
+       }
+
+       return IOTCON_FUNC_CONTINUE;
+}
+
+API int iotcon_remote_resource_clone(iotcon_remote_resource_h src, iotcon_remote_resource_h *dest)
 {
+       int ret;
+       iotcon_remote_resource_h resource = NULL;
+
        RETV_IF(NULL == src, IOTCON_ERROR_INVALID_PARAMETER);
-       RETV_IF(src->ref_count <= 0, IOTCON_ERROR_INVALID_PARAMETER);
 
-       src->ref_count++;
+       resource = calloc(1, sizeof(struct icl_remote_resource));
+       if (NULL == resource) {
+               ERR("calloc() Fail(%d)", errno);
+               return IOTCON_ERROR_OUT_OF_MEMORY;
+       }
+
+       resource->uri_path = ic_utils_strdup(src->uri_path);
+       resource->host = ic_utils_strdup(src->host);
+       resource->device_id = ic_utils_strdup(src->device_id);
+       resource->is_secure = src->is_secure;
+       resource->is_observable = src->is_observable;
+
+       if (src->header_options) {
+               ret = iotcon_options_foreach(src->header_options,
+                               _icl_remote_resource_header_foreach_cb, resource);
+               if (IOTCON_ERROR_NONE != ret) {
+                       ERR("iotcon_options_foreach() Fail(%d)", ret);
+                       iotcon_remote_resource_destroy(resource);
+                       return ret;
+               }
+       }
+
+       if (src->types) {
+               ret = iotcon_resource_types_clone(src->types, &resource->types);
+               if (IOTCON_ERROR_NONE != ret) {
+                       ERR("iotcon_resource_types_clone() Fail(%d)", ret);
+                       iotcon_remote_resource_destroy(resource);
+                       return ret;
+               }
+       }
+
+       resource->ifaces = src->ifaces;
+       resource->conn_type = src->conn_type;
 
-       *dest = src;
+       *dest = resource;
 
        return IOTCON_ERROR_NONE;
 }
@@ -334,7 +390,6 @@ static iotcon_remote_resource_h _icl_remote_resource_from_gvariant(GVariant *pay
                ERR("iotcon_remote_resource_create() Fail");
                return NULL;
        }
-       resource->ref_count = 1;
 
        resource->device_id = strdup(device_id);
        if (NULL == resource->device_id) {
index f9b1507..f14c363 100644 (file)
@@ -21,7 +21,6 @@
 #include "icl-options.h"
 
 struct icl_remote_resource {
-       int ref_count;
        char *uri_path;
        char *host;
        char *device_id;
@@ -35,4 +34,7 @@ struct icl_remote_resource {
        unsigned int observe_sub_id;
 };
 
+void icl_remote_resource_crud_stop(iotcon_remote_resource_h resource);
+
+
 #endif /* __IOT_CONNECTIVITY_MANAGER_LIBRARY_CLIENT_H__ */
index db9fc4f..637ea88 100644 (file)
@@ -654,7 +654,7 @@ int iotcon_find_resource(const char *host_address, const char *resource_type,
  * @retval #IOTCON_ERROR_OUT_OF_MEMORY  Out of memory
  *
  * @see iotcon_remote_resource_destroy()
- * @see iotcon_remote_resource_ref()
+ * @see iotcon_remote_resource_clone()
  */
 int iotcon_remote_resource_create(const char *host,
                const char *uri_path,
@@ -675,17 +675,17 @@ int iotcon_remote_resource_create(const char *host,
  * @return void
  *
  * @see iotcon_remote_resource_create()
- * @see iotcon_remote_resource_ref()
+ * @see iotcon_remote_resource_clone()
  */
 void iotcon_remote_resource_destroy(iotcon_remote_resource_h resource);
 
 /**
- * @brief Increments reference count of the source resource.
+ * @brief Makes a clone of a remote resource.
  *
  * @since_tizen 3.0
  *
  * @param[in] src The Source of resource
- * @param[out] dest The referenced resource handle
+ * @param[out] dest The cloned resource handle
  *
  * @return 0 on success, otherwise a negative error value.
  * @retval #IOTCON_ERROR_NONE  Successful
@@ -694,7 +694,7 @@ void iotcon_remote_resource_destroy(iotcon_remote_resource_h resource);
  * @see iotcon_remote_resource_create()
  * @see iotcon_remote_resource_destroy()
  */
-int iotcon_remote_resource_ref(iotcon_remote_resource_h src, iotcon_remote_resource_h *dest);
+int iotcon_remote_resource_clone(iotcon_remote_resource_h src, iotcon_remote_resource_h *dest);
 
 /**
  * @brief Specifies the type of function passed to iotcon_remote_resource_observer_start().
index e015e50..d3ad77c 100644 (file)
@@ -37,8 +37,10 @@ static void _on_observe(iotcon_remote_resource_h resource,
        static int i = 0;
        i++;
 
-       if (2 == i)
+       if (2 == i) {
                iotcon_remote_resource_observer_stop(resource);
+               iotcon_remote_resource_destroy(resource);
+       }
 }
 
 static void _on_delete(iotcon_remote_resource_h resource, iotcon_options_h header_options,
@@ -59,7 +61,7 @@ static void _on_delete(iotcon_remote_resource_h resource, iotcon_options_h heade
        if (IOTCON_ERROR_NONE != ret)
                ERR("iotcon_remote_resource_observer_start() Fail(%d)", ret);
 
-       iotcon_remote_resource_destroy(door_resource);
+       iotcon_remote_resource_destroy(resource);
 }
 
 static void _on_post(iotcon_remote_resource_h resource, iotcon_representation_h recv_repr,
@@ -114,9 +116,9 @@ static void _on_post(iotcon_remote_resource_h resource, iotcon_representation_h
                return;
        }
 
-       ret = iotcon_remote_resource_ref(resource, &door_resource);
+       ret = iotcon_remote_resource_clone(resource, &door_resource);
        if (IOTCON_ERROR_NONE != ret) {
-               ERR("iotcon_remote_resource_ref() Fail(%d)", ret);
+               ERR("iotcon_remote_resource_clone() Fail(%d)", ret);
                iotcon_remote_resource_destroy(new_door_resource);
                return;
        }
@@ -129,7 +131,7 @@ static void _on_post(iotcon_remote_resource_h resource, iotcon_representation_h
                return;
        }
 
-       iotcon_remote_resource_destroy(new_door_resource);
+       iotcon_remote_resource_destroy(resource);
 }
 
 static void _on_put(iotcon_remote_resource_h resource, iotcon_representation_h recv_repr,
@@ -281,6 +283,7 @@ static void _found_resource(iotcon_remote_resource_h resource, void *user_data)
        int ret, resource_interfaces;
        iotcon_presence_h presence_handle;
        iotcon_resource_types_h resource_types;
+       iotcon_remote_resource_h resource_clone = NULL;
 
        if (NULL == resource)
                return;
@@ -401,8 +404,17 @@ static void _found_resource(iotcon_remote_resource_h resource, void *user_data)
                        return;
                }
 
+               ret = iotcon_remote_resource_clone(resource, &resource_clone);
+               if (IOTCON_ERROR_NONE != ret) {
+                       ERR("iotcon_remote_resource_clone() Fail(%d)", ret);
+                       iotcon_query_destroy(query);
+                       device_id_list = g_list_remove(device_id_list, door_resource_device_id);
+                       free(door_resource_device_id);
+                       return;
+               }
+
                /* send GET Request */
-               ret = iotcon_remote_resource_get(resource, query, _on_get, NULL);
+               ret = iotcon_remote_resource_get(resource_clone, query, _on_get, NULL);
                if (IOTCON_ERROR_NONE != ret)
                        ERR("iotcon_remote_resource_get() Fail(%d)", ret);