Adapt poll layer behaviour to match the epoll layer
authorYannick Lamarre <ylamarre@efficios.com>
Thu, 25 Apr 2019 22:23:30 +0000 (18:23 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sat, 4 May 2019 19:25:51 +0000 (15:25 -0400)
Signed-off-by: Yannick Lamarre <ylamarre@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
src/common/compat/compat-poll.c

index b45b39dc6bdbd45daf69944316b1d663f1744867..2318920aed84a7c9dcdb5c1668035913ecb0ff10 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C)  2011 - David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C)  2019 - Yannick Lamarre <ylamarre@efficios.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 2 only,
@@ -204,10 +205,10 @@ int compat_poll_mod(struct lttng_poll_event *events, int fd,
                uint32_t req_events)
 {
        int i;
-       bool fd_found = false;
        struct compat_poll_event_array *current;
 
-       if (events == NULL || events->current.events == NULL || fd < 0) {
+       if (events == NULL || events->current.nb_fd == 0 ||
+                       events->current.events == NULL || fd < 0) {
                ERR("Bad compat poll mod arguments");
                goto error;
        }
@@ -216,16 +217,16 @@ int compat_poll_mod(struct lttng_poll_event *events, int fd,
 
        for (i = 0; i < current->nb_fd; i++) {
                if (current->events[i].fd == fd) {
-                       fd_found = true;
                        current->events[i].events = req_events;
                        events->need_update = 1;
                        break;
                }
        }
 
-       if (!fd_found) {
-               goto error;
-       }
+       /*
+        * The epoll flavor doesn't flag modifying a non-included FD as an
+        * error.
+        */
 
        return 0;
 
@@ -238,11 +239,12 @@ error:
  */
 int compat_poll_del(struct lttng_poll_event *events, int fd)
 {
-       int new_size, i, count = 0, ret;
+       int i, count = 0, ret;
+       uint32_t new_size;
        struct compat_poll_event_array *current;
 
-       if (events == NULL || events->current.events == NULL || fd < 0) {
-               ERR("Wrong arguments for poll del");
+       if (events == NULL || events->current.nb_fd == 0 ||
+                       events->current.events == NULL || fd < 0) {
                goto error;
        }
 
@@ -257,13 +259,20 @@ int compat_poll_del(struct lttng_poll_event *events, int fd)
                        count++;
                }
        }
+
+       /* The fd was not in our set, return no error as with epoll. */
+       if (current->nb_fd == count) {
+               goto end;
+       }
+
        /* No fd duplicate should be ever added into array. */
        assert(current->nb_fd - 1 == count);
        current->nb_fd = count;
 
        /* Resize array if needed. */
        new_size = 1U << utils_get_count_order_u32(current->nb_fd);
-       if (new_size != current->alloc_size && new_size >= current->init_size) {
+       if (new_size != current->alloc_size && new_size >= current->init_size
+                       && current->nb_fd != 0) {
                ret = resize_poll_event(current, new_size);
                if (ret < 0) {
                        goto error;
@@ -272,6 +281,7 @@ int compat_poll_del(struct lttng_poll_event *events, int fd)
 
        events->need_update = 1;
 
+end:
        return 0;
 
 error:
This page took 0.027016 seconds and 4 git commands to generate.