Change Account GDBusProxy instance to not support singleton 26/82726/1 accepted/tizen/common/20160808.121205 accepted/tizen/common/20160808.121225 accepted/tizen/ivi/20160808.081258 accepted/tizen/mobile/20160808.081224 accepted/tizen/wearable/20160808.081245 submit/tizen/20160808.042100
authorManasij Sur Roy <manasij.r@samsung.com>
Fri, 5 Aug 2016 09:12:18 +0000 (14:42 +0530)
committerManasij Sur Roy <manasij.r@samsung.com>
Fri, 5 Aug 2016 09:12:55 +0000 (14:42 +0530)
Change-Id: Ib668bcfd26decc8e739ad644e6755fc3036a46c0
Signed-off-by: Manasij Sur Roy <manasij.r@samsung.com>
src/account.c

index a93c1ba..a691bd6 100644 (file)
@@ -24,6 +24,7 @@
 #include <gio/gunixfdlist.h>
 #include <unistd.h>
 #endif
+#include <pthread.h>
 #include <vconf.h>
 
 #include <dbg.h>
 
 #define VCONF_OK 0
 
+static GDBusConnection *_connection = NULL;
 static AccountManager *_acc_mgr = NULL;
+static int _instance_count = 0;
+static pthread_mutex_t _account_proxy_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void _account_manager_increase_count()
+{
+       _instance_count++;
+}
+
+static void _account_manager_decrease_count()
+{
+       _instance_count--;
+}
+
+static void _account_manager_destroy_instance()
+{
+       g_object_unref(_connection);
+       _connection = NULL;
+       g_object_unref(_acc_mgr);
+       _acc_mgr = NULL;
+}
+
+static void _account_manager_release_instance()
+{
+       pthread_mutex_lock(&_account_proxy_instance_mutex);
+       _account_manager_decrease_count();
+
+       if (_instance_count <= 0)
+               _account_manager_destroy_instance();
+       pthread_mutex_unlock(&_account_proxy_instance_mutex);
+}
 
 static char *_account_get_text(const char *text_data)
 {
@@ -60,12 +92,15 @@ static char *_account_get_text(const char *text_data)
        return text_value;
 }
 
-AccountManager *
+static AccountManager *
 _account_manager_get_instance()
 {
        _INFO("_account_manager_get_instance");
+       pthread_mutex_lock(&_account_proxy_instance_mutex);
        if (_acc_mgr != NULL) {
                _INFO("instance already created.");
+               _account_manager_increase_count();
+               pthread_mutex_unlock(&_account_proxy_instance_mutex);
                return _acc_mgr;
        }
 
@@ -73,18 +108,18 @@ _account_manager_get_instance()
        g_type_init();
 #endif
 
-       GDBusConnection *connection = NULL;
        GError *error = NULL;
 
-       connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       _connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
 
        _INFO("after g_bus_get_sync");
 
-       if (!connection) {
+       if (!_connection) {
                if (error) {
                        _ERR("Unable to connect to gdbus: %s", error->message);
                        g_clear_error(&error);
                }
+               pthread_mutex_unlock(&_account_proxy_instance_mutex);
                return NULL;
        }
 
@@ -92,7 +127,7 @@ _account_manager_get_instance()
 
        /* Create the object */
        _acc_mgr =
-               account_manager_proxy_new_sync(connection,
+               account_manager_proxy_new_sync(_connection,
                                                                                 G_DBUS_PROXY_FLAGS_NONE,
                                                                                 "org.tizen.account.manager",
                                                                                "/org/tizen/account/manager",
@@ -104,13 +139,19 @@ _account_manager_get_instance()
                        _ERR("Unable account_manager_proxy_new_sync: %s", error->message);
                        g_clear_error(&error);
                }
-               if (connection)
-                       g_object_unref(connection);
+               if (_connection) {
+                       g_object_unref(_connection);
+                       _connection = NULL;
+               }
+               pthread_mutex_unlock(&_account_proxy_instance_mutex);
                return NULL;
        }
 
        g_clear_error(&error);
+
+       _account_manager_increase_count();
        _INFO("_account_manager_get_instance end");
+       pthread_mutex_unlock(&_account_proxy_instance_mutex);
        return _acc_mgr;
 }
 
@@ -203,6 +244,7 @@ ACCOUNT_API int account_insert_to_db(account_h account, int *account_db_id)
 
        _INFO("3. Before account_manager_call_account_add_sync");
        bool is_success = account_manager_call_account_add_sync(acc_mgr, account_serialized, (int)getuid(), &db_id, NULL, &error);
+       _account_manager_release_instance();
 
        ACCOUNT_CATCH_ERROR((is_success != false), {}, _account_get_error_code(is_success, error), "Failed to get dbus.");
        g_clear_error(&error);
@@ -217,7 +259,6 @@ ACCOUNT_API int account_insert_to_db(account_h account, int *account_db_id)
 CATCH:
        g_clear_error(&error);
        _ERR("account_manager_call_account_add_sync()=[%d]", error_code);
-
        return error_code;
 }
 
@@ -244,12 +285,14 @@ ACCOUNT_API int account_delete_from_db_by_id(int account_db_id)
                error_code = _account_get_error_code(is_success, error);
                g_clear_error(&error);
                _ERR("account_manager_call_account_query_account_by_account_id_sync failed [%d]", error_code);
+               _account_manager_release_instance();
                return error_code;
        }
        g_clear_error(&error);
 
        _INFO("3. Before account_manager_call_account_delete_from_db_by_id_sync");
        is_success = account_manager_call_account_delete_from_db_by_id_sync(acc_mgr, account_db_id, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        if (!is_success) {
                error_code = _account_get_error_code(is_success, error);
@@ -286,6 +329,7 @@ ACCOUNT_API int account_delete_from_db_by_user_name(char *user_name, char *packa
        error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
        if (error_code != ACCOUNT_ERROR_NONE) {
+               _account_manager_release_instance();
                _ERR("account_query_account_by_user_name error=[%d]", error_code);
                return error_code;
        }
@@ -293,10 +337,13 @@ ACCOUNT_API int account_delete_from_db_by_user_name(char *user_name, char *packa
        GSList *account_list = unmarshal_account_list(account_list_variant);
        g_variant_unref(account_list_variant);
 
-       if (account_list == NULL)
+       if (account_list == NULL) {
+               _account_manager_release_instance();
                return ACCOUNT_ERROR_NO_DATA;
+       }
 
        is_success = account_manager_call_account_delete_from_db_by_user_name_sync(acc_mgr, user_name, package_name, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        if (!is_success) {
                error_code = _account_get_error_code(is_success, error);
@@ -333,6 +380,7 @@ int _account_delete_from_db_by_package_name(const char *package_name, bool permi
        error_code = _account_get_error_code(is_success, error);
        if (error_code != ACCOUNT_ERROR_NONE)
        {
+               _account_manager_release_instance();
                return error_code;
        }
 
@@ -341,10 +389,12 @@ int _account_delete_from_db_by_package_name(const char *package_name, bool permi
        _INFO("after unmarshal_account_list");
        if (account_list == NULL)
        {
+               _account_manager_release_instance();
                return ACCOUNT_ERROR_NO_DATA;
        }
 */
        bool is_success = account_manager_call_account_delete_from_db_by_package_name_sync(acc_mgr, package_name, permission, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        if (!is_success) {
                error_code = _account_get_error_code(is_success, error);
@@ -386,6 +436,7 @@ ACCOUNT_API int account_update_to_db_by_id(account_h account, int account_id)
        if (!is_success) {
                error_code = _account_get_error_code(is_success, error);
                g_clear_error(&error);
+               _account_manager_release_instance();
                _ERR("account_manager_call_account_query_account_by_account_id_sync failed [%d]", error_code);
                return error_code;
        }
@@ -394,6 +445,7 @@ ACCOUNT_API int account_update_to_db_by_id(account_h account, int account_id)
        _INFO("3. Before account_manager_call_account_update_to_db_by_id_sync");
        GVariant *account_serialized = marshal_account((account_s *)account);
        is_success = account_manager_call_account_update_to_db_by_id_sync(acc_mgr, account_serialized, account_id, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        if (!is_success) {
                error_code = _account_get_error_code(is_success, error);
@@ -439,6 +491,7 @@ ACCOUNT_INTERNAL_API int account_update_to_db_by_id_without_permission(account_h
                error_code = _account_get_error_code(is_success, error);
                g_clear_error(&error);
                _ERR("account_manager_call_account_query_account_by_account_id_sync failed [%d]", error_code);
+               _account_manager_release_instance();
                return error_code;
        }
        g_clear_error(&error);
@@ -448,6 +501,7 @@ ACCOUNT_INTERNAL_API int account_update_to_db_by_id_without_permission(account_h
        _INFO("after marshal() : account_id[%d]", account_id);
        if (account_serialized == NULL) {
                _ERR("Invalid input");
+               _account_manager_release_instance();
                return ACCOUNT_ERROR_INVALID_PARAMETER;
        }
 
@@ -455,6 +509,8 @@ ACCOUNT_INTERNAL_API int account_update_to_db_by_id_without_permission(account_h
        is_success = account_manager_call_account_update_to_db_by_id_ex_sync(acc_mgr, account_serialized, account_id, (int)getuid(), NULL, &error);
 
        _INFO("after call update() : is_success=%d", is_success);
+       _account_manager_release_instance();
+
        if (!is_success) {
                error_code = _account_get_error_code(is_success, error);
                g_clear_error(&error);
@@ -490,6 +546,7 @@ ACCOUNT_API int account_update_to_db_by_user_name(account_h account, const char
        if (!is_success) {
                error_code = _account_get_error_code(is_success, error);
                g_clear_error(&error);
+               _account_manager_release_instance();
                _ERR("account_manager_call_account_query_account_by_account_id_sync failed [%d]", error_code);
                return error_code;
        }
@@ -497,6 +554,7 @@ ACCOUNT_API int account_update_to_db_by_user_name(account_h account, const char
 
        GVariant *account_serialized = marshal_account(account_data);
        is_success = account_manager_call_account_update_to_db_by_user_name_sync(acc_mgr, account_serialized, user_name, package_name, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        if (!is_success) {
                error_code = _account_get_error_code(is_success, error);
@@ -1345,6 +1403,7 @@ ACCOUNT_API int account_foreach_account_from_db(account_cb callback, void *user_
 
        GVariant *account_list_variant = NULL;
        bool is_success = account_manager_call_account_query_all_sync(acc_mgr, (int)getuid(), &account_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -1394,6 +1453,7 @@ ACCOUNT_API int account_query_account_by_account_id(int account_db_id, account_h
 
        GVariant *account_variant = NULL;
        bool is_success = account_manager_call_account_query_account_by_account_id_sync(acc_mgr, account_db_id, (int)getuid(), &account_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -1438,6 +1498,7 @@ ACCOUNT_API int account_query_account_by_user_name(account_cb callback, const ch
 
        GVariant *account_list_variant = NULL;
        bool is_success = account_manager_call_account_query_account_by_user_name_sync(acc_mgr, user_name, (int)getuid(), &account_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -1484,6 +1545,7 @@ ACCOUNT_API int account_query_account_by_package_name(account_cb callback, const
 
        GVariant *account_list_variant = NULL;
        bool is_success = account_manager_call_account_query_account_by_package_name_sync(acc_mgr, package_name, (int)getuid(), &account_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -1536,6 +1598,7 @@ ACCOUNT_API int account_query_account_by_capability(account_cb callback, const c
 
        GVariant *account_list_variant = NULL;
        bool is_success = account_manager_call_account_query_account_by_capability_sync(acc_mgr, capability_type, capability_value, (int)getuid(), &account_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -1581,6 +1644,7 @@ ACCOUNT_API int account_query_account_by_capability_type(account_cb callback, co
 
        GVariant *account_list_variant = NULL;
        bool is_success = account_manager_call_account_query_account_by_capability_type_sync(acc_mgr, capability_type, (int)getuid(), &account_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -1626,6 +1690,7 @@ ACCOUNT_API int account_query_capability_by_account_id(capability_cb callback, i
 
        GVariant *capability_list_variant = NULL;
        bool is_success = account_manager_call_account_query_capability_by_account_id_sync(acc_mgr, account_id, (int)getuid(), &capability_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -1679,6 +1744,8 @@ static int _account_get_total_count(int *count, bool include_hidden)
 
        int temp_count = -1;
        bool is_success = account_manager_call_account_get_total_count_from_db_sync(acc_mgr, include_hidden, (int)getuid(), &temp_count, NULL, &error);
+       _account_manager_release_instance();
+
        int error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
        if (error_code != ACCOUNT_ERROR_NONE)
@@ -1723,6 +1790,7 @@ ACCOUNT_API int account_update_sync_status_by_id(int account_db_id, const accoun
        }
 
        bool is_success = account_manager_call_account_update_sync_status_by_id_sync(acc_mgr, account_db_id, sync_status, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -1970,6 +2038,7 @@ ACCOUNT_API int account_type_query_provider_feature_by_app_id(provider_feature_c
 
        GVariant *feature_list_variant = NULL;
        bool is_success = account_manager_call_account_type_query_provider_feature_by_app_id_sync(acc_mgr, app_id, (int)getuid(), &feature_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        _INFO("account_manager_call_account_type_query_provider_feature_by_app_id_sync end=[%d]", is_success);
 
@@ -2026,6 +2095,7 @@ ACCOUNT_API bool account_type_query_supported_feature(const char *app_id, const
        }
 
        bool is_success = account_manager_call_account_type_query_supported_feature_sync(acc_mgr, app_id, capability, (int)getuid(), &is_supported, NULL, &error);
+       _account_manager_release_instance();
 
        _INFO("account_manager_call_account_type_query_supported_feature_sync end=[%d]", is_success);
 
@@ -2268,6 +2338,7 @@ ACCOUNT_INTERNAL_API int account_type_insert_to_db(account_type_h account_type,
        int db_id = -1;
        GVariant *account_type_serialized = marshal_account_type((account_type_s *)account_type);
        bool is_success = account_manager_call_account_type_add_sync(acc_mgr, account_type_serialized, (int)getuid(), &db_id, NULL, &error);
+       _account_manager_release_instance();
 
        int ret = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -2304,10 +2375,12 @@ ACCOUNT_INTERNAL_API int account_type_update_to_db_by_app_id(const account_type_
        GVariant *account_type_variant = marshal_account_type((account_type_s *)account_type);
        if (account_type_variant == NULL) {
                _ERR("Failed to serialize");
+               _account_manager_release_instance();
                return ACCOUNT_ERROR_INVALID_PARAMETER;
        }
 
        bool is_success = account_manager_call_account_type_update_to_db_by_app_id_sync(acc_mgr, account_type_variant, app_id, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -2331,6 +2404,7 @@ ACCOUNT_INTERNAL_API int account_type_delete_by_app_id(const char *app_id)
        }
 
        bool is_success = account_manager_call_account_type_delete_by_app_id_sync(acc_mgr, app_id, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -2355,6 +2429,7 @@ ACCOUNT_API int account_type_query_label_by_app_id(account_label_cb callback, co
 
        GVariant *label_list_variant = NULL;
        bool is_success = account_manager_call_account_type_query_label_by_app_id_sync(acc_mgr, app_id, (int)getuid(), &label_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int ret = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -2403,6 +2478,7 @@ ACCOUNT_API int account_type_query_by_app_id(const char *app_id, account_type_h
        account_type_s *in_data = (account_type_s *)*account_type;
 
        bool is_success = account_manager_call_account_type_query_by_app_id_sync(acc_mgr, app_id, (int)getuid(), &account_type_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int ret = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -2445,6 +2521,7 @@ ACCOUNT_API int account_type_foreach_account_type_from_db(account_type_cb callba
        GVariant *account_type_list_variant = NULL;
        _INFO("before account_type_query_all_sync()");
        bool is_success = account_manager_call_account_type_query_all_sync(acc_mgr, (int)getuid(), &account_type_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        _INFO("after account_type_query_all_sync()");
        int ret = _account_get_error_code(is_success, error);
@@ -2496,6 +2573,7 @@ ACCOUNT_API int account_type_query_label_by_locale(const char *app_id, const cha
        char *label_temp = NULL;
        _INFO("before account_type_query_label_by_locale_sync()");
        bool is_success = account_manager_call_account_type_query_label_by_locale_sync(acc_mgr, app_id, locale, (int)getuid(), &label_temp, NULL, &error);
+       _account_manager_release_instance();
 
        _INFO("after account_type_query_label_by_locale_sync() : is_success=%d", is_success);
        int ret = _account_get_error_code(is_success, error);
@@ -2536,6 +2614,7 @@ ACCOUNT_API int account_type_query_by_provider_feature(account_type_cb callback,
 
        GVariant *account_type_list_variant = NULL;
        bool is_success = account_manager_call_account_type_query_by_provider_feature_sync(acc_mgr, key, (int)getuid(), &account_type_list_variant, NULL, &error);
+       _account_manager_release_instance();
 
        int ret = _account_get_error_code(is_success, error);
        g_clear_error(&error);
@@ -2585,6 +2664,7 @@ ACCOUNT_API int account_type_query_app_id_exist(const char *app_id)
        }
 
        bool is_success = account_manager_call_account_type_query_app_id_exist_sync(acc_mgr, app_id, (int)getuid(), NULL, &error);
+       _account_manager_release_instance();
 
        error_code = _account_get_error_code(is_success, error);
        g_clear_error(&error);