]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: list: make the delete and pop operations idempotent
authorWilly Tarreau <w@1wt.eu>
Thu, 28 Feb 2019 14:05:53 +0000 (15:05 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 28 Feb 2019 15:03:29 +0000 (16:03 +0100)
These operations previously used to return a "locked" element, which is
a constraint when multiple threads try to delete the same element, because
the second one will block indefinitely. Instead, let's make sure that both
LIST_DEL_LOCKED() and LIST_POP_LOCKED() always reinitialize the element
after deleting it. This ensures that the second thread will immediately
unblock and succeed with the removal. It also secures the pop vs delete
competition that may happen when trying to remove an element that's about
to be dequeued.

include/common/mini-clist.h

index d8fcb159970fbf92a200b36f03f3b69268b14a72..3b1f599ca2a938a575ccfbd8be576833d403a406 100644 (file)
@@ -261,6 +261,9 @@ struct cond_wordlist {
                        n->p = p;                                          \
                        p->n = n;                                          \
                        __ha_barrier_store();                              \
+                       (el)->p = (el);                                    \
+                       (el)->n = (el);                                    \
+                       __ha_barrier_store();                              \
                        break;                                             \
                }                                                          \
        } while (0)
@@ -308,6 +311,9 @@ struct cond_wordlist {
                         (lh)->n = n2;                                     \
                         (n2)->p = (lh);                                   \
                         __ha_barrier_store();                             \
+                        (n)->p = (n);                                     \
+                        (n)->n = (n);                                     \
+                        __ha_barrier_store();                             \
                         _ret = LIST_ELEM(n, pt, el);                      \
                         break;                                            \
                 }                                                         \