Call poll() again when it fails with an EAGAIN error
[platform/core/multimedia/mm-resource-manager.git] / src / daemon / mm_resource_manager_daemon_priv.c
index 71298d9..63017a7 100644 (file)
@@ -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;