From: Sangyoon Jang Date: Tue, 8 Jan 2019 04:37:29 +0000 (+0900) Subject: Fix potential race condition problem X-Git-Tag: submit/tizen/20190114.045227~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fapi%2Fpackage-manager.git;a=commitdiff_plain;h=d3ff11ed137b944e0288edb58da8e0275fb26913 Fix potential race condition problem There was a potential race condition because of using global hash table for storing getsize callback information. The getsize can be invoked by multiple thread in same time, so this global hashtable should be removed. Change-Id: I78ff68c085f73031a7fb76ace660cf3c497519f0 Signed-off-by: Sangyoon Jang --- diff --git a/src/package_manager.c b/src/package_manager.c index 83b789e..bce3f8c 100644 --- a/src/package_manager.c +++ b/src/package_manager.c @@ -28,8 +28,6 @@ #include "package_manager.h" #include "package_manager_internal.h" -static GHashTable *__cb_table = NULL; - #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) typedef struct _request_event_info { int req_id; @@ -1532,23 +1530,25 @@ API int package_manager_clear_all_cache_dir(void) return package_manager_clear_cache_dir(PKG_CLEAR_ALL_CACHE); } -static void __free_client(gpointer data) -{ - pkgmgr_client *pc = (pkgmgr_client *)data; - pkgmgr_client_free(pc); -} +struct getsize_cbdata { + pkgmgr_client *pc; + void *cb; + void *user_data; +}; -static void __initialize_cb_table(void) +static void __free_getsize_cbdata(struct getsize_cbdata *cbdata) { - __cb_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, __free_client, NULL); + pkgmgr_client_free(cbdata->pc); + free(cbdata); } static void __result_cb(pkgmgr_client *pc, const char *pkgid, const pkg_size_info_t *result, void *user_data) { - package_manager_size_info_receive_cb callback = g_hash_table_lookup(__cb_table, pc); + struct getsize_cbdata *cbdata = (struct getsize_cbdata *)user_data; + package_manager_size_info_receive_cb callback = cbdata->cb; if (callback == NULL) { _LOGE("callback is null."); - g_hash_table_remove(__cb_table, pc); + __free_getsize_cbdata(cbdata); return; } @@ -1562,15 +1562,16 @@ static void __result_cb(pkgmgr_client *pc, const char *pkgid, const pkg_size_inf callback(pkgid, (package_size_info_h)&size_info, user_data); - g_hash_table_remove(__cb_table, pc); + __free_getsize_cbdata(cbdata); } static void __total_result_cb(pkgmgr_client *pc, const pkg_size_info_t *result, void *user_data) { - package_manager_total_size_info_receive_cb callback = g_hash_table_lookup(__cb_table, pc); + struct getsize_cbdata *cbdata = (struct getsize_cbdata *)user_data; + package_manager_total_size_info_receive_cb callback = cbdata->cb; if (callback == NULL) { _LOGE("callback is null."); - g_hash_table_remove(__cb_table, pc); + __free_getsize_cbdata(cbdata); return; } @@ -1584,26 +1585,35 @@ static void __total_result_cb(pkgmgr_client *pc, const pkg_size_info_t *result, callback((package_size_info_h)&size_info, user_data); - g_hash_table_remove(__cb_table, pc); + __free_getsize_cbdata(cbdata); } static int _get_pkg_size_info(const char *package_id, void *callback, void *user_data) { + struct getsize_cbdata *cbdata; + if (package_id == NULL || callback == NULL) return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - if (__cb_table == NULL) - __initialize_cb_table(); + cbdata = malloc(sizeof(struct getsize_cbdata)); + if (cbdata == NULL) + return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); pkgmgr_client *pc = pkgmgr_client_new(PC_REQUEST); - if (pc == NULL) + if (pc == NULL) { + free(cbdata); return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); + } + + cbdata->pc = pc; + cbdata->cb = callback; + cbdata->user_data = user_data; int res = 0; if (strcmp(package_id, PKG_SIZE_INFO_TOTAL) != 0) - res = pkgmgr_client_get_package_size_info(pc, package_id, __result_cb, user_data); + res = pkgmgr_client_get_package_size_info(pc, package_id, __result_cb, cbdata); else - res = pkgmgr_client_get_total_package_size_info(pc, __total_result_cb, user_data); + res = pkgmgr_client_get_total_package_size_info(pc, __total_result_cb, cbdata); if (res == PKGMGR_R_EINVAL) { pkgmgr_client_free(pc); @@ -1625,12 +1635,10 @@ static int _get_pkg_size_info(const char *package_id, void *callback, void *user return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); } else if (res != PKGMGR_R_OK) { _LOGE("Unexpected error"); - pkgmgr_client_free(pc); + __free_getsize_cbdata(cbdata); return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL); } - g_hash_table_insert(__cb_table, pc, callback); - return PACKAGE_MANAGER_ERROR_NONE; }