]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: (monitor) epoll_wait code consolidation
authorKarel Zak <kzak@redhat.com>
Wed, 28 May 2025 09:18:57 +0000 (11:18 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Aug 2025 12:50:56 +0000 (14:50 +0200)
The epoll_wait() and op_process_event() are called in two places. Move
the code to read_epoll_events() and process everything in one place

Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/monitor.c

index 66319132681eff86e5daeff14ac1c63f7d775552..6272fbdd286dce145891e439a26f28e99e4e2764 100644 (file)
@@ -313,6 +313,55 @@ err:
        return rc;
 }
 
+/* Returns: <0 on error, 0 on success, 1 nothing (timeout) */
+static int read_epoll_events(struct libmnt_monitor *mn, int timeout, struct monitor_entry **act)
+{
+       int rc;
+       struct monitor_entry *me = NULL;
+       struct epoll_event events[1];
+
+       if (act)
+               *act = NULL;
+
+       do {
+               DBG(MONITOR, ul_debugobj(mn, "calling epoll_wait(), timeout=%d", timeout));
+               rc = epoll_wait(mn->fd, events, 1, timeout);
+               if (rc < 0) {
+                       rc = -errno;
+                       goto failed;
+               }
+               if (rc == 0)
+                       goto nothing;           /* timeout */
+
+               me = (struct monitor_entry *) events[0].data.ptr;
+               if (!me) {
+                       rc = -EINVAL;
+                       goto failed;
+               }
+
+               /* rc: 1 event accepted; 0 ignored; <0 error */
+               rc = me->opers->op_process_event(mn, me);
+               if (rc < 0)
+                       goto failed;
+               if (rc == 1)
+                       break;
+               /* TODO" recalculate timeout */
+       } while (1);
+
+       if (me)
+               me->active = 1;
+       if (act)
+               *act = me;
+       return 0;
+
+nothing:
+       DBG(MONITOR, ul_debugobj(mn, " *** nothing"));
+       return 1;
+failed:
+       DBG(MONITOR, ul_debugobj(mn, " *** error"));
+       return rc;
+}
+
 /**
  * mnt_monitor_wait:
  * @mn: monitor
@@ -327,8 +376,6 @@ err:
 int mnt_monitor_wait(struct libmnt_monitor *mn, int timeout)
 {
        int rc;
-       struct monitor_entry *me;
-       struct epoll_event events[1];
 
        if (!mn)
                return -EINVAL;
@@ -339,25 +386,11 @@ int mnt_monitor_wait(struct libmnt_monitor *mn, int timeout)
                        return rc;
        }
 
-       do {
-               DBG(MONITOR, ul_debugobj(mn, "calling epoll_wait(), timeout=%d", timeout));
-               rc = epoll_wait(mn->fd, events, 1, timeout);
-               if (rc < 0)
-                       return -errno;          /* error */
-               if (rc == 0)
-                       return 0;               /* timeout */
-
-               me = (struct monitor_entry *) events[0].data.ptr;
-               if (!me)
-                       return -EINVAL;
-
-               if (me->opers->op_process_event(mn, me) == 1) {
-                       me->active = 1;
-                       break;
-               }
-       } while (1);
+       rc = read_epoll_events(mn, timeout, NULL);
 
-       return 1;                       /* success */
+       return  rc == 0 ? 1 :   /* success */
+               rc == 1 ? 0 :   /* timeout (aka nothing) */
+               rc;             /* error */
 }
 
 
@@ -389,40 +422,17 @@ int mnt_monitor_next_change(struct libmnt_monitor *mn,
                             const char **filename,
                             int *type)
 {
-       int rc;
-       struct monitor_entry *me;
+       int rc = 0;
+       struct monitor_entry *me = NULL;
 
        if (!mn || mn->fd < 0)
                return -EINVAL;
 
-       /*
-        * if we previously called epoll_wait() (e.g. mnt_monitor_wait()) then
-        * info about unread change is already stored in monitor_entry.
-        *
-        * If we get nothing, then ask kernel.
-        */
        me = get_active(mn);
-       while (!me) {
-               struct epoll_event events[1];
-
-               DBG(MONITOR, ul_debugobj(mn, "asking for next changed"));
-
-               rc = epoll_wait(mn->fd, events, 1, 0);  /* no timeout! */
-               if (rc < 0) {
-                       DBG(MONITOR, ul_debugobj(mn, " *** error"));
-                       return -errno;
-               }
-               if (rc == 0) {
-                       DBG(MONITOR, ul_debugobj(mn, " *** nothing"));
-                       return 1;
-               }
-
-               me = (struct monitor_entry *) events[0].data.ptr;
-               if (!me)
-                       return -EINVAL;
-
-               if (me->opers->op_process_event(mn, me) != 1)
-                       me = NULL;
+       if (!me) {
+               rc = read_epoll_events(mn, 0, &me);     /* try without timeout */
+               if (rc != 0)
+                       return rc;
        }
 
        me->active = 0;