From 1cd8896cf725c8f48de10ef0367dc031e9ec8260 Mon Sep 17 00:00:00 2001 From: YoungHun Kim Date: Tue, 28 Apr 2020 07:49:24 +0900 Subject: [PATCH] Call poll() again when it fails with an EAGAIN error - poll() can fail with the error EAGAIN if the system fails to allocate kernel-internal resources. Portable programs may wish to check for EAGAIN and loop. - Change the mode of mm_resource_manager_daemon_priv.c - Update some logs Change-Id: I2ee8f16931b14e57ed065be607b08d9d81f1b4ca --- src/daemon/mm_resource_manager_daemon_dbus.c | 0 src/daemon/mm_resource_manager_daemon_priv.c | 76 +++++++++++++++++----------- src/lib/mm_resource_manager_priv.c | 7 +-- 3 files changed, 48 insertions(+), 35 deletions(-) mode change 100755 => 100644 src/daemon/mm_resource_manager_daemon_dbus.c diff --git a/src/daemon/mm_resource_manager_daemon_dbus.c b/src/daemon/mm_resource_manager_daemon_dbus.c old mode 100755 new mode 100644 diff --git a/src/daemon/mm_resource_manager_daemon_priv.c b/src/daemon/mm_resource_manager_daemon_priv.c index 71298d9..63017a7 100644 --- a/src/daemon/mm_resource_manager_daemon_priv.c +++ b/src/daemon/mm_resource_manager_daemon_priv.c @@ -95,6 +95,7 @@ static void __handle_release_callbacks(GArray *requests); static inline void __add_cb_request(GArray *cb_requests, mm_resource_manager_dmn_p mgr, mm_resource_manager_res_type_e type, mm_resource_manager_res_volume volume); static void __release_all_resources(mm_resource_manager_dmn_s *manager); +static gboolean __poll(struct pollfd sync); static gboolean __wait_for_release_cb_sync(mm_resource_manager_id id); @@ -766,9 +767,38 @@ static void __release_all_resources(mm_resource_manager_dmn_s *manager) } } +static gboolean __poll(struct pollfd sync) +{ + int errsv = 0; + int try_cnt = 0; + int ret = 0; + + while (try_cnt++ < 3) { + sync.events = POLLIN; + sync.revents = 0; + + ret = poll(&sync, 1, RELEASE_CB_SYNC_TIMEOUT * 1000); + + if (ret == -1) { + errsv = errno; + MM_RM_ERROR("Polling is failed [fd %d errno %d]", sync.fd, errsv); + if (errsv == EAGAIN) + continue; + break; + } else if (ret == 0) { + MM_RM_WARNING("Wait timeout is elapsed [fd %d]", sync.fd); + break; + } + + return TRUE; + } + + return FALSE; +} + static gboolean __wait_for_release_cb_sync(mm_resource_manager_id id) { - gboolean ret = TRUE; + gboolean ret = FALSE; struct pollfd sync = {0}; mm_resource_manager_id recv_id; ssize_t read_size; @@ -776,37 +806,23 @@ static gboolean __wait_for_release_cb_sync(mm_resource_manager_id id) sync.fd = open(RELEASE_CB_SYNC_PATH, O_RDONLY | O_NONBLOCK); MM_RM_RETVM_IF(sync.fd == -1, FALSE, "Sync FIFO cannot be opened"); - sync.events = POLLIN; - switch (poll(&sync, 1, RELEASE_CB_SYNC_TIMEOUT * 1000)) { - case -1: - MM_RM_ERROR("Polling is failed"); - ret = FALSE; - break; - case 0: - MM_RM_DEBUG("Wait timeout is elapsed"); - ret = FALSE; - break; - default: - read_size = read(sync.fd, &recv_id, sizeof(recv_id)); - if (read_size == sizeof(recv_id)) { - ret = id == _mm_rm_hash64(recv_id); - if (ret == FALSE) - MM_RM_ERROR("Sync is received from wrong client #%"PRIu64, id); - /* - * Wait POLLHUP to avoid situation when client sent last sync - * through the pipe, but not already closed the pipe handle and - * the daemon is already opened the pipe again and waiting for - * the next sync. - */ - sync.revents = 0; - if (poll(&sync, 1, RELEASE_CB_SYNC_TIMEOUT * 1000) == 0 || (sync.revents & (POLLHUP | POLLERR)) == 0) - MM_RM_ERROR("The client didn't close the FIFO"); - } else { - MM_RM_ERROR("Read is failed (revents=%hd,read_size=%zd)", sync.revents, read_size); - ret = FALSE; - } + if (!__poll(sync)) + goto out; + + read_size = read(sync.fd, &recv_id, sizeof(recv_id)); + if (read_size != sizeof(recv_id)) { + MM_RM_ERROR("Read is failed (revents=%hd, read_size=%zd)", sync.revents, read_size); + goto out; } + if (id != _mm_rm_hash64(recv_id)) { + MM_RM_ERROR("Sync is received from wrong client #%"PRIu64, id); + goto out; + } + + ret = __poll(sync); + +out: close(sync.fd); return ret; diff --git a/src/lib/mm_resource_manager_priv.c b/src/lib/mm_resource_manager_priv.c index 5e43657..6ce9630 100644 --- a/src/lib/mm_resource_manager_priv.c +++ b/src/lib/mm_resource_manager_priv.c @@ -394,7 +394,7 @@ int _mm_resource_manager_get_resource_info(mm_resource_manager_h rm, MM_RM_UNLOCK_RETVM_IF(i == MM_RESOURCE_MANAGER_RES_NOT_FOUND, handle->resources_lock, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, - "Invalid resource handle"); + "Invalid resource handle #%"PRIu64"", _mm_rm_hash64(handle->id)); info->type = resource->type; info->volume = resource->volume; @@ -766,10 +766,7 @@ static int __dbus_init_conf(mm_resource_manager_s *handle) MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION, "Variant data are empty"); if (g_variant_iter_init(&volume_iter, max_volume) == MM_RESOURCE_MANAGER_RES_TYPE_MAX) { - for (i = 0; g_variant_iter_next(&volume_iter, "i", &handle->__max_resource_volumes[i]); i++) { - if (handle->__max_resource_volumes[i] == MM_RESOURCE_MANAGER_NO_RES) - MM_RM_INFO("Maybe occur the error operation related dbus"); - } + for (i = 0; g_variant_iter_next(&volume_iter, "i", &handle->__max_resource_volumes[i]); i++); g_variant_unref(max_volume); max_volume = NULL; } else { -- 2.7.4